From 5ae2387cccd7a4c4cef4db4e23044c98a7ced9f3 Mon Sep 17 00:00:00 2001 From: gh-actions Date: Thu, 23 Nov 2023 05:26:42 +0000 Subject: [PATCH] Deploy website - based on 185bb5320520029b58b36936e098cf46a52e0bf5 --- 404.html | 4 +- asdocs/contacts/all-classes.html | 5 +- asdocs/contacts/all-index-A.html | 17 +- asdocs/contacts/all-index-B.html | 6 +- asdocs/contacts/all-index-C.html | 15 +- asdocs/contacts/all-index-D.html | 5 +- asdocs/contacts/all-index-E.html | 2 +- asdocs/contacts/all-index-F.html | 4 +- asdocs/contacts/all-index-G.html | 22 +- asdocs/contacts/all-index-H.html | 4 +- asdocs/contacts/all-index-I.html | 6 +- asdocs/contacts/all-index-J.html | 4 +- asdocs/contacts/all-index-K.html | 2 +- asdocs/contacts/all-index-L.html | 8 +- asdocs/contacts/all-index-M.html | 3 +- asdocs/contacts/all-index-N.html | 2 +- asdocs/contacts/all-index-O.html | 2 +- asdocs/contacts/all-index-P.html | 2 +- asdocs/contacts/all-index-Q.html | 2 +- asdocs/contacts/all-index-R.html | 2 +- asdocs/contacts/all-index-S.html | 11 +- asdocs/contacts/all-index-T.html | 2 +- asdocs/contacts/all-index-U.html | 2 +- asdocs/contacts/all-index-V.html | 2 +- asdocs/contacts/all-index-W.html | 2 +- asdocs/contacts/all-index-X.html | 2 +- asdocs/contacts/all-index-Y.html | 2 +- asdocs/contacts/all-index-Z.html | 2 +- asdocs/contacts/class-summary.html | 12 +- .../contacts/AuthorisationStatus.html | 4 +- .../contacts/ContactPickerOptions.html | 21 + .../distriqt/extension/contacts/Contacts.html | 442 ++++++------------ .../extension/contacts/class-list.html | 2 +- .../contacts/events/AuthorisationEvent.html | 15 +- .../contacts/events/ContactsEvent.html | 72 +-- .../contacts/events/ContactsJSONEvent.html | 31 +- .../extension/contacts/events/class-list.html | 2 +- .../contacts/events/package-detail.html | 4 +- .../extension/contacts/model/Address.html | 8 +- .../extension/contacts/model/Contact.html | 16 +- .../extension/contacts/model/ContactDate.html | 12 +- .../contacts/model/ContactOrganisation.html | 4 +- .../contacts/model/ContactProperty.html | 4 +- .../contacts/model/InstantMessageService.html | 16 +- .../contacts/model/SocialService.html | 14 +- .../extension/contacts/model/class-list.html | 2 +- .../contacts/model/package-detail.html | 2 +- .../extension/contacts/package-detail.html | 6 +- asdocs/contacts/index-list.html | 2 +- asdocs/contacts/index.html | 2 +- asdocs/contacts/package-frame.html | 2 +- asdocs/contacts/package-list.html | 2 +- asdocs/contacts/package-summary.html | 2 +- asdocs/contacts/title-bar.html | 2 +- assets/js/3e86e93e.0d253a19.js | 1 - assets/js/3e86e93e.e07e59af.js | 1 + ...f2afb.fa576174.js => 935f2afb.33ddf85f.js} | 2 +- ...n.394ca64f.js => runtime~main.ccf4ba71.js} | 2 +- docs/adverts/add-the-extension/index.html | 4 +- .../adverts/advertising-identifier/index.html | 4 +- docs/adverts/app-open-ads/index.html | 4 +- docs/adverts/banner-adverts/index.html | 4 +- docs/adverts/changelog/index.html | 4 +- docs/adverts/consent/index.html | 4 +- docs/adverts/index.html | 4 +- docs/adverts/initialise-platform/index.html | 4 +- docs/adverts/interstitials/index.html | 4 +- docs/adverts/life-time-value/index.html | 4 +- docs/adverts/mediation/adcolony/index.html | 4 +- docs/adverts/mediation/applovin/index.html | 4 +- docs/adverts/mediation/changelog/index.html | 4 +- .../mediation/facebookaudience/index.html | 4 +- docs/adverts/mediation/index.html | 4 +- docs/adverts/mediation/ironsource/index.html | 4 +- docs/adverts/mediation/pangle/index.html | 4 +- docs/adverts/mediation/tapjoy/index.html | 4 +- docs/adverts/mediation/unityads/index.html | 4 +- .../migrating-from-version-4/index.html | 4 +- docs/adverts/migrating-to-androidx/index.html | 4 +- .../migrating-to-version-10/index.html | 4 +- .../migrating-to-version-12/index.html | 4 +- .../migrating-to-version-13.6/index.html | 4 +- .../migrating-to-version-13/index.html | 4 +- .../migrating-to-version-14.0/index.html | 4 +- docs/adverts/native-ads/index.html | 4 +- docs/adverts/platform/admob/index.html | 4 +- docs/adverts/platform/huawei/index.html | 4 +- .../rewarded-interstitial-ads/index.html | 4 +- docs/adverts/rewarded-video-ads/index.html | 4 +- .../server-side-verification/index.html | 4 +- docs/adverts/targeting/index.html | 4 +- docs/adverts/test-ads/index.html | 4 +- docs/adverts/troubleshooting/index.html | 4 +- .../user-messaging-platform/index.html | 4 +- docs/appconfig/add-the-extension/index.html | 4 +- docs/appconfig/changelog/index.html | 4 +- docs/appconfig/index.html | 4 +- docs/appconfig/setup/index.html | 4 +- docs/appconfig/usage/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../add-the-plugin/index.html | 4 +- docs/appgroupdefaults/android/index.html | 4 +- docs/appgroupdefaults/changelog/index.html | 4 +- docs/appgroupdefaults/index.html | 4 +- docs/appgroupdefaults/ios/index.html | 4 +- docs/appgroupdefaults/unity/index.html | 4 +- docs/appgroupdefaults/usage/index.html | 4 +- docs/applesignin/add-the-extension/index.html | 4 +- docs/applesignin/changelog/index.html | 4 +- .../get-user-credentials/index.html | 4 +- docs/applesignin/index.html | 4 +- .../login-with-apple-id/index.html | 4 +- docs/applesignin/setup-application/index.html | 4 +- docs/applesignin/setup-auth-server/index.html | 4 +- docs/application/add-the-extension/index.html | 4 +- docs/application/alarm-manager/index.html | 4 +- .../application-state-events/index.html | 4 +- docs/application/auto-start/index.html | 4 +- docs/application/changelog/index.html | 4 +- docs/application/defaults/index.html | 4 +- .../accessibility/index.html | 4 +- .../device-state/index.html | 4 +- .../device-information/device/index.html | 4 +- .../operating-system/index.html | 4 +- .../orientation-events/index.html | 4 +- .../phone-number/index.html | 4 +- .../unique-device-id/index.html | 4 +- .../device-information/year-class/index.html | 4 +- docs/application/display/cutouts/index.html | 4 +- docs/application/display/dark-mode/index.html | 4 +- .../display/display-metrics/index.html | 4 +- docs/application/display/index.html | 4 +- .../display/soft-keyboard/index.html | 4 +- docs/application/general-helpers/index.html | 4 +- docs/application/index.html | 4 +- docs/application/keychain/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../application/migrating-to-v6.12/index.html | 4 +- docs/application/settings/index.html | 4 +- docs/application/status-bar/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../add-the-plugin/index.html | 4 +- .../application-id/index.html | 4 +- .../index.html | 4 +- .../application-rate-dialog/index.html | 4 +- docs/applicationrater/changelog/index.html | 4 +- .../handling-stores/index.html | 4 +- docs/applicationrater/index.html | 4 +- .../requesting-review/index.html | 4 +- .../review-controller/index.html | 4 +- docs/applicationrater/unity/index.html | 4 +- docs/applovinsdk/add-the-extension/index.html | 4 +- docs/applovinsdk/changelog/index.html | 4 +- docs/applovinsdk/index.html | 4 +- docs/applovinsdk/initialise/index.html | 4 +- docs/applovinsdk/interstitials/index.html | 4 +- docs/applovinsdk/mediation/admob/index.html | 4 +- .../applovinsdk/mediation/facebook/index.html | 4 +- .../mediation/ironsource/index.html | 4 +- .../applovinsdk/mediation/unityads/index.html | 4 +- docs/applovinsdk/rewarded-video/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/audiorecorder/changelog/index.html | 4 +- docs/audiorecorder/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../migrating-to-v3.1/index.html | 4 +- docs/audiorecorder/playback/index.html | 4 +- docs/audiorecorder/recording-audio/index.html | 4 +- .../requesting-authorisation/index.html | 4 +- docs/battery/add-the-extension/index.html | 4 +- docs/battery/battery-info/index.html | 4 +- docs/battery/changelog/index.html | 4 +- docs/battery/index.html | 4 +- docs/beacon/add-the-extension/index.html | 4 +- docs/beacon/broadcasting/index.html | 4 +- docs/beacon/changelog/index.html | 4 +- docs/beacon/events/index.html | 4 +- docs/beacon/index.html | 4 +- docs/beacon/migrating-to-androidx/index.html | 4 +- docs/beacon/migrating-to-v5.1/index.html | 4 +- docs/beacon/monitoring-a-region/index.html | 4 +- .../requesting-authorisation/index.html | 4 +- docs/beacon/tools-and-resources/index.html | 4 +- docs/bluetooth/add-the-extension/index.html | 4 +- docs/bluetooth/changelog/index.html | 4 +- docs/bluetooth/connecting/index.html | 4 +- docs/bluetooth/index.html | 4 +- docs/bluetooth/ios/index.html | 4 +- docs/bluetoothle/adapter-state/index.html | 4 +- docs/bluetoothle/add-the-extension/index.html | 4 +- docs/bluetoothle/central-manager/index.html | 4 +- .../centrals-and-peripherals/index.html | 4 +- docs/bluetoothle/changelog/index.html | 4 +- docs/bluetoothle/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/bluetoothle/migrating-to-v4.2/index.html | 4 +- .../bluetoothle/peripheral-manager/index.html | 4 +- .../request-authorisation/index.html | 4 +- docs/bolts/changelog/index.html | 4 +- docs/branch/add-the-extension/index.html | 4 +- .../branch-universal-objects/index.html | 4 +- docs/branch/changelog/index.html | 4 +- docs/branch/deep-links/index.html | 4 +- docs/branch/event-tracking/index.html | 4 +- docs/branch/get-short-url/index.html | 4 +- docs/branch/index.html | 4 +- docs/branch/initialisation/index.html | 4 +- docs/branch/link-parameters/index.html | 4 +- docs/branch/migrating-to-androidx/index.html | 4 +- docs/branch/referral-credits/index.html | 4 +- docs/branch/testing/index.html | 4 +- docs/branch/user-identity/index.html | 4 +- docs/braze/add-the-extension/index.html | 4 +- docs/braze/analytics/index.html | 4 +- docs/braze/changelog/index.html | 4 +- docs/braze/content-cards/index.html | 4 +- docs/braze/deep-linking/index.html | 4 +- docs/braze/in-app-messaging/index.html | 4 +- docs/braze/index.html | 4 +- docs/braze/integration/index.html | 4 +- docs/braze/push-notifications/index.html | 4 +- docs/braze/unity/index.html | 4 +- docs/calendar/add-events/index.html | 4 +- docs/calendar/add-the-extension/index.html | 4 +- docs/calendar/changelog/index.html | 4 +- docs/calendar/get-events/index.html | 4 +- docs/calendar/index.html | 4 +- .../calendar/migrating-to-androidx/index.html | 4 +- docs/calendar/migrating-to-v5.1/index.html | 4 +- .../calendar/request-authorisation/index.html | 4 +- docs/camera/add-the-extension/index.html | 4 +- docs/camera/camera-modes/index.html | 4 +- docs/camera/capturing-images/index.html | 4 +- docs/camera/changelog/index.html | 4 +- docs/camera/connecting/index.html | 4 +- docs/camera/index.html | 4 +- docs/camera/migrating-to-androidx/index.html | 4 +- docs/camera/migrating-to-v6.1/index.html | 4 +- docs/camera/parameters-exposure/index.html | 4 +- docs/camera/parameters-flash/index.html | 4 +- docs/camera/parameters-focus/index.html | 4 +- .../parameters-white-balance/index.html | 4 +- docs/camera/preview-frames/index.html | 4 +- .../requesting-authorisation/index.html | 4 +- docs/camera/selecting-a-device/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../adding-files/index.html | 4 +- .../browse-for-an-asset/index.html | 4 +- docs/camerarollextended/changelog/index.html | 4 +- .../camerarollextended/file-access/index.html | 4 +- docs/camerarollextended/index.html | 4 +- .../loading-an-asset/index.html | 4 +- .../loading-as-asset---deprecated/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../migrating-to-v6.4/index.html | 4 +- .../migrating-to-v7.0/index.html | 4 +- .../request-authorisation/index.html | 4 +- docs/cameraui/add-the-extension/index.html | 4 +- docs/cameraui/camera-ui-options/index.html | 4 +- docs/cameraui/capture-media/index.html | 4 +- docs/cameraui/changelog/index.html | 4 +- docs/cameraui/index.html | 4 +- .../cameraui/migrating-to-androidx/index.html | 4 +- docs/cameraui/migrating-to-v3.5/index.html | 4 +- .../requesting-authorisation/index.html | 4 +- docs/chartboost/add-the-extension/index.html | 4 +- docs/chartboost/changelog/index.html | 4 +- docs/chartboost/index.html | 4 +- docs/chartboost/initialise/index.html | 4 +- docs/chartboost/setup/index.html | 4 +- .../cloudstorage/add-the-extension/index.html | 4 +- docs/cloudstorage/add-the-plugin/index.html | 4 +- docs/cloudstorage/android-testing/index.html | 4 +- docs/cloudstorage/changelog/index.html | 4 +- docs/cloudstorage/document-store/index.html | 4 +- docs/cloudstorage/index.html | 4 +- .../cloudstorage/key-value-storage/index.html | 4 +- docs/cloudstorage/unity/index.html | 4 +- docs/compass/add-the-extension/index.html | 4 +- docs/compass/changelog/index.html | 4 +- docs/compass/heading/index.html | 4 +- docs/compass/index.html | 4 +- docs/compass/magnetic-field-sensor/index.html | 4 +- docs/compass/request-authorisation/index.html | 4 +- docs/contacts/add-the-extension/index.html | 4 +- docs/contacts/changelog/index.html | 8 +- docs/contacts/contact-images/index.html | 4 +- docs/contacts/contact-picker-ui/index.html | 4 +- docs/contacts/index.html | 4 +- .../contacts/migrating-to-androidx/index.html | 4 +- docs/contacts/migrating-to-v5.1/index.html | 4 +- .../contacts/request-authorisation/index.html | 4 +- .../retrieving-the-contact-list/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../contentprovider/add-the-plugin/index.html | 4 +- docs/contentprovider/changelog/index.html | 4 +- docs/contentprovider/index.html | 4 +- docs/contentprovider/unity/index.html | 4 +- docs/core/changelog/index.html | 4 +- docs/debug/add-the-extension/index.html | 4 +- docs/debug/changelog/index.html | 4 +- docs/debug/index.html | 4 +- docs/debug/usage/index.html | 4 +- .../devicemotion/add-the-extension/index.html | 4 +- .../algorithms-and-format/index.html | 4 +- docs/devicemotion/changelog/index.html | 4 +- docs/devicemotion/index.html | 4 +- .../register-for-updates/index.html | 4 +- docs/dialog/action-sheet/index.html | 4 +- docs/dialog/activity-dialog/index.html | 4 +- docs/dialog/add-the-extension/index.html | 4 +- docs/dialog/air-fallback/index.html | 4 +- docs/dialog/alerts/index.html | 4 +- docs/dialog/changelog/index.html | 4 +- docs/dialog/custom-picker/index.html | 4 +- docs/dialog/date-time-dialog/index.html | 4 +- .../dialog-views-and-builders/index.html | 4 +- docs/dialog/index.html | 4 +- docs/dialog/migrating-to-androidx/index.html | 4 +- docs/dialog/multi-select/index.html | 4 +- docs/dialog/progress-dialog/index.html | 4 +- docs/dialog/text-view-alert/index.html | 4 +- docs/dialog/toast/index.html | 4 +- docs/dynamicicon/add-the-extension/index.html | 4 +- docs/dynamicicon/adding-icons/index.html | 4 +- docs/dynamicicon/change-icon/index.html | 4 +- docs/dynamicicon/changelog/index.html | 4 +- docs/dynamicicon/index.html | 4 +- docs/dynamicicon/packaging/index.html | 4 +- docs/epos/add-the-extension/index.html | 4 +- docs/epos/changelog/index.html | 4 +- docs/epos/index.html | 4 +- docs/epos/initialisation/index.html | 4 +- docs/epos/printing/index.html | 4 +- docs/exceptions/add-the-extension/index.html | 4 +- docs/exceptions/changelog/index.html | 4 +- docs/exceptions/index.html | 4 +- docs/exceptions/usage/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/expansionfiles/changelog/index.html | 4 +- .../downloading-expansion-files/index.html | 4 +- docs/expansionfiles/index.html | 4 +- docs/expansionfiles/jobb-files/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../migrating-to-v4.2/index.html | 4 +- .../mounting-an-obb-file/index.html | 4 +- .../reading-an-obb-file/index.html | 4 +- .../request-authorisation/index.html | 4 +- .../expansionfiles/setup-licensing/index.html | 4 +- .../uploading-expansion-files/index.html | 4 +- .../index.html | 4 +- .../account-kit---deprecation/index.html | 4 +- .../account-kit---overview/index.html | 4 +- .../account-kit---setup/index.html | 4 +- .../account-kit---usage/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../advanced-facebook-settings/index.html | 4 +- .../app-events---automatic-logging/index.html | 4 +- .../app-events---logging/index.html | 4 +- .../app-events---overview/index.html | 4 +- .../app-events---user-properties/index.html | 4 +- .../app-invites---dialog/index.html | 4 +- .../app-links---incoming-links/index.html | 4 +- .../app-links---overview/index.html | 4 +- docs/facebookapi-legacy/changelog/index.html | 4 +- .../facebook-android-app/index.html | 4 +- .../facebook-application/index.html | 4 +- .../facebook-ios-app/index.html | 4 +- .../games---game-request-dialog/index.html | 4 +- .../games---overview/index.html | 4 +- .../graph-api---basics/index.html | 4 +- .../graph-api---batch/index.html | 4 +- .../graph-api---examples/index.html | 4 +- .../graph-api---overview/index.html | 4 +- docs/facebookapi-legacy/index.html | 4 +- .../initialise-facebook-app/index.html | 4 +- .../initialise-the-extension/index.html | 4 +- .../login---access-token/index.html | 4 +- .../login---facebook-login/index.html | 4 +- .../login---overview/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../sharing---content/index.html | 4 +- .../sharing---message-dialog/index.html | 4 +- .../sharing---open-graph-stories/index.html | 4 +- .../sharing---overview/index.html | 4 +- .../sharing---share-api/index.html | 4 +- .../sharing---share-dialog/index.html | 4 +- docs/facebookapi/changelog/index.html | 4 +- .../core/add-the-extension/index.html | 4 +- .../app-events/automatic-logging/index.html | 4 +- .../core/app-events/logging/index.html | 4 +- .../core/app-events/overview/index.html | 4 +- .../app-events/user-properties/index.html | 4 +- .../handling-incoming-links/index.html | 4 +- .../core/app-links/overview/index.html | 4 +- .../core/app-links/support/index.html | 4 +- .../core/graph-api/basics/index.html | 4 +- .../core/graph-api/batch/index.html | 4 +- .../core/graph-api/examples/index.html | 4 +- .../core/graph-api/overview/index.html | 4 +- .../core/initialise-the-extension/index.html | 4 +- docs/facebookapi/core/overview/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../friend-finder-dialog/index.html | 4 +- .../game-request-dialog/index.html | 4 +- .../gamingservices/overview/index.html | 4 +- docs/facebookapi/get-started/index.html | 4 +- docs/facebookapi/index.html | 4 +- .../facebookapi/login/access-token/index.html | 4 +- .../login/add-the-extension/index.html | 4 +- .../login/facebook-login/index.html | 4 +- docs/facebookapi/login/overview/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../migrating-to-version-10/index.html | 4 +- .../migrating-to-version-8/index.html | 4 +- .../migrating-to-version-9/index.html | 4 +- .../share/add-the-extension/index.html | 4 +- docs/facebookapi/share/content/index.html | 4 +- docs/facebookapi/share/overview/index.html | 4 +- .../facebookapi/share/share-dialog/index.html | 4 +- docs/facebookapi/signing/index.html | 4 +- docs/facebookaudience/changelog/index.html | 4 +- docs/faqs/error-404/index.html | 4 +- docs/faqs/error-context-create/index.html | 4 +- docs/faqs/index.html | 4 +- docs/faqs/ld-framework-not-found/index.html | 4 +- docs/faqs/ld-unknown-option/index.html | 4 +- docs/faqs/ld-warning/index.html | 4 +- .../auth/add-the-extensions/index.html | 4 +- docs/firebase/auth/initialise/index.html | 4 +- docs/firebase/auth/introduction/index.html | 4 +- .../auth/link-multiple-providers/index.html | 4 +- docs/firebase/auth/manage-users/index.html | 4 +- .../auth/provider/anonymous/index.html | 4 +- docs/firebase/auth/provider/apple/index.html | 4 +- .../auth/provider/custom-auth/index.html | 4 +- .../auth/provider/email-link/index.html | 4 +- docs/firebase/auth/provider/email/index.html | 4 +- .../auth/provider/facebook/index.html | 4 +- docs/firebase/auth/provider/github/index.html | 4 +- .../auth/provider/google-identity/index.html | 4 +- .../auth/provider/microsoft/index.html | 4 +- docs/firebase/auth/provider/phone/index.html | 4 +- .../firebase/auth/provider/twitter/index.html | 4 +- docs/firebase/changelog/index.html | 4 +- .../core/add-the-extensions/index.html | 4 +- docs/firebase/core/analytics/index.html | 4 +- docs/firebase/core/initialise/index.html | 4 +- docs/firebase/core/introduction/index.html | 4 +- .../crash/add-the-extensions/index.html | 4 +- docs/firebase/crash/introduction/index.html | 4 +- docs/firebase/crash/usage/index.html | 4 +- .../crashlytics/add-the-extension/index.html | 4 +- .../crashlytics/introduction/index.html | 4 +- docs/firebase/crashlytics/testing/index.html | 4 +- .../crashlytics/uploading-dsyms/index.html | 4 +- docs/firebase/crashlytics/usage/index.html | 4 +- .../database/add-the-extensions/index.html | 4 +- .../configure-database-rules/index.html | 4 +- docs/firebase/database/delete-data/index.html | 4 +- docs/firebase/database/disconnect/index.html | 4 +- docs/firebase/database/initialise/index.html | 4 +- .../firebase/database/introduction/index.html | 4 +- docs/firebase/database/lists/index.html | 4 +- docs/firebase/database/offline/index.html | 4 +- .../read-data-and-change-events/index.html | 4 +- .../firebase/database/transactions/index.html | 4 +- docs/firebase/database/write-data/index.html | 4 +- .../dynamiclinks/add-the-extension/index.html | 4 +- .../create-dynamic-links/index.html | 4 +- .../dynamiclinks/initialise/index.html | 4 +- .../dynamiclinks/introduction/index.html | 4 +- .../receive-dynamic-links/index.html | 4 +- docs/firebase/dynamiclinks/testing/index.html | 4 +- docs/firebase/fcm/introduction/index.html | 4 +- docs/firebase/firestore/add-data/index.html | 4 +- .../firestore/add-the-extension/index.html | 4 +- .../firebase/firestore/delete-data/index.html | 4 +- .../firestore/enable-offline-data/index.html | 4 +- docs/firebase/firestore/get-data/index.html | 4 +- .../firestore/get-realtime-updates/index.html | 4 +- .../firestore/introduction/index.html | 4 +- .../firestore/order-and-limit-data/index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- docs/firebase/index.html | 4 +- .../invites/add-the-extension/index.html | 4 +- .../firebase/invites/dynamic-links/index.html | 4 +- docs/firebase/invites/initialise/index.html | 4 +- docs/firebase/invites/introduction/index.html | 4 +- docs/firebase/invites/invitations/index.html | 4 +- docs/firebase/migrating-to-v4/index.html | 4 +- docs/firebase/migrating-to-v6/index.html | 4 +- .../performance/add-the-extension/index.html | 4 +- .../performance/disable-monitoring/index.html | 4 +- .../performance/introduction/index.html | 4 +- docs/firebase/performance/traces/index.html | 4 +- .../add-the-extensions/index.html | 4 +- .../remoteconfig/initialise/index.html | 4 +- .../remoteconfig/introduction/index.html | 4 +- .../set-initial-values/index.html | 4 +- docs/firebase/remoteconfig/usage/index.html | 4 +- .../setup/configuration-files/index.html | 4 +- .../create-a-firebase-project/index.html | 4 +- .../storage/add-the-extensions/index.html | 4 +- docs/firebase/storage/delete-files/index.html | 4 +- .../storage/download-files/index.html | 4 +- .../firebase/storage/file-metadata/index.html | 4 +- docs/firebase/storage/introduction/index.html | 4 +- docs/firebase/storage/list-files/index.html | 4 +- docs/firebase/storage/references/index.html | 4 +- docs/firebase/storage/upload-files/index.html | 4 +- docs/flurry/add-the-extension/index.html | 4 +- docs/flurry/analytics-events/index.html | 4 +- docs/flurry/analytics-sessions/index.html | 4 +- .../analytics-standard-events/index.html | 4 +- docs/flurry/changelog/index.html | 4 +- docs/flurry/index.html | 4 +- .../initialise-the-extension/index.html | 4 +- docs/flurry/migrating-to-v6/index.html | 4 +- docs/flurry/user-properties/index.html | 4 +- docs/forcetouch/add-the-extension/index.html | 4 +- docs/forcetouch/app-shortcuts/index.html | 4 +- docs/forcetouch/changelog/index.html | 4 +- docs/forcetouch/force-touch-events/index.html | 4 +- docs/forcetouch/index.html | 4 +- docs/gameservices/access-point/index.html | 4 +- docs/gameservices/achievements/index.html | 4 +- docs/gameservices/auth-utilities/index.html | 4 +- docs/gameservices/changelog/index.html | 4 +- docs/gameservices/index.html | 4 +- .../initialise-the-service/index.html | 4 +- docs/gameservices/leaderboards/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../gameservices/quests-and-events/index.html | 4 +- .../saved-games---conflicts/index.html | 4 +- docs/gameservices/saved-games/index.html | 4 +- docs/gameservices/screen-recording/index.html | 4 +- .../gamecenter/add-the-extension/index.html | 4 +- .../service/gamecenter/setup/index.html | 4 +- .../gamecenter/troubleshooting/index.html | 4 +- .../huawei/add-the-extension/index.html | 4 +- .../service/huawei/setup/index.html | 4 +- .../service/huawei/troubleshooting/index.html | 4 +- .../playgames/add-the-extension/index.html | 4 +- .../service/playgames/setup/index.html | 4 +- .../playgames/troubleshooting/index.html | 4 +- docs/gameservices/sign-in/index.html | 4 +- docs/gameservices/troubleshooting/index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- docs/gameservices/user-interface/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/googleanalytics/changelog/index.html | 4 +- .../create-a-tracker/index.html | 4 +- docs/googleanalytics/ecommerce/index.html | 4 +- .../enhanced-ecommerce/index.html | 4 +- docs/googleanalytics/index.html | 4 +- .../install-referrer/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/googleanalytics/notes/index.html | 4 +- .../sending-hits-and-events/index.html | 4 +- docs/googleanalytics/tracking-ids/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../android-certificate/index.html | 4 +- .../index.html | 4 +- docs/googleidentity/changelog/index.html | 4 +- docs/googleidentity/disconnect/index.html | 4 +- .../enabling-server-side-access/index.html | 4 +- .../index.html | 4 +- .../google-identity-options/index.html | 4 +- docs/googleidentity/index.html | 4 +- .../migrating-from-version-1/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/googleidentity/setup/index.html | 4 +- docs/googleidentity/signing-in/index.html | 4 +- .../googleidentity/troubleshooting/index.html | 4 +- .../user-information/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/googletagmanager/changelog/index.html | 4 +- .../google-tag-manager-setup/index.html | 4 +- docs/googletagmanager/index.html | 4 +- .../legacy/containers/index.html | 4 +- .../legacy/datalayer/index.html | 4 +- docs/googletagmanager/log-events/index.html | 4 +- docs/gyroscope/add-the-extension/index.html | 4 +- docs/gyroscope/changelog/index.html | 4 +- docs/gyroscope/index.html | 4 +- docs/gyroscope/sensor-updates/index.html | 4 +- docs/health/add-the-extension/index.html | 4 +- docs/health/add-the-plugin/index.html | 4 +- docs/health/authorisation/index.html | 4 +- docs/health/changelog/index.html | 4 +- docs/health/check-for-updates/index.html | 4 +- docs/health/index.html | 4 +- docs/health/queries/index.html | 4 +- docs/health/setup/index.html | 4 +- docs/idfa/add-the-extension/index.html | 4 +- docs/idfa/changelog/index.html | 4 +- .../get-advertising-identifier/index.html | 4 +- docs/idfa/index.html | 4 +- docs/idfa/migrating-to-androidx/index.html | 4 +- docs/idfa/migrating/index.html | 4 +- docs/image/add-the-extension/index.html | 4 +- docs/image/capturing-a-screenshot/index.html | 4 +- docs/image/changelog/index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- docs/image/index.html | 4 +- .../loading-bitmapdata-from-file/index.html | 4 +- docs/image/migrating-to-androidx/index.html | 4 +- docs/image/migrating-to-v5.2/index.html | 4 +- docs/image/request-authorisation/index.html | 4 +- .../saving-bitmapdata-to-file/index.html | 4 +- .../index.html | 4 +- docs/image/transformations/index.html | 4 +- .../inappbilling/add-the-extension/index.html | 4 +- .../amazon/add-the-extension/index.html | 4 +- .../amazon-in-app-purchasing/index.html | 4 +- docs/inappbilling/amazon/testing/index.html | 4 +- .../apple/apple-in-app-purchases/index.html | 4 +- .../apple/server-side-verification/index.html | 4 +- docs/inappbilling/apple/testing/index.html | 4 +- .../apple/troubleshooting/index.html | 4 +- .../application-receipt/index.html | 4 +- docs/inappbilling/billing-service/index.html | 4 +- .../inappbilling/change-a-purchase/index.html | 4 +- docs/inappbilling/changelog/index.html | 4 +- .../consuming-purchases/index.html | 4 +- docs/inappbilling/get-purchases/index.html | 4 +- .../google-play-inapp-billing/index.html | 4 +- docs/inappbilling/google/testing/index.html | 4 +- .../huawei/add-the-extension/index.html | 4 +- .../huawei/huawei-appgallery/index.html | 4 +- docs/inappbilling/huawei/testing/index.html | 4 +- docs/inappbilling/in-app-updates/index.html | 4 +- docs/inappbilling/index.html | 4 +- .../introductory-prices/index.html | 4 +- docs/inappbilling/make-a-purchase/index.html | 4 +- docs/inappbilling/migration-v14/index.html | 4 +- docs/inappbilling/migration-v15/index.html | 4 +- docs/inappbilling/migration/index.html | 4 +- docs/inappbilling/overview/index.html | 4 +- .../inappbilling/pending-purchases/index.html | 4 +- docs/inappbilling/products/index.html | 4 +- docs/inappbilling/promotions/index.html | 4 +- .../inappbilling/restore-purchases/index.html | 4 +- .../samsung/add-the-extension/index.html | 4 +- .../samsung-in-app-purchases/index.html | 4 +- docs/inappbilling/samsung/testing/index.html | 4 +- .../subscription-offers/index.html | 4 +- docs/inappbilling/testing/index.html | 4 +- docs/inappbilling/user-data/index.html | 4 +- docs/index.html | 4 +- docs/ironsource/add-the-extension/index.html | 4 +- docs/ironsource/banner-ads/index.html | 4 +- docs/ironsource/changelog/index.html | 4 +- docs/ironsource/errors/index.html | 4 +- docs/ironsource/index.html | 4 +- docs/ironsource/initialisation/index.html | 4 +- docs/ironsource/interstitials/index.html | 4 +- docs/ironsource/mediation/adcolony/index.html | 4 +- docs/ironsource/mediation/admob/index.html | 4 +- docs/ironsource/mediation/amazon/index.html | 4 +- docs/ironsource/mediation/applovin/index.html | 4 +- .../mediation/chartboost/index.html | 4 +- .../mediation/digitalturbine/index.html | 4 +- .../mediation/facebook-audience/index.html | 4 +- docs/ironsource/mediation/tapjoy/index.html | 4 +- docs/ironsource/mediation/unityads/index.html | 4 +- docs/ironsource/mediation/vungle/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/ironsource/offerwall/index.html | 4 +- docs/ironsource/rewarded-video/index.html | 4 +- docs/isallmediators/changelog/index.html | 4 +- .../jobscheduler/add-the-extension/index.html | 4 +- .../application-termination/index.html | 4 +- docs/jobscheduler/changelog/index.html | 4 +- docs/jobscheduler/index.html | 4 +- docs/localauth/add-the-extension/index.html | 4 +- .../biometric-authentication/index.html | 4 +- docs/localauth/changelog/index.html | 4 +- docs/localauth/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../request-authorisation/index.html | 4 +- docs/location/add-the-extension/index.html | 4 +- docs/location/changelog/index.html | 4 +- .../device-location-settings/index.html | 4 +- docs/location/geocoding/index.html | 4 +- docs/location/geofences/index.html | 4 +- docs/location/index.html | 4 +- .../initialise-the-extension/index.html | 4 +- .../ios-location-simulation/index.html | 4 +- docs/location/location-monitoring/index.html | 4 +- .../location-utils---distance/index.html | 4 +- .../location/migrating-to-androidx/index.html | 4 +- docs/location/migrating-to-v4.5/index.html | 4 +- .../location/request-authorisation/index.html | 4 +- docs/mediaplayer/add-the-extension/index.html | 4 +- .../index.html | 4 +- docs/mediaplayer/audio-player/index.html | 4 +- docs/mediaplayer/changelog/index.html | 4 +- docs/mediaplayer/index.html | 4 +- .../index.html | 4 +- .../media-player---create/index.html | 4 +- .../media-player---loading-media/index.html | 4 +- .../media-player---playback-events/index.html | 4 +- .../migrating-from-version-1/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../remote-command-center/index.html | 4 +- docs/mediaplayer/sound-pool/index.html | 4 +- docs/mediaplayer/system-control/index.html | 4 +- docs/memory/add-the-extension/index.html | 4 +- docs/memory/changelog/index.html | 4 +- docs/memory/index.html | 4 +- docs/memory/usage/index.html | 4 +- docs/message/add-the-extension/index.html | 4 +- docs/message/changelog/index.html | 4 +- docs/message/email/index.html | 4 +- docs/message/index.html | 4 +- docs/message/migrating-to-androidx/index.html | 4 +- docs/message/sms/index.html | 4 +- docs/nativemaps/add-the-extension/index.html | 4 +- docs/nativemaps/apple-maps/index.html | 4 +- docs/nativemaps/changelog/index.html | 4 +- .../controlling-the-view/index.html | 4 +- docs/nativemaps/create-a-map/index.html | 4 +- docs/nativemaps/google-maps/index.html | 4 +- docs/nativemaps/index.html | 4 +- .../initialise-the-extension/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/nativemaps/migrating-to-v5.2/index.html | 4 +- docs/nativemaps/overlays---markers/index.html | 4 +- .../nativemaps/overlays---polygons/index.html | 4 +- .../overlays---polylines/index.html | 4 +- docs/nativemaps/overlays/index.html | 4 +- .../request-authorisation/index.html | 4 +- docs/nativemaps/touch-events/index.html | 4 +- .../nativemaps/upgrade-new-version/index.html | 4 +- docs/nativetext/add-the-extension/index.html | 4 +- docs/nativetext/changelog/index.html | 4 +- docs/nativetext/index.html | 4 +- docs/nativetext/keyboard-input/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/nativewebview/browser-view/index.html | 4 +- docs/nativewebview/changelog/index.html | 4 +- docs/nativewebview/communication/index.html | 4 +- .../nativewebview/create-a-webview/index.html | 4 +- docs/nativewebview/index.html | 4 +- .../initialise-the-extension/index.html | 4 +- .../loading-packaged-files/index.html | 4 +- .../nativewebview/location-changes/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../migrating-to-v5.4/index.html | 4 +- docs/nativewebview/migrating-to-v5/index.html | 4 +- .../position-size-visibility/index.html | 4 +- .../removing-the-webview/index.html | 4 +- docs/nativewebview/screenshot/index.html | 4 +- .../webview-information/index.html | 4 +- docs/networkinfo/add-the-extension/index.html | 4 +- docs/networkinfo/changelog/index.html | 4 +- docs/networkinfo/index.html | 4 +- .../network-change-monitoring/index.html | 4 +- docs/networkinfo/telephony/index.html | 4 +- docs/nfc/add-the-extension/index.html | 4 +- docs/nfc/add-the-plugin/index.html | 4 +- docs/nfc/changelog/index.html | 4 +- docs/nfc/dispatch-mode/index.html | 4 +- docs/nfc/index.html | 4 +- docs/nfc/reader-mode/index.html | 4 +- docs/nfc/scanning/index.html | 4 +- docs/nfc/unity/index.html | 4 +- .../add-the-extension---windows/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../cancel-notifications/index.html | 4 +- docs/notifications/changelog/index.html | 4 +- .../delay-and-repeat-interval/index.html | 4 +- .../displaying-notifications/index.html | 4 +- docs/notifications/emojis/index.html | 4 +- docs/notifications/index.html | 4 +- .../notifications/migrating-to-6.3/index.html | 4 +- .../notifications/migrating-to-6.4/index.html | 4 +- .../notifications/migrating-to-6.5/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../notification-icons/index.html | 4 +- .../notification-scenarios/index.html | 4 +- .../notification-types/index.html | 4 +- .../receiving-notifications/index.html | 4 +- .../register-for-notifications/index.html | 4 +- .../request-authorisation/index.html | 4 +- .../notifications/set-badge-number/index.html | 4 +- .../setup-your-service/index.html | 4 +- docs/notifications/sounds/index.html | 4 +- docs/ocr/add-the-extension/index.html | 4 +- docs/ocr/changelog/index.html | 4 +- docs/ocr/index.html | 4 +- docs/ocr/migrating-to-androidx/index.html | 4 +- docs/ocr/recognising-text/index.html | 4 +- .../tips-for-improving-ocr-results/index.html | 4 +- docs/ocr/training-data/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/packagemanager/changelog/index.html | 4 +- docs/packagemanager/index.html | 4 +- .../installed-application-info/index.html | 4 +- .../packagemanager/installing-apps/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/packagemanager/package-events/index.html | 4 +- docs/pdfreader/add-the-extension/index.html | 4 +- docs/pdfreader/changelog/index.html | 4 +- docs/pdfreader/create-a-pdf-view/index.html | 4 +- docs/pdfreader/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/pdfreader/pages/index.html | 4 +- docs/permissions/add-the-extension/index.html | 4 +- docs/permissions/changelog/index.html | 4 +- .../permissions/file-folder-access/index.html | 4 +- docs/permissions/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- docs/permissions/migrating-to-v3.4/index.html | 4 +- docs/permissions/requesting-access/index.html | 4 +- docs/permissions/set-permissions/index.html | 4 +- docs/permissions/system-settings/index.html | 4 +- .../add-the-extension/index.html | 4 +- .../apple/add-the-extension/index.html | 4 +- .../index.html | 4 +- .../apple/ios-apns-message/index.html | 4 +- .../apple/ios-apns-payload/index.html | 4 +- .../azure/azure-notifications/index.html | 4 +- .../azure/setup-your-service/index.html | 4 +- docs/pushnotifications/changelog/index.html | 4 +- .../firebase/add-the-extension/index.html | 4 +- .../firebase/fcm-gcm-payload/index.html | 4 +- .../firebase-cloud-message/index.html | 4 +- .../firebase-cloud-messaging/index.html | 4 +- .../firebase-inapp-messaging/index.html | 4 +- .../gcm/google-cloud-message/index.html | 4 +- .../gcm/google-cloud-messaging/index.html | 4 +- .../handling-startup-notifications/index.html | 4 +- docs/pushnotifications/icons/index.html | 4 +- .../inapp-messaging/index.html | 4 +- docs/pushnotifications/index.html | 4 +- .../migrating-to-androidx/index.html | 4 +- .../migrating-to-v10.1/index.html | 4 +- .../migrating-to-v10.2/index.html | 4 +- .../migrating-to-v11.2/index.html | 4 +- .../migrating-to-v11.3/index.html | 4 +- .../migrating-to-v13.0/index.html | 4 +- .../notification-scenarios/index.html | 4 +- .../onesignal/add-the-extension/index.html | 4 +- .../onesignal/amazon/index.html | 4 +- .../onesignal/huawei/index.html | 4 +- docs/pushnotifications/onesignal/index.html | 4 +- .../onesignal/migrating-to-v7.5/index.html | 4 +- .../onesignal/quick-start/index.html | 4 +- .../onesignal/setup-your-service/index.html | 4 +- .../onesignal/signing/index.html | 4 +- docs/pushnotifications/pushy/index.html | 4 +- .../pushy/pushy-message/index.html | 4 +- .../pushy/pushy-payload/index.html | 4 +- .../receiving-notifications/index.html | 4 +- .../register-for-notifications/index.html | 4 +- .../request-authorisation/index.html | 4 +- .../set-badge-number/index.html | 4 +- .../setup-your-service/index.html | 4 +- docs/pushnotifications/sounds/index.html | 4 +- docs/pushnotifications/tags/index.html | 4 +- docs/pushnotifications/topics/index.html | 4 +- .../pushnotifications/user-consent/index.html | 4 +- .../windows/add-the-extension/index.html | 4 +- .../windows-notification-service/index.html | 4 +- .../windows/windows-wns-message/index.html | 4 +- .../windows/windows-wns-payload/index.html | 4 +- docs/reactivex/changelog/index.html | 4 +- docs/restartapp/add-the-extension/index.html | 4 +- docs/restartapp/changelog/index.html | 4 +- docs/restartapp/index.html | 4 +- .../restartapp/restart-application/index.html | 4 +- docs/rootchecker/add-the-extension/index.html | 4 +- docs/rootchecker/changelog/index.html | 4 +- docs/rootchecker/index.html | 4 +- docs/rootchecker/root-check/index.html | 4 +- docs/scanner/add-the-extension/index.html | 4 +- docs/scanner/changelog/index.html | 4 +- docs/scanner/index.html | 4 +- docs/scanner/migrating-to-androidx/index.html | 4 +- docs/scanner/migrating-to-v5.1/index.html | 4 +- .../scanner/migrating-to-version-5/index.html | 4 +- docs/scanner/requesting-access/index.html | 4 +- docs/scanner/scanning-bitmap-data/index.html | 4 +- docs/scanner/scanning/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/sensormanager/changelog/index.html | 4 +- docs/sensormanager/index.html | 4 +- docs/sensormanager/proximity/index.html | 4 +- docs/share/add-the-extension/index.html | 4 +- docs/share/add-the-plugin/index.html | 4 +- docs/share/android-events/index.html | 4 +- .../appextension---introduction/index.html | 4 +- docs/share/appextension---setup/index.html | 4 +- .../appextension---share-extension/index.html | 4 +- docs/share/changelog/index.html | 4 +- docs/share/email/index.html | 4 +- docs/share/index.html | 4 +- docs/share/launch-applications/index.html | 4 +- docs/share/migrating-from-message/index.html | 4 +- docs/share/migrating-to-androidx/index.html | 4 +- docs/share/migrating-to-v7.4/index.html | 4 +- docs/share/positioning/index.html | 4 +- docs/share/share-files/index.html | 4 +- docs/share/simple-share/index.html | 4 +- docs/share/sms/index.html | 4 +- docs/share/unity/index.html | 4 +- docs/singular/add-the-extension/index.html | 4 +- docs/singular/advanced-options/index.html | 4 +- docs/singular/changelog/index.html | 4 +- docs/singular/index.html | 4 +- docs/singular/initialise/index.html | 4 +- docs/singular/tracking-events/index.html | 4 +- docs/speech/add-the-extension/index.html | 4 +- docs/speech/authorisation/index.html | 4 +- docs/speech/changelog/index.html | 4 +- docs/speech/index.html | 4 +- docs/speech/recognition/index.html | 4 +- docs/speech/texttospeech/index.html | 4 +- docs/square libs/changelog/index.html | 4 +- docs/squarelibs/changelog/index.html | 4 +- docs/styles/index.html | 4 +- .../add-the-extension/index.html | 4 +- docs/systemgestures/changelog/index.html | 4 +- .../defer-system-gestures/index.html | 4 +- docs/systemgestures/home-indicator/index.html | 4 +- docs/systemgestures/index.html | 4 +- .../native-gesture-events/index.html | 4 +- .../android-adaptive-icons/index.html | 4 +- .../android-device-debugging/index.html | 4 +- docs/tutorials/android-resources/index.html | 4 +- .../android-splash-screen/index.html | 4 +- docs/tutorials/device-logs/index.html | 4 +- .../getting-started-animate/index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- .../getting-started-flashdevelop/index.html | 4 +- .../getting-started-intellij/index.html | 4 +- docs/tutorials/getting-started/index.html | 4 +- docs/tutorials/index.html | 4 +- .../tutorials/ios-icons-assets-car/index.html | 4 +- docs/tutorials/ios-launchscreens/index.html | 4 +- docs/tutorials/ios-sdk-custom/index.html | 4 +- docs/tutorials/ios-sdk-versions/index.html | 4 +- .../windows-appx-packaging-method1/index.html | 4 +- .../windows-appx-packaging-method2/index.html | 4 +- .../windows-appx-packaging-method3/index.html | 4 +- .../windows-appx-packaging/index.html | 4 +- docs/unityads/add-the-extension/index.html | 4 +- docs/unityads/changelog/index.html | 4 +- docs/unityads/index.html | 4 +- docs/unityads/initialise/index.html | 4 +- docs/unityads/interstitials/index.html | 4 +- docs/vibration/add-the-extension/index.html | 4 +- docs/vibration/add-the-plugin/index.html | 4 +- docs/vibration/changelog/index.html | 4 +- docs/vibration/feedback-generators/index.html | 4 +- docs/vibration/haptic-engine/index.html | 4 +- docs/vibration/index.html | 4 +- docs/vibration/unity/index.html | 4 +- docs/vibration/vibrate/index.html | 4 +- docs/volume/add-the-extension/index.html | 4 +- docs/volume/changelog/index.html | 4 +- docs/volume/index.html | 4 +- docs/volume/silent-switch/index.html | 4 +- docs/volume/streams/index.html | 4 +- docs/volume/volume-control/index.html | 4 +- docs/webp/add-the-extension/index.html | 4 +- docs/webp/changelog/index.html | 4 +- docs/webp/index.html | 4 +- docs/webp/load-a-webp-file/index.html | 4 +- docs/webp/parse-webp-data/index.html | 4 +- docs/webp/webploader/index.html | 4 +- .../windowsstore/add-the-extension/index.html | 4 +- docs/windowsstore/changelog/index.html | 4 +- docs/windowsstore/consumables/index.html | 4 +- docs/windowsstore/index.html | 4 +- .../initialise-the-extension/index.html | 4 +- docs/windowsstore/make-purchase/index.html | 4 +- docs/windowsstore/products/index.html | 4 +- docs/windowsstore/purchases/index.html | 4 +- .../windows-desktop-app-converter/index.html | 4 +- .../windows-developer-account/index.html | 4 +- docs/windowsstore/windows-overview/index.html | 4 +- docs/ziputils/add-the-extension/index.html | 4 +- docs/ziputils/changelog/index.html | 4 +- docs/ziputils/index.html | 4 +- docs/ziputils/unzipping-a-file/index.html | 4 +- docs/ziputils/zipping/index.html | 4 +- index.html | 4 +- news/2020-11/index.html | 4 +- news/2020-12/index.html | 4 +- news/2021-01/index.html | 4 +- news/2021-02/index.html | 4 +- news/2021-03/index.html | 4 +- news/2021-04/index.html | 4 +- news/2021-05/index.html | 4 +- news/2021-06/index.html | 4 +- news/2021-07/index.html | 4 +- news/2021-08/index.html | 4 +- news/2021-09/index.html | 4 +- news/2021-10/index.html | 4 +- news/2021-11/index.html | 4 +- news/2022-01/index.html | 4 +- news/2022-02/index.html | 4 +- news/2022-03/index.html | 4 +- news/2022-06/index.html | 4 +- news/2022-07/index.html | 4 +- news/2022-08/index.html | 4 +- news/2022-09/index.html | 4 +- news/2022-10/index.html | 4 +- news/2022-11/index.html | 4 +- .../06/15/accessing-gdpr-settings/index.html | 4 +- .../10/07/inappbilling-v14-update/index.html | 4 +- news/2023-01/index.html | 4 +- .../08/25/game-center-entitlement/index.html | 4 +- news/archive/index.html | 4 +- news/index.html | 4 +- news/page/2/index.html | 4 +- news/page/3/index.html | 4 +- news/tags/admob/index.html | 4 +- news/tags/adskit/index.html | 4 +- news/tags/advertising/index.html | 4 +- news/tags/adverts/index.html | 4 +- news/tags/air/index.html | 4 +- news/tags/air/page/2/index.html | 4 +- news/tags/airsdk-dev/index.html | 4 +- news/tags/airsdk/index.html | 4 +- news/tags/android-30/index.html | 4 +- news/tags/ane/index.html | 4 +- news/tags/apm/index.html | 4 +- news/tags/apm/page/2/index.html | 4 +- news/tags/apple/index.html | 4 +- news/tags/application-rater/index.html | 4 +- news/tags/crashlytics/index.html | 4 +- news/tags/cutouts/index.html | 4 +- news/tags/dialog/index.html | 4 +- news/tags/documentation/index.html | 4 +- news/tags/dynamicicon/index.html | 4 +- news/tags/facebook/index.html | 4 +- news/tags/fcm/index.html | 4 +- news/tags/firebase/index.html | 4 +- news/tags/flash-eol/index.html | 4 +- news/tags/game-services/index.html | 4 +- news/tags/gamecenter/index.html | 4 +- news/tags/gamecontroller/index.html | 4 +- news/tags/gameservices/index.html | 4 +- news/tags/gdpr/index.html | 4 +- news/tags/google-play-billing/index.html | 4 +- news/tags/google-play-services/index.html | 4 +- news/tags/hello/index.html | 4 +- news/tags/huawei/index.html | 4 +- news/tags/inappbilling/index.html | 4 +- news/tags/index.html | 4 +- news/tags/ios-simulator/index.html | 4 +- news/tags/ios/index.html | 4 +- news/tags/ironsource/index.html | 4 +- news/tags/nativewebview/index.html | 4 +- news/tags/newsletter/index.html | 4 +- news/tags/newsletter/page/2/index.html | 4 +- news/tags/newsletter/page/3/index.html | 4 +- news/tags/nfc/index.html | 4 +- news/tags/permissions/index.html | 4 +- news/tags/playbilling/index.html | 4 +- news/tags/samsung/index.html | 4 +- news/tags/scanner/index.html | 4 +- news/tags/swc/index.html | 4 +- news/tags/unity/index.html | 4 +- news/welcome/index.html | 4 +- search/index.html | 4 +- 1078 files changed, 2347 insertions(+), 2586 deletions(-) create mode 100644 asdocs/contacts/com/distriqt/extension/contacts/ContactPickerOptions.html delete mode 100644 assets/js/3e86e93e.0d253a19.js create mode 100644 assets/js/3e86e93e.e07e59af.js rename assets/js/{935f2afb.fa576174.js => 935f2afb.33ddf85f.js} (99%) rename assets/js/{runtime~main.394ca64f.js => runtime~main.ccf4ba71.js} (99%) diff --git a/404.html b/404.html index dcd126b34d0..e741222b3f9 100644 --- a/404.html +++ b/404.html @@ -13,13 +13,13 @@ - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/asdocs/contacts/all-classes.html b/asdocs/contacts/all-classes.html index d2ec9c13507..3c9335eb6d5 100644 --- a/asdocs/contacts/all-classes.html +++ b/asdocs/contacts/all-classes.html @@ -28,6 +28,9 @@

All Cla ContactOrganisation + + ContactPickerOptions + ContactProperty @@ -49,4 +52,4 @@

All Cla - \ No newline at end of file + \ No newline at end of file diff --git a/asdocs/contacts/all-index-A.html b/asdocs/contacts/all-index-A.html index f134452102f..d35aaf5fc3c 100644 --- a/asdocs/contacts/all-index-A.html +++ b/asdocs/contacts/all-index-A.html @@ -11,30 +11,25 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("A Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
ACCESS_DENIED — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when the user DENIES permission for the application to access the contact information.
ACCESS_GRANTED — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when the user GRANTS permission for the application to access the contact information.
addContact(contact:com.distriqt.extension.contacts.model:Contact) — method, class com.distriqt.extension.contacts.Contacts
- Adds a contact to the user's address book.
addContactWithUI(contact:com.distriqt.extension.contacts.model:Contact) — method, class com.distriqt.extension.contacts.Contacts
- - Unimplemented - -
Address — class, package com.distriqt.extension.contacts.model
+ Adds a contact to the user's address book.
ADD_CONTACT_COMPLETE — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
+ Dispatched when a contact has been added and the contact information available.
addContactWithUI(contact:com.distriqt.extension.contacts.model:Contact) — method, class com.distriqt.extension.contacts.Contacts
Address — class, package com.distriqt.extension.contacts.model
Represents an address for a contact, the properties array will contain all the available information about the contact's mailing / postal address.
Address() — Constructor, class com.distriqt.extension.contacts.model.Address
Constructor
addresses — Property, class com.distriqt.extension.contacts.model.Contact
- The available addresses for the contact.
authorisation:changed — Event, class com.distriqt.extension.contacts.Contacts
AuthorisationEvent — class, package com.distriqt.extension.contacts.events
AuthorisationEvent(type:String, status:String, bubbles:Boolean, cancelable:Boolean) — Constructor, class com.distriqt.extension.contacts.events.AuthorisationEvent
- Constructor -
authorisationStatus() — method, class com.distriqt.extension.contacts.Contacts
+ The available addresses for the contact.
allowMultipleSelection — Property, class com.distriqt.extension.contacts.ContactPickerOptions
authorisation:changed — Event, class com.distriqt.extension.contacts.Contacts
AuthorisationEvent — class, package com.distriqt.extension.contacts.events
AuthorisationEvent(type:String, status:String, bubbles:Boolean, cancelable:Boolean) — Constructor, class com.distriqt.extension.contacts.events.AuthorisationEvent
+ Constructor +
authorisationStatus() — method, class com.distriqt.extension.contacts.Contacts
Retrieves the current authorisation status of this application.
AuthorisationStatus — class, package com.distriqt.extension.contacts
AuthorisationStatus() — Constructor, class com.distriqt.extension.contacts.AuthorisationStatus
Constructor
AUTHORISED — Constant Static Property, class com.distriqt.extension.contacts.AuthorisationStatus
User has authorized this application to access contacts -
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-B.html b/asdocs/contacts/all-index-B.html index 9bfde8589b7..05e94d2226e 100644 --- a/asdocs/contacts/all-index-B.html +++ b/asdocs/contacts/all-index-B.html @@ -11,7 +11,5 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("B Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
birthday — Property, class com.distriqt.extension.contacts.model.Contact
- - A birthday date string in the format dd-mm-yyyy - -
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A birthday date string in the format yyyy-MM-dd + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-C.html b/asdocs/contacts/all-index-C.html index 159fab6d832..6847e17d05d 100644 --- a/asdocs/contacts/all-index-C.html +++ b/asdocs/contacts/all-index-C.html @@ -11,7 +11,6 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("C Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
CHANGED — Constant Static Property, class com.distriqt.extension.contacts.events.AuthorisationEvent
- Dispatched when the user changes the authorisation status.
clone() — method, class com.distriqt.extension.contacts.events.AuthorisationEvent
clone() — method, class com.distriqt.extension.contacts.events.ContactsEvent
clone() — method, class com.distriqt.extension.contacts.events.ContactsJSONEvent
com.distriqt.extension.contacts — package
com.distriqt.extension.contacts.events — package
com.distriqt.extension.contacts.model — package
Contact — class, package com.distriqt.extension.contacts.model
Contact model class @@ -28,28 +27,24 @@ Basic
ContactOrganisation — class, package com.distriqt.extension.contacts.model
ContactOrganisation() — Constructor, class com.distriqt.extension.contacts.model.ContactOrganisation
CONTACTPICKER_CANCEL — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when the user cancels the contact picker selection.
CONTACTPICKER_CLOSED — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when the contact picker is closed.
CONTACTPICKER_ERROR — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- - Dispatched if there was an error launching the contact picker.
ContactProperty — class, package com.distriqt.extension.contacts.model
ContactProperty(label:String, value:String, isPrimary:Boolean) — Constructor, class com.distriqt.extension.contacts.model.ContactProperty
Contacts — class, package com.distriqt.extension.contacts
+ Dispatched if there was an error launching the contact picker.
ContactPickerOptions — class, package com.distriqt.extension.contacts
+ Controls available options for the contact picker +
ContactPickerOptions() — Constructor, class com.distriqt.extension.contacts.ContactPickerOptions
ContactProperty — class, package com.distriqt.extension.contacts.model
ContactProperty(label:String, value:String, isPrimary:Boolean) — Constructor, class com.distriqt.extension.contacts.model.ContactProperty
Contacts — class, package com.distriqt.extension.contacts
This class represents the Contacts extension.
Contacts() — Constructor, class com.distriqt.extension.contacts.Contacts
Constructor You should not call this directly, but instead use the singleton access
contacts:access:denied — Event, class com.distriqt.extension.contacts.Contacts
contacts:access:granted — Event, class com.distriqt.extension.contacts.Contacts
contacts:contact:selected — Event, class com.distriqt.extension.contacts.Contacts
contacts:contactpicker:cancel — Event, class com.distriqt.extension.contacts.Contacts
contacts:contactpicker:closed — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:basic — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:error — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:extended — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:json — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:json:error — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:modified — Event, class com.distriqt.extension.contacts.Contacts
contacts:get:contacts:modified:json — Event, class com.distriqt.extension.contacts.Contacts
contacts:save:images:complete — Event, class com.distriqt.extension.contacts.Contacts
contacts:save:images:error — Event, class com.distriqt.extension.contacts.Contacts
CONTACT_SELECTED — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when a contact has been selected from the contact picker.
ContactsEvent — class, package com.distriqt.extension.contacts.events
The event dispatched by the Contacts Extension
ContactsEvent(type:String, data:Array, message:String, bubbles:Boolean, cancelable:Boolean) — Constructor, class com.distriqt.extension.contacts.events.ContactsEvent
Constructor
ContactsJSONEvent — class, package com.distriqt.extension.contacts.events
- Dispatched regarding JSON retrieval events - -
ContactsJSONEvent(type:String, json:String, bubbles:Boolean, cancelable:Boolean) — Constructor, class com.distriqt.extension.contacts.events.ContactsJSONEvent
+
ContactsJSONEvent(type:String, json:String, bubbles:Boolean, cancelable:Boolean) — Constructor, class com.distriqt.extension.contacts.events.ContactsJSONEvent
Constructor
createFromObject(data:Object) — method, class com.distriqt.extension.contacts.model.Address
creationDate — Property, class com.distriqt.extension.contacts.model.Contact
- The date this contact was created.
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + The date this contact was created.A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-D.html b/asdocs/contacts/all-index-D.html index d3ddf0e968b..d3adcde36a6 100644 --- a/asdocs/contacts/all-index-D.html +++ b/asdocs/contacts/all-index-D.html @@ -11,17 +11,14 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("D Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
data — Property, class com.distriqt.extension.contacts.events.ContactsEvent
- This field contains any data attached to the event.
dates — Property, class com.distriqt.extension.contacts.model.Contact
List of dates associated with this contact, such as anniversaries etc
dateString — Property, class com.distriqt.extension.contacts.model.ContactDate
- The date string in the format dd-mm-yyyy -
DENIED — Constant Static Property, class com.distriqt.extension.contacts.AuthorisationStatus
User has explicitly denied this application access to contacts
dispose() — method, class com.distriqt.extension.contacts.Contacts
- Disposes the extension and releases any allocated resources.
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + Disposes the extension and releases any allocated resources.A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-E.html b/asdocs/contacts/all-index-E.html index f311fd409a9..b311b8d27a7 100644 --- a/asdocs/contacts/all-index-E.html +++ b/asdocs/contacts/all-index-E.html @@ -17,4 +17,4 @@ The number of email addresses associated with this contact Basic - EXT_CONTEXT_ID — Constant Static Property, class com.distriqt.extension.contacts.ContactsA  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + EXT_CONTEXT_ID — Constant Static Property, class com.distriqt.extension.contacts.ContactsA  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-F.html b/asdocs/contacts/all-index-F.html index d8b179ac3a1..7134268e2b6 100644 --- a/asdocs/contacts/all-index-F.html +++ b/asdocs/contacts/all-index-F.html @@ -15,8 +15,8 @@ First name Basic - fromObject(data:Object) — Static Method , class com.distriqt.extension.contacts.model.AddressfromObject(data:Object) — Static Method , class com.distriqt.extension.contacts.model.ContactfullName — Property, class com.distriqt.extension.contacts.model.Contact + fromObject(data:Object) — Static Method , class com.distriqt.extension.contacts.model.AddressfromObject(data:Object) — Static Method , class com.distriqt.extension.contacts.model.ContactfromObject(data:Object) — Static Method , class com.distriqt.extension.contacts.model.InstantMessageServicefromObject(data:Object) — Static Method , class com.distriqt.extension.contacts.model.SocialServicefullName — Property, class com.distriqt.extension.contacts.model.Contact The full name of the contact, generally the same as firstName + lastName - A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-G.html b/asdocs/contacts/all-index-G.html index 320241ad2f7..3502d232c4b 100644 --- a/asdocs/contacts/all-index-G.html +++ b/asdocs/contacts/all-index-G.html @@ -10,13 +10,10 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("G Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
getContactDetails(contactId:int, loadImage:Boolean) — method, class com.distriqt.extension.contacts.Contacts
- +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
getContactDetails(contactId:String, loadImage:Boolean) — method, class com.distriqt.extension.contacts.Contacts
Retrieves the contact information object for the specified contact id including the contact image if available - - -
getContactImage(contactId:int) — method, class com.distriqt.extension.contacts.Contacts
+
getContactImage(contactId:String) — method, class com.distriqt.extension.contacts.Contacts
Load the BitmapData image for the specified contact.
getContactList(loadImages:Boolean) — method, class com.distriqt.extension.contacts.Contacts
@@ -25,38 +22,31 @@ Retrieves the contact list as JSON asynchronously.
getContactListAsync(loadImages:Boolean) — method, class com.distriqt.extension.contacts.Contacts
- Asynchronously retrieves a list of the users contacts containing + Asynchronously retrieves a list of the users contacts containing only basic information about each contact.
getContactListExtended(loadImages:Boolean) — method, class com.distriqt.extension.contacts.Contacts
- Retrieves a list of the users contacts containing all information available + Retrieves a list of the users contacts containing all information available about each contact.
getContactListExtendedAsync(loadImages:Boolean) — method, class com.distriqt.extension.contacts.Contacts
- Asynchronously retrieves a list of the users contacts containing + Asynchronously retrieves a list of the users contacts containing all information about each contact.
getContactListModifiedSince(date:Date) — method, class com.distriqt.extension.contacts.Contacts
Retrieves the list of contacts that have been updated / modified after the specified date.
getContactListModifiedSinceAsJSON(date:Date) — method, class com.distriqt.extension.contacts.Contacts
Retrieves the list of contacts that have been updated / modified after the specified date as JSON asynchronously.
GET_CONTACTS — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched after a successful call to getContactListAsync The data field will contain the array of contacts that were retrieved.
GET_CONTACTS_ERROR — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when an error occurs while retrieving the contact list.
GET_CONTACTS_EXTENDED — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched after a successful call to getContactListExtendedAsync The data field will contain the array of contacts that were retrieved.
GET_CONTACTS_JSON — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsJSONEvent
- Dispatched when the JSON representation of the contact list has been retrieved.
GET_CONTACTS_JSON_ERROR — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsJSONEvent
- Dispatched when an error occurs retrieving the JSON representation of the contact list.
GET_CONTACTS_MODIFIED — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched after a successful call to getContactListModifiedSince The data field will contain the array of contacts that were retrieved.
GET_CONTACTS_MODIFIED_JSON — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsJSONEvent
- Dispatched when the JSON representation of the modified contact - list has been retrieved.
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + list has been retrieved.
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-H.html b/asdocs/contacts/all-index-H.html index 88d72b0bb77..2c7f392194d 100644 --- a/asdocs/contacts/all-index-H.html +++ b/asdocs/contacts/all-index-H.html @@ -12,7 +12,7 @@ -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
hasAccess() — method, class com.distriqt.extension.contacts.Contacts
- Checks if the user has granted your application access to the + Checks if the user has granted your application access to the contacts.
hasImage — Property, class com.distriqt.extension.contacts.model.Contact
If true this contact has an image available -
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-I.html b/asdocs/contacts/all-index-I.html index 443f9d54620..5e73bf27dd5 100644 --- a/asdocs/contacts/all-index-I.html +++ b/asdocs/contacts/all-index-I.html @@ -10,7 +10,7 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("I Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
image — Property, class com.distriqt.extension.contacts.model.Contact
+

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
identifier — Property, class com.distriqt.extension.contacts.model.SocialService
image — Property, class com.distriqt.extension.contacts.model.Contact
The image / icon set in the address book for the contact.
imageHeight — Property, class com.distriqt.extension.contacts.model.Contact
The height of the user icon @@ -19,7 +19,7 @@
implementation — Property, class com.distriqt.extension.contacts.Contacts
The implementation currently in use.
init(key:String) — Static Method , class com.distriqt.extension.contacts.Contacts
- Initialises the extension class for use with the provided key.
InstantMessageService — class, package com.distriqt.extension.contacts.model
InstantMessageService(service:String, username:String) — Constructor, class com.distriqt.extension.contacts.model.InstantMessageService
+ Initialises the extension class for use with the provided key.
InstantMessageService — class, package com.distriqt.extension.contacts.model
InstantMessageService(service:String, username:String, label:String) — Constructor, class com.distriqt.extension.contacts.model.InstantMessageService
Constructor
instantMessaging — Property, class com.distriqt.extension.contacts.model.Contact
@@ -28,4 +28,4 @@
isPrimary — Property, class com.distriqt.extension.contacts.model.ContactProperty
isSupported — Static Property, class com.distriqt.extension.contacts.Contacts
Whether the current device supports the extensions functionality -
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-J.html b/asdocs/contacts/all-index-J.html index 877ec49f1c3..392727a80e1 100644 --- a/asdocs/contacts/all-index-J.html +++ b/asdocs/contacts/all-index-J.html @@ -11,7 +11,5 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("J Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
json — Property, class com.distriqt.extension.contacts.events.ContactsJSONEvent
- The JSON data associated with this event - -
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-K.html b/asdocs/contacts/all-index-K.html index 3000a929140..86b24aded72 100644 --- a/asdocs/contacts/all-index-K.html +++ b/asdocs/contacts/all-index-K.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("K Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-L.html b/asdocs/contacts/all-index-L.html index ed3d449bdb6..c0d06990cb1 100644 --- a/asdocs/contacts/all-index-L.html +++ b/asdocs/contacts/all-index-L.html @@ -10,11 +10,9 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("L Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
label — Property, class com.distriqt.extension.contacts.model.ContactDate
- +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
label — Property, class com.distriqt.extension.contacts.model.Address
label — Property, class com.distriqt.extension.contacts.model.ContactDate
A label associated with this date value - -
label — Property, class com.distriqt.extension.contacts.model.ContactProperty
LABEL_CITY — Constant Static Property, class com.distriqt.extension.contacts.model.Address
+
label — Property, class com.distriqt.extension.contacts.model.ContactProperty
label — Property, class com.distriqt.extension.contacts.model.InstantMessageService
label — Property, class com.distriqt.extension.contacts.model.SocialService
LABEL_CITY — Constant Static Property, class com.distriqt.extension.contacts.model.Address
Label for the contact property representing the city of this address
LABEL_COUNTRY — Constant Static Property, class com.distriqt.extension.contacts.model.Address
Label for the contact property representing the country of this address @@ -28,4 +26,4 @@ Last name Basic -
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-M.html b/asdocs/contacts/all-index-M.html index 7616ca1074e..c15da338487 100644 --- a/asdocs/contacts/all-index-M.html +++ b/asdocs/contacts/all-index-M.html @@ -11,11 +11,10 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("M Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
message — Property, class com.distriqt.extension.contacts.events.ContactsEvent
- A message associated with this event.
middleName — Property, class com.distriqt.extension.contacts.model.Contact
Contact middle name
modificationDate — Property, class com.distriqt.extension.contacts.model.Contact
- The date this contact was last modified in the address book.
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + The date this contact was last modified in the address book.A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-N.html b/asdocs/contacts/all-index-N.html index 24c4f8883dc..41fe7fbddeb 100644 --- a/asdocs/contacts/all-index-N.html +++ b/asdocs/contacts/all-index-N.html @@ -18,4 +18,4 @@ A user note for this contact - A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-O.html b/asdocs/contacts/all-index-O.html index d91b8e10f11..2d869371b2a 100644 --- a/asdocs/contacts/all-index-O.html +++ b/asdocs/contacts/all-index-O.html @@ -12,4 +12,4 @@ -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
organisation — Property, class com.distriqt.extension.contacts.model.Contact
- Information about the contacts associated organsation.
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + Information about the contacts associated organsation.A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-P.html b/asdocs/contacts/all-index-P.html index 7a723c86479..12d282dfce8 100644 --- a/asdocs/contacts/all-index-P.html +++ b/asdocs/contacts/all-index-P.html @@ -17,4 +17,4 @@ Basic phoneNumbers — Property, class com.distriqt.extension.contacts.model.Contact - List of phone numbers associated with this contact.prefix — Property, class com.distriqt.extension.contacts.model.Contactproperties — Property, class com.distriqt.extension.contacts.model.AddressA  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + List of phone numbers associated with this contact.prefix — Property, class com.distriqt.extension.contacts.model.Contactproperties — Property, class com.distriqt.extension.contacts.model.AddressA  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-Q.html b/asdocs/contacts/all-index-Q.html index e318d37aca2..bbd409f3493 100644 --- a/asdocs/contacts/all-index-Q.html +++ b/asdocs/contacts/all-index-Q.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("Q Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-R.html b/asdocs/contacts/all-index-R.html index 7aec457b554..35935a6cb62 100644 --- a/asdocs/contacts/all-index-R.html +++ b/asdocs/contacts/all-index-R.html @@ -17,4 +17,4 @@ requestAccess() — method, class com.distriqt.extension.contacts.Contacts Requests access to the user contacts.RESTRICTED — Constant Static Property, class com.distriqt.extension.contacts.AuthorisationStatus - This application is not authorized to access contacts.A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + This application is not authorized to access contacts.A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-S.html b/asdocs/contacts/all-index-S.html index 573e07e8fa0..0102dc6f825 100644 --- a/asdocs/contacts/all-index-S.html +++ b/asdocs/contacts/all-index-S.html @@ -10,16 +10,13 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("S Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
saveContactImage(contactId:int, destination:flash.filesystem:File) — method, class com.distriqt.extension.contacts.Contacts
+

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
saveContactImage(contactId:String, destination:flash.filesystem:File) — method, class com.distriqt.extension.contacts.Contacts
This function will attempt to save any image for the specified contact to the specified folder.
saveContactImages(destination:flash.filesystem:File) — method, class com.distriqt.extension.contacts.Contacts
This function will save any available contact images to the specified folder.
SAVE_IMAGES_COMPLETE — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched when a call to saveContactImages completes successfully.
SAVE_IMAGES_ERROR — Constant Static Property, class com.distriqt.extension.contacts.events.ContactsEvent
- Dispatched if an error occurred when saving the contact images -
service — Static Property, class com.distriqt.extension.contacts.Contacts
The singleton instance of the Extension class.
service — Property, class com.distriqt.extension.contacts.model.InstantMessageService
@@ -27,9 +24,9 @@
service — Property, class com.distriqt.extension.contacts.model.SocialService
Social profile service -
SHOULD_EXPLAIN — Constant Static Property, class com.distriqt.extension.contacts.AuthorisationStatus
+
setAllowMultipleSelection(allow:Boolean) — method, class com.distriqt.extension.contacts.ContactPickerOptions
SHOULD_EXPLAIN — Constant Static Property, class com.distriqt.extension.contacts.AuthorisationStatus
- This status means that the user has previously denied access.
showContactPicker() — method, class com.distriqt.extension.contacts.Contacts
+ This status means that the user has previously denied access.
showContactPicker(options:com.distriqt.extension.contacts:ContactPickerOptions) — method, class com.distriqt.extension.contacts.Contacts
Shows a native select dialog for the user to choose a contact from the available contacts.
SocialService — class, package com.distriqt.extension.contacts.model
SocialService(service:String, username:String, url:String) — Constructor, class com.distriqt.extension.contacts.model.SocialService
@@ -38,4 +35,4 @@ Social services associated with this contact -
status — Property, class com.distriqt.extension.contacts.events.AuthorisationEvent
suffix — Property, class com.distriqt.extension.contacts.model.Contact
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +
status — Property, class com.distriqt.extension.contacts.events.AuthorisationEvent
suffix — Property, class com.distriqt.extension.contacts.model.Contact
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-T.html b/asdocs/contacts/all-index-T.html index 5fc76926cbd..52742838c07 100644 --- a/asdocs/contacts/all-index-T.html +++ b/asdocs/contacts/all-index-T.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("T Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
title — Property, class com.distriqt.extension.contacts.model.ContactOrganisation
toString() — method, class com.distriqt.extension.contacts.model.Address
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
title — Property, class com.distriqt.extension.contacts.model.ContactOrganisation
toString() — method, class com.distriqt.extension.contacts.model.Address
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-U.html b/asdocs/contacts/all-index-U.html index e33f97aa7b5..a9f3030f611 100644 --- a/asdocs/contacts/all-index-U.html +++ b/asdocs/contacts/all-index-U.html @@ -20,4 +20,4 @@ username — Property, class com.distriqt.extension.contacts.model.SocialService Social profile username - A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-V.html b/asdocs/contacts/all-index-V.html index 3390f85c485..a974dcf405c 100644 --- a/asdocs/contacts/all-index-V.html +++ b/asdocs/contacts/all-index-V.html @@ -12,4 +12,4 @@ -->

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
value — Property, class com.distriqt.extension.contacts.model.ContactProperty
version — Property, class com.distriqt.extension.contacts.Contacts
- The version of this extension.
VERSION — Constant Static Property, class com.distriqt.extension.contacts.Contacts
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + The version of this extension.VERSION — Constant Static Property, class com.distriqt.extension.contacts.ContactsA  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-W.html b/asdocs/contacts/all-index-W.html index 557cc9c73d4..3f27fbd3072 100644 --- a/asdocs/contacts/all-index-W.html +++ b/asdocs/contacts/all-index-W.html @@ -14,4 +14,4 @@ List of websites / urls associated with this contact - A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file + A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-X.html b/asdocs/contacts/all-index-X.html index 2e4c0c7258b..20cf445e289 100644 --- a/asdocs/contacts/all-index-X.html +++ b/asdocs/contacts/all-index-X.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("X Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-Y.html b/asdocs/contacts/all-index-Y.html index bbe02e39733..4bf00679947 100644 --- a/asdocs/contacts/all-index-Y.html +++ b/asdocs/contacts/all-index-Y.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("Y Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/all-index-Z.html b/asdocs/contacts/all-index-Z.html index 495658cd87c..b63bdeb5a59 100644 --- a/asdocs/contacts/all-index-Z.html +++ b/asdocs/contacts/all-index-Z.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("Z Index"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> -

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file +

A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  

\ No newline at end of file diff --git a/asdocs/contacts/class-summary.html b/asdocs/contacts/class-summary.html index f5f33175a58..ad7876656d5 100644 --- a/asdocs/contacts/class-summary.html +++ b/asdocs/contacts/class-summary.html @@ -19,12 +19,12 @@ This class represents a contact, containing all information about the contact - available to your application. ContactDate
com.distriqt.extension.contacts.model  ContactOrganisation
com.distriqt.extension.contacts.model  ContactProperty
com.distriqt.extension.contacts.model  Contacts
com.distriqt.extension.contacts + available to your application. ContactDate
com.distriqt.extension.contacts.model  ContactOrganisation
com.distriqt.extension.contacts.model  ContactPickerOptions
com.distriqt.extension.contacts + Controls available options for the contact picker +  ContactProperty
com.distriqt.extension.contacts.model  Contacts
com.distriqt.extension.contacts - This class represents the Contacts extension. ContactsEvent
com.distriqt.extension.contacts.events + This class represents the Contacts extension. ContactsEvent
com.distriqt.extension.contacts.events The event dispatched by the Contacts Extension -  ContactsJSONEvent
com.distriqt.extension.contacts.events - +  ContactsJSONEvent
com.distriqt.extension.contacts.events Dispatched regarding JSON retrieval events - -  InstantMessageService
com.distriqt.extension.contacts.model  SocialService
com.distriqt.extension.contacts.model 

\ No newline at end of file +  InstantMessageService
com.distriqt.extension.contacts.model  SocialService
com.distriqt.extension.contacts.model 

\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/AuthorisationStatus.html b/asdocs/contacts/com/distriqt/extension/contacts/AuthorisationStatus.html index 92d4ee27b8b..6bd1952d508 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/AuthorisationStatus.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/AuthorisationStatus.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.AuthorisationStatus +
Packagecom.distriqt.extension.contacts
Classpublic class ContactPickerOptions
InheritanceContactPickerOptions Inheritance Object

+ Controls available options for the contact picker +



Public Properties
 PropertyDefined By
  allowMultipleSelection : Boolean = false
+
ContactPickerOptions
Public Methods
 MethodDefined By
  
ContactPickerOptions
  
+
ContactPickerOptions
Property Detail
allowMultipleSelectionproperty
public var allowMultipleSelection:Boolean = false

+

See also

Constructor Detail
ContactPickerOptions()Constructor
public function ContactPickerOptions()



Method Detail
setAllowMultipleSelection()method
public function setAllowMultipleSelection(allow:Boolean = true):ContactPickerOptions

+

Parameters
allow:Boolean (default = true)

Returns
ContactPickerOptions




\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/Contacts.html b/asdocs/contacts/com/distriqt/extension/contacts/Contacts.html index ec54be943a1..12ddc3ba55a 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/Contacts.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/Contacts.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.Contacts
Packagecom.distriqt.extension.contacts
Classpublic class Contacts
InheritanceContacts Inheritance flash.events.EventDispatcher

+
Packagecom.distriqt.extension.contacts
Classpublic class Contacts
InheritanceContacts Inheritance flash.events.EventDispatcher

This class represents the Contacts extension.

- - Permissions - -

+ Permissions +

The user has the ability to deny your application access to the contact list. So you must be prepared to handle the case when you can't access the list. - This is most significant on iOS as on Android the user will be required to - accept these as part of the installation process, however this extension + This is most significant on iOS as on Android the user will be required to + accept these as part of the installation process, however this extension has wrapped the functionality on each platform to match the coding required.

- -

- The following listing demonstrates how you should check for access to the +

+ The following listing demonstrates how you should check for access to the contacts list. You should do this every time you require access to the list as the user may have changed the permissions outside of this application.

- -

+

Under iOS the settings are found at: Settings / Privacy / Contacts / [Your application name]

- - - -
+	 	 	 	        
 Contacts.init( APPLICATION_KEY );
 Contacts.service.addEventListener( AuthorisationEvent.CHANGED, contacts_authorisationChangedHandler );
 switch (Contacts.service.authorisationStatus())
@@ -64,11 +57,8 @@
     // Check event.status
 }
      
- - - Retrieving a list of contacts - -

+ Retrieving a list of contacts +

There are 2 main functions to retrieve the list of contacts a user has on a device:

    @@ -77,23 +67,20 @@
  • getContactListExtended: Retrieves all details about every contact (see the following notes)
- -

- Each of these functions also has an asynchronous version which returns the list +

+ Each of these functions also has an asynchronous version which returns the list through an event. The asynchronous methods are the better versions as they do - not block the UI from continuing to update while the list of contacts is + not block the UI from continuing to update while the list of contacts is built.

- -

+

With a large number of contacts you may see some disturbance to the UI - as the contacts get converted to Actionscript objects even with the asychronous - versions. It's suggested you avoid attempting to retrieve the entire extended - contacts list but instead retrieve the basic list and then individually get + as the contacts get converted to Actionscript objects even with the asychronous + versions. It's suggested you avoid attempting to retrieve the entire extended + contacts list but instead retrieve the basic list and then individually get details on a contact of interest.

- -
+	 	            
 Contacts.init( APPLICATION_KEY );
 Contacts.service.addEventListener( ContactsEvent.GET_CONTACTS, contacts_getContactsHandler, false, 0, true );
 Contacts.service.getContactListAsync();
@@ -104,42 +91,29 @@
     {
         trace( "> " + contact.firstName + " " + contact.lastName + "  [ "+contact.fullName +" ]");
     }
-} 
-     
- - - - Retrieving a contact details - -

- You can retrieve the information about a single contact by using the +} +

+ Retrieving a contact details +

+ You can retrieve the information about a single contact by using the getContactDetails function, passing a contact id as a parameter. - This process used in combination with the basic list is the suggested method + This process used in combination with the basic list is the suggested method for best practices.

- -
+	 	            
 var contact:Contact = Contacts.service.getContactDetails( id );
 if (contact != null)
 {
     trace( "> " + contact.firstName + " " + contact.lastName + "  [ "+contact.fullName +" ]");
 }
      
- - - - - - - Android - -

+ Android +

You have to add the following permissions and activity to your application descriptors manifest additions node. This allows your application access to the neccessary data and adds in the required native activities.

- -
+	 	            
 <android>
     <manifestAdditions><![CDATA[
         <manifest android:installLocation="auto">
@@ -155,10 +129,7 @@
     ]]></manifestAdditions>
 </android>
      
- - - -

View the examples



Public Properties
 PropertyDefined By
  implementation : String
[read-only] +

View the examples



Public Properties
 PropertyDefined By
  implementation : String
[read-only] The implementation currently in use.
Contacts
  isSupported : Boolean
[static] [read-only] Whether the current device supports the extensions functionality @@ -174,19 +145,14 @@ Adds a contact to the user's address book.
Contacts
  
addContactWithUI(contact:Contact):Boolean
- Unimplemented -
Contacts
  
Retrieves the current authorisation status of this application.
Contacts
  
dispose():void
- Disposes the extension and releases any allocated resources.
Contacts
  
getContactDetails(contactId:int, loadImage:Boolean = false):Contact
- + Disposes the extension and releases any allocated resources.
Contacts
  
getContactDetails(contactId:String, loadImage:Boolean = false):Contact
Retrieves the contact information object for the specified contact id including the contact image if available - - -
Contacts
  
getContactImage(contactId:int):BitmapData
+
Contacts
  
getContactImage(contactId:String):BitmapData
Load the BitmapData image for the specified contact.
Contacts
  
getContactList(loadImages:Boolean = false):Vector.<Contact>
@@ -195,78 +161,62 @@ Retrieves the contact list as JSON asynchronously.
Contacts
  
getContactListAsync(loadImages:Boolean = false):Boolean
- Asynchronously retrieves a list of the users contacts containing + Asynchronously retrieves a list of the users contacts containing only basic information about each contact.
Contacts
  
getContactListExtended(loadImages:Boolean = false):Vector.<Contact>
- Retrieves a list of the users contacts containing all information available + Retrieves a list of the users contacts containing all information available about each contact.
Contacts
  
getContactListExtendedAsync(loadImages:Boolean = false):Boolean
- Asynchronously retrieves a list of the users contacts containing + Asynchronously retrieves a list of the users contacts containing all information about each contact.
Contacts
  
getContactListModifiedSince(date:Date):Boolean
Retrieves the list of contacts that have been updated / modified after the specified date.
Contacts
  
Retrieves the list of contacts that have been updated / modified after the specified date as JSON asynchronously.
Contacts
  
hasAccess():Boolean
- Checks if the user has granted your application access to the + Checks if the user has granted your application access to the contacts.
Contacts
  
init(key:String):void
Deprecated: You no longer need to use an application key
[static] Initialises the extension class for use with the provided key.
Contacts
  
requestAccess():Boolean
- Requests access to the user contacts.
Contacts
  
saveContactImage(contactId:int, destination:File):Boolean
+ Requests access to the user contacts.
Contacts
  
saveContactImage(contactId:String, destination:File):Boolean
This function will attempt to save any image for the specified contact to the specified folder.
Contacts
  
saveContactImages(destination:File):Boolean
- This function will save any available contact images to the specified folder.
Contacts
  
+ This function will save any available contact images to the specified folder.
Contacts
  
showContactPicker(options:ContactPickerOptions = null):Boolean
Shows a native select dialog for the user to choose a contact from the available contacts.
Contacts
Events
 Event Summary Defined By
   - Dispatched when the user changes the authorisation status.Contacts
   - Dispatched when the user DENIES permission for the application to access the contact information.Contacts
   - Dispatched when the user GRANTS permission for the application to access the contact information.Contacts
   - Dispatched when a contact has been selected from the contact picker.Contacts
   - Dispatched when the user cancels the contact picker selection.Contacts
   - Dispatched when the contact picker is closed.Contacts
   - Dispatched after a successful call to getContactListAsync The data field will contain the array of contacts that were retrieved.Contacts
   - Dispatched when an error occurs while retrieving the contact list.Contacts
   - Dispatched after a successful call to getContactListExtendedAsync The data field will contain the array of contacts that were retrieved.Contacts
   - Dispatched when the JSON representation of the contact list has been retrieved.Contacts
   - Dispatched when an error occurs retrieving the JSON representation of the contact list.Contacts
   - Dispatched after a successful call to getContactListModifiedSince The data field will contain the array of contacts that were retrieved.Contacts
   - Dispatched when the JSON representation of the modified contact list has been retrieved.Contacts
   - Dispatched when a call to saveContactImages completes successfully.Contacts
   - Dispatched if an error occurred when saving the contact images - - Contacts
Public Constants
 ConstantDefined By
  EXT_CONTEXT_ID : String = com.distriqt.Contacts
[static]
Contacts
  VERSION : String = 5.1.1
[static]
Contacts
Property Detail
implementationproperty
implementation:String  [read-only]

- The implementation currently in use. + The implementation currently in use. This should be one of the following depending on the platform in use and the functionality supported by this extension:

    @@ -299,21 +249,22 @@ Adds a contact to the user's address book.

    - Currently this supports: + Currently this supports:

    • first,middle,last names
    • +
    • note
    • +
    • organisation
    • phone numbers
    • emails
    • -
    • address
    • +
    • addresses
    • +
    • websites
    • +
    • social services (iOS Only)
    • +
    • instant messaging
    -

    - -

    Parameters
    contact:Contact

    Returns
    Boolean — true if the contact was successfully added to the address book - -
addContactWithUI()method 
public function addContactWithUI(contact:Contact):Boolean

-

- Unimplemented

+

Parameters
contact:Contact

Returns
Boolean — true if the contact was successfully added to the address book +
addContactWithUI()method 
public function addContactWithUI(contact:Contact):Boolean

+

Parameters
contact:Contact

Returns
Boolean
authorisationStatus()method 
public function authorisationStatus():String

Retrieves the current authorisation status of this application. @@ -321,62 +272,43 @@

There are several possible values as defined in the AuthorisationStatus class.

- -

Returns
String — The AuthorisationStatus string - -

See also

dispose()method 
public function dispose():void

+

Returns
String — The AuthorisationStatus string +

See also

dispose()method 
public function dispose():void

- Disposes the extension and releases any allocated resources. Once this function - has been called, a call to init is neccesary again before any of the + Disposes the extension and releases any allocated resources. Once this function + has been called, a call to init is neccesary again before any of the extensions functionality will work.

-

getContactDetails()method 
public function getContactDetails(contactId:int, loadImage:Boolean = false):Contact

-

+

getContactDetails()method 
public function getContactDetails(contactId:String, loadImage:Boolean = false):Contact

Retrieves the contact information object for the specified contact id including the contact image if available -

- -

Parameters
contactId:int — The unique identifier for the contact - -
 
loadImage:Boolean (default = false)

Returns
Contact — A Contact object representing the specified contact - -
getContactImage()method 
public function getContactImage(contactId:int):BitmapData

+

Parameters
contactId:String — The unique identifier for the contact +
 
loadImage:Boolean (default = false)

Returns
Contact — A Contact object representing the specified contact +
getContactImage()method 
public function getContactImage(contactId:String):BitmapData

Load the BitmapData image for the specified contact.

- -

Parameters
contactId:int — The unique identifier for the contact - -

Returns
BitmapData — A BitmapData object if the load was successful or null if the contact has no image. - -
getContactList()method 
public function getContactList(loadImages:Boolean = false):Vector.<Contact>

+

Parameters
contactId:String — The unique identifier for the contact +

Returns
BitmapData — A BitmapData object if the load was successful or null if the contact has no image. +
getContactList()method 
public function getContactList(loadImages:Boolean = false):Vector.<Contact>

Retrieves a list of the users contacts containing only basic information about each contact.

- -

- You should not use this function unless really necessary. The asynchronous +

+ You should not use this function unless really necessary. The asynchronous version is much better as it does not block the UI.

- -

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts - -

Returns
Vector.<Contact> — Vector array of Contact objects representing the user contact list - -

See also

getContactListAsync()
getContactListAsJSON()method 
public function getContactListAsJSON():Boolean

+

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts +

Returns
Vector.<Contact> — Vector array of Contact objects representing the user contact list +

See also

getContactListAsync()
getContactListAsJSON()method 
public function getContactListAsJSON():Boolean

- Retrieves the contact list as JSON asynchronously. + Retrieves the contact list as JSON asynchronously. Once the list is retrieved a ContactsJSONEvent will be dispatched containing the JSON string.

- -

Returns
Boolean — true if the retrieval was successfully started and false if there was an error - -

See also


Example
- - Simple example illustrating retrieving the JSON string of the contact list - -
+		 		 

Returns
Boolean — true if the retrieval was successfully started and false if there was an error +

See also


Example
Simple example illustrating retrieving the JSON string of the contact list +
 Contacts.service.addEventListener( ContactsJSONEvent.GET_CONTACTS_JSON, getContactsJSONHandler );
 Contacts.service.getContactListAsJSON();
 ...
@@ -385,79 +317,60 @@
     trace( event.json );
 }
          
- -
getContactListAsync()method 
public function getContactListAsync(loadImages:Boolean = false):Boolean

+

getContactListAsync()method 
public function getContactListAsync(loadImages:Boolean = false):Boolean

- Asynchronously retrieves a list of the users contacts containing - only basic information about each contact. The contacts are + Asynchronously retrieves a list of the users contacts containing + only basic information about each contact. The contacts are returned through the data property on a ContactsEvent.GET_CONTACTS.

- -

+

You should listen for two events before calling this function:

  • GET_CONTACTS_ERROR: when an error occurs
  • GET_CONTACTS: on successful completion
- -

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts - -

Returns
Boolean

See also

getContactListExtended()method 
public function getContactListExtended(loadImages:Boolean = false):Vector.<Contact>

+

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts +

Returns
Boolean

See also

getContactListExtended()method 
public function getContactListExtended(loadImages:Boolean = false):Vector.<Contact>

- Retrieves a list of the users contacts containing all information available + Retrieves a list of the users contacts containing all information available about each contact.

- -

- Please note this function may be slow if the user has a lot of contacts. +

+ Please note this function may be slow if the user has a lot of contacts. A better procedure is to list using the basic contact list and then individually retrieve details about specific contacts.

- -

- You should not use this function unless really necessary. The asynchronous +

+ You should not use this function unless really necessary. The asynchronous version is much better as it does not block the UI.

- -

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts - -

Returns
Vector.<Contact> — Vector array of Contact objects representing the user contact list - -

See also

getContactDetails()
getContactListBasic()
getContactListExtendedAsync()
getContactListExtendedAsync()method 
public function getContactListExtendedAsync(loadImages:Boolean = false):Boolean

+

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts +

Returns
Vector.<Contact> — Vector array of Contact objects representing the user contact list +

See also

getContactDetails()
getContactListBasic()
getContactListExtendedAsync()
getContactListExtendedAsync()method 
public function getContactListExtendedAsync(loadImages:Boolean = false):Boolean

- Asynchronously retrieves a list of the users contacts containing - all information about each contact. The contacts are + Asynchronously retrieves a list of the users contacts containing + all information about each contact. The contacts are returned through the data property on a ContactsEvent.GET_CONTACTS_EXTENDED.

- - -

+

You should listen for two events before calling this function:

  • GET_CONTACTS_ERROR: when an error occurs
  • GET_CONTACTS_EXTENDED: on successful completion
- -

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts - -

Returns
Boolean

See also

getContactListModifiedSince()method 
public function getContactListModifiedSince(date:Date):Boolean

+

Parameters
loadImages:Boolean (default = false) — If true then the contact image is populated for each of the retrieved contacts +

Returns
Boolean

See also

getContactListModifiedSince()method 
public function getContactListModifiedSince(date:Date):Boolean

Retrieves the list of contacts that have been updated / modified after the specified date. This allows you to retrieve contacts that have been recently updated.

- -

Parameters
date:Date — The start date to check for contact modification - -

Returns
Boolean — true if the retrieval was successfully started and false if there was an error - -

See also


Example
- - Simple example illustrating retrieving the contact list that has been modified since +

Parameters
date:Date — The start date to check for contact modification +

Returns
Boolean — true if the retrieval was successfully started and false if there was an error +

See also


Example
Simple example illustrating retrieving the contact list that has been modified since the 1st of october 2015. - -
+		 		 
 Contacts.service.addEventListener( ContactsEvent.GET_CONTACTS_MODIFIED, getContactsModifiedHandler );
 Contacts.service.getContactListModifiedSince( new Date( 2015, 9, 1 ) );
 ...
@@ -468,20 +381,14 @@
          
getContactListModifiedSinceAsJSON()method 
public function getContactListModifiedSinceAsJSON(date:Date):Boolean

- Retrieves the list of contacts that have been updated / modified after the specified date as JSON asynchronously. + Retrieves the list of contacts that have been updated / modified after the specified date as JSON asynchronously. Once the list is retrieved a ContactsJSONEvent will be dispatched containing the JSON string.

- -

Parameters
date:Date — The start date to check for contact modification - -

Returns
Boolean — true if the retrieval was successfully started and false if there was an error - -

See also


Example
- - Simple example illustrating retrieving the contact list that has been modified since +

Parameters
date:Date — The start date to check for contact modification +

Returns
Boolean — true if the retrieval was successfully started and false if there was an error +

See also


Example
Simple example illustrating retrieving the contact list that has been modified since the 1st of october 2015. - -
+		 		 
 Contacts.service.addEventListener( ContactsJSONEvent.GET_CONTACTS_MODIFIED_JSON, getContactsModifiedHandler );
 Contacts.service.getContactListModifiedSinceAsJSON( new Date( 2015, 9, 1 ) );
 ...
@@ -492,63 +399,47 @@
          
hasAccess()method 
public function hasAccess():Boolean

- Checks if the user has granted your application access to the + Checks if the user has granted your application access to the contacts.

- - Android < 6.0 - -

+ Android < 6.0 +

This will only return false under Android if you haven't correctly added the READ_CONTACTS permission to your applications manifest additions.

- - -

Returns
Boolean — true if the user has granted permissions and false - if they denied it or if the request access dialog +

Returns
Boolean — true if the user has granted permissions and false + if they denied it or if the request access dialog is yet to be shown. - -
init()method 
public static function init(key:String):void
Deprecated: You no longer need to use an application key

+

init()method 
public static function init(key:String):void
Deprecated: You no longer need to use an application key

Initialises the extension class for use with the provided key.

Parameters
key:String

requestAccess()method 
public function requestAccess():Boolean

Requests access to the user contacts. An AuthorisationEvent is dispatched with the result of the request.

- -

+

Note this will only be shown if the authorisation status is currently NOT_DETERMINED

- - iOS + iOS

On the first call to this it will present a dialog that will ask the user to grant permission for your application to access the contacts. They may deny access which will mean all other calls will fail. - In order to get access once they have denied it they have to change + In order to get access once they have denied it they have to change the permissions in the device settings.

- -

Returns
Boolean
saveContactImage()method 
public function saveContactImage(contactId:int, destination:File):Boolean

+

Returns
Boolean
saveContactImage()method 
public function saveContactImage(contactId:String, destination:File):Boolean

This function will attempt to save any image for the specified contact to the specified folder. - The destination should be a writable folder in your application, + The destination should be a writable folder in your application, eg File.applicationStorageDirectory.resolvePath( "contacts/images" ) -

- - -

Parameters
contactId:int — The id of the contact of interest +

+

Parameters
contactId:String — The id of the contact of interest
 
destination:File — A File object representing the destination directory. - - -

Returns
Boolean — true if the save process was successfully started and false if there was an error, +

Returns
Boolean — true if the save process was successfully started and false if there was an error, generally an issue with the destination file - -

Example
- - Simple example illustrating saving a contact image with id of 10 to "contacts/images". - -
+		 		 

Example

Simple example illustrating saving a contact image with id of 10 to "contacts/images". +
 Contacts.service.addEventListener( ContactsEvent.SAVE_IMAGES_COMPLETE, saveImagesCompleteHandler );
 var destination:File = File.applicationStorageDirectory.resolvePath( "contacts/images" );
 Contacts.service.saveContactImage( 10, destination );
@@ -568,20 +459,14 @@
 		 
saveContactImages()method 
public function saveContactImages(destination:File):Boolean

This function will save any available contact images to the specified folder. - The destination should be a writable folder in your application, + The destination should be a writable folder in your application, eg File.applicationStorageDirectory.resolvePath( "contacts/images" )

- -

Parameters
destination:File — A File object representing the destination directory. - -

Returns
Boolean — true if the save process was successfully started and false if there was an error, +

Parameters
destination:File — A File object representing the destination directory. +

Returns
Boolean — true if the save process was successfully started and false if there was an error, generally an issue with the destination file - -

Example
- - Simple example illustrating saving the contact images to "contacts/images". - -
+		 		 

Example
Simple example illustrating saving the contact images to "contacts/images". +
 Contacts.service.addEventListener( ContactsEvent.SAVE_IMAGES_COMPLETE, saveImagesCompleteHandler );
 var destination:File = File.applicationStorageDirectory.resolvePath( "contacts/images" );
 Contacts.service.saveContactImages( destination );
@@ -598,13 +483,12 @@
     }
 }
          
-
showContactPicker()method 
public function showContactPicker():Boolean

+

showContactPicker()method 
public function showContactPicker(options:ContactPickerOptions = null):Boolean

Shows a native select dialog for the user to choose a contact from the available contacts.

- -

+

This will return 3 possible events:

    @@ -612,127 +496,87 @@
  • CONTACTPICKER_CANCEL: When the user cancels the selection
  • CONTACTPICKER_CLOSED: Dispatched after the dialog is closed
- -

+

The CONTACT_SELECTED event will contain information about the contact.

- -

Returns
Boolean — true if the picker was successfully displayed and false if permission was denied - -

See also

Event Detail
authorisation:changed Event
Event Detail
authorisation:changed Event
Event Object Type: com.distriqt.extension.contacts.events.AuthorisationEvent
AuthorisationEvent.type property = com.distriqt.extension.contacts.events.AuthorisationEvent.CHANGED

-

Dispatched when the user changes the authorisation status. The status will indicate the new authorisation status. -

contacts:access:denied Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.ACCESS_DENIED

-

Dispatched when the user DENIES permission for the application to access the contact information. This will occur after a call to request access. -

-

- Note: On iOS, once a user has denied access to the application they must + + Note: On iOS, once a user has denied access to the application they must manually reset the permissions in the settings. -

contacts:access:granted Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.ACCESS_GRANTED

-

Dispatched when the user GRANTS permission for the application to access the contact information. This will occur after a call to request access. -

contacts:contact:selected Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.CONTACT_SELECTED

-

Dispatched when a contact has been selected from the contact picker. data[0] will contain the contact selected. -

contacts:contactpicker:cancel Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.CONTACTPICKER_CANCEL

-

Dispatched when the user cancels the contact picker selection. -

contacts:contactpicker:closed Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.CONTACTPICKER_CLOSED

-

Dispatched when the contact picker is closed. This should follow either a cancel or a select event. -

contacts:get:contacts:basic Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.GET_CONTACTS

-

Dispatched after a successful call to getContactListAsync The data field will contain the array of contacts that were retrieved. -

contacts:get:contacts:error Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.GET_CONTACTS_ERROR

-

Dispatched when an error occurs while retrieving the contact list. The message field will contain a description of the error that occurred. -

contacts:get:contacts:extended Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.GET_CONTACTS_EXTENDED

-

Dispatched after a successful call to getContactListExtendedAsync The data field will contain the array of contacts that were retrieved. -

contacts:get:contacts:json Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsJSONEvent
ContactsJSONEvent.type property = com.distriqt.extension.contacts.events.ContactsJSONEvent.GET_CONTACTS_JSON

-

Dispatched when the JSON representation of the contact list has been retrieved. -

-

- The json variable will contain the json string representation of the contact list -

+ + The json variable will contain the json string representation of the contact list
contacts:get:contacts:json:error Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsJSONEvent
ContactsJSONEvent.type property = com.distriqt.extension.contacts.events.ContactsJSONEvent.GET_CONTACTS_JSON_ERROR

-

Dispatched when an error occurs retrieving the JSON representation of the contact list. -

contacts:get:contacts:modified Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.GET_CONTACTS_MODIFIED

-

Dispatched after a successful call to getContactListModifiedSince The data field will contain the array of contacts that were retrieved. -

contacts:get:contacts:modified:json Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsJSONEvent
ContactsJSONEvent.type property = com.distriqt.extension.contacts.events.ContactsJSONEvent.GET_CONTACTS_MODIFIED_JSON

-

Dispatched when the JSON representation of the modified contact list has been retrieved. -

-

- The json variable will contain the json string representation of the contact list -

+ + The json variable will contain the json string representation of the contact list
contacts:save:images:complete Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.SAVE_IMAGES_COMPLETE

-

Dispatched when a call to saveContactImages completes successfully. -

-

- data will contain an array of objects, each containing a contactId + + data will contain an array of objects, each containing a contactId and an imagePath that can be used to access the contact image -

contacts:save:images:error Event  
Event Object Type: com.distriqt.extension.contacts.events.ContactsEvent
ContactsEvent.type property = com.distriqt.extension.contacts.events.ContactsEvent.SAVE_IMAGES_ERROR

-

Dispatched if an error occurred when saving the contact images -

-
Constant Detail
EXT_CONTEXT_IDConstant
public static const EXT_CONTEXT_ID:String = com.distriqt.Contacts

VERSIONConstant 
public static const VERSION:String = 5.1.1

Examples
- -

- The following example demonstrates the process of initialising, checking for access +

Constant Detail
EXT_CONTEXT_IDConstant
public static const EXT_CONTEXT_ID:String = com.distriqt.Contacts

VERSIONConstant 
public static const VERSION:String = 6.0.1

Examples

+ The following example demonstrates the process of initialising, checking for access and retrieving a particular contact detail

- -
+	 	 
 try
 {
     Contacts.init( APPLICATION_KEY );
@@ -795,16 +639,11 @@
     }
 }
      
- - - -
-

- The following example shows using the contact picker dialog to get the +

+ The following example shows using the contact picker dialog to get the user to select a contact.

- -
+	 	 
 try
 {
     Contacts.init( APPLICATION_KEY );
@@ -885,5 +724,4 @@
     trace( "Picker cancelled by user" );
 }
      
- -




\ No newline at end of file +




\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/class-list.html b/asdocs/contacts/com/distriqt/extension/contacts/class-list.html index a4c60e0871d..7e38192e64a 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/class-list.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/class-list.html @@ -1 +1 @@ -com.distriqt.extension.contacts - distriqt // Contacts

Package com.distriqt.extension.contacts

Classes
AuthorisationStatus
Contacts
\ No newline at end of file +com.distriqt.extension.contacts - distriqt // Contacts

Package com.distriqt.extension.contacts

Classes
AuthorisationStatus
ContactPickerOptions
Contacts
\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/events/AuthorisationEvent.html b/asdocs/contacts/com/distriqt/extension/contacts/events/AuthorisationEvent.html index 1dcb2cc121a..12efb64664d 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/events/AuthorisationEvent.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/events/AuthorisationEvent.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.events.AuthorisationEvent
Packagecom.distriqt.extension.contacts.events
Classpublic class AuthorisationEvent
InheritanceAuthorisationEvent Inheritance flash.events.Event



Public Properties
 PropertyDefined By
  status : String
AuthorisationEvent
Public Methods
 MethodDefined By
  
AuthorisationEvent(type:String, status:String, bubbles:Boolean = false, cancelable:Boolean = false)
- Constructor -
AuthorisationEvent
  
clone():Event
[override]
AuthorisationEvent
Public Constants
 ConstantDefined By
  CHANGED : String = authorisation:changed
[static] - + Constructor +
AuthorisationEvent
  
clone():Event
[override]
AuthorisationEvent
Public Constants
 ConstantDefined By
  CHANGED : String = authorisation:changed
[static] Dispatched when the user changes the authorisation status.
AuthorisationEvent
Property Detail
statusproperty
public var status:String

Constructor Detail
AuthorisationEvent()Constructor
public function AuthorisationEvent(type:String, status:String, bubbles:Boolean = false, cancelable:Boolean = false)

- Constructor -

Parameters
type:String
 
status:String
 
bubbles:Boolean (default = false)
 
cancelable:Boolean (default = false)
Method Detail
clone()method
override public function clone():Event

Returns
Event
Constant Detail
CHANGEDConstant
public static const CHANGED:String = authorisation:changed

-

+ Constructor +

Parameters
type:String
 
status:String
 
bubbles:Boolean (default = false)
 
cancelable:Boolean (default = false)
Method Detail
clone()method
override public function clone():Event

Returns
Event
Constant Detail
CHANGEDConstant
public static const CHANGED:String = authorisation:changed

Dispatched when the user changes the authorisation status. The status will indicate the new authorisation status. -

-





\ No newline at end of file +





\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsEvent.html b/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsEvent.html index 8572b4323cf..2a847fc57ef 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsEvent.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsEvent.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.events.ContactsEvent
Packagecom.distriqt.extension.contacts.events
Classpublic class ContactsEvent
InheritanceContactsEvent Inheritance flash.events.Event

The event dispatched by the Contacts Extension



Public Properties
 PropertyDefined By
  data : Array
- This field contains any data attached to the event.
ContactsEvent
  message : String
- A message associated with this event.
ContactsEvent
Public Methods
 MethodDefined By
  
ContactsEvent(type:String, data:Array = null, message:String, bubbles:Boolean = false, cancelable:Boolean = false)
Constructor
ContactsEvent
  
clone():Event
[override]
ContactsEvent
Public Constants
 ConstantDefined By
  ACCESS_DENIED : String = contacts:access:denied
[static] - Dispatched when the user DENIES permission for the application to access the contact information.
ContactsEvent
  ACCESS_GRANTED : String = contacts:access:granted
[static] - Dispatched when the user GRANTS permission for the application to - access the contact information.
ContactsEvent
  CONTACTPICKER_CANCEL : String = contacts:contactpicker:cancel
[static] - + access the contact information.
ContactsEvent
  ADD_CONTACT_COMPLETE : String = contacts:add:complete
[static] + Dispatched when a contact has been added and the contact information available.
ContactsEvent
  CONTACTPICKER_CANCEL : String = contacts:contactpicker:cancel
[static] Dispatched when the user cancels the contact picker selection.
ContactsEvent
  CONTACTPICKER_CLOSED : String = contacts:contactpicker:closed
[static] - Dispatched when the contact picker is closed.
ContactsEvent
  CONTACTPICKER_ERROR : String = contacts:contactpicker:error
[static] - Dispatched if there was an error launching the contact picker.
ContactsEvent
  CONTACT_SELECTED : String = contacts:contact:selected
[static] - Dispatched when a contact has been selected from the contact picker.
ContactsEvent
  GET_CONTACTS : String = contacts:get:contacts:basic
[static] - Dispatched after a successful call to getContactListAsync The data field will contain the array of contacts that were retrieved.
ContactsEvent
  GET_CONTACTS_ERROR : String = contacts:get:contacts:error
[static] - Dispatched when an error occurs while retrieving the contact list.
ContactsEvent
  GET_CONTACTS_EXTENDED : String = contacts:get:contacts:extended
[static] - Dispatched after a successful call to getContactListExtendedAsync The data field will contain the array of contacts that were retrieved.
ContactsEvent
  GET_CONTACTS_MODIFIED : String = contacts:get:contacts:modified
[static] - Dispatched after a successful call to getContactListModifiedSince The data field will contain the array of contacts that were retrieved.
ContactsEvent
  SAVE_IMAGES_COMPLETE : String = contacts:save:images:complete
[static] - Dispatched when a call to saveContactImages completes successfully.
ContactsEvent
  SAVE_IMAGES_ERROR : String = contacts:save:images:error
[static] - Dispatched if an error occurred when saving the contact images -
ContactsEvent
Property Detail
dataproperty
data:Array

-

This field contains any data attached to the event. -

-

- Generally this is an array containing a single contact object, + + Generally this is an Array containing a single contact object, however see the individual events for more details. -


Implementation
    public function get data():Array
    public function set data(value:Array):void
messageproperty 
message:String

-

A message associated with this event. Generally only a description of an error that occurred. -


Implementation
    public function get message():String
    public function set message(value:String):void
Constructor Detail
ContactsEvent()Constructor
public function ContactsEvent(type:String, data:Array = null, message:String, bubbles:Boolean = false, cancelable:Boolean = false)

Constructor

Parameters
type:String
 
data:Array (default = null)
 
message:String
 
bubbles:Boolean (default = false)
 
cancelable:Boolean (default = false)
Method Detail
clone()method
override public function clone():Event

Returns
Event
Constant Detail
ACCESS_DENIEDConstant
public static const ACCESS_DENIED:String = contacts:access:denied

-

Dispatched when the user DENIES permission for the application to access the contact information. This will occur after a call to request access. -

-

- Note: On iOS, once a user has denied access to the application they must + + Note: On iOS, once a user has denied access to the application they must manually reset the permissions in the settings. -

ACCESS_GRANTEDConstant 
public static const ACCESS_GRANTED:String = contacts:access:granted

-

Dispatched when the user GRANTS permission for the application to access the contact information. This will occur after a call to request access. -

+

ADD_CONTACT_COMPLETEConstant 
public static const ADD_CONTACT_COMPLETE:String = contacts:add:complete

+ Dispatched when a contact has been added and the contact information available. + The contact in the event should contain the identifier for the contact.

CONTACT_SELECTEDConstant 
public static const CONTACT_SELECTED:String = contacts:contact:selected

-

Dispatched when a contact has been selected from the contact picker. data[0] will contain the contact selected. -

CONTACTPICKER_CANCELConstant 
public static const CONTACTPICKER_CANCEL:String = contacts:contactpicker:cancel

-

Dispatched when the user cancels the contact picker selection. -

CONTACTPICKER_CLOSEDConstant 
public static const CONTACTPICKER_CLOSED:String = contacts:contactpicker:closed

-

Dispatched when the contact picker is closed. This should follow either a cancel or a select event. -

CONTACTPICKER_ERRORConstant 
public static const CONTACTPICKER_ERROR:String = contacts:contactpicker:error

-

Dispatched if there was an error launching the contact picker. -

-

For example, if there is no application on the device that can handle contact selection -

+ + For example, if there is no application on the device that can handle contact selection

GET_CONTACTSConstant 
public static const GET_CONTACTS:String = contacts:get:contacts:basic

-

Dispatched after a successful call to getContactListAsync The data field will contain the array of contacts that were retrieved. -

GET_CONTACTS_ERRORConstant 
public static const GET_CONTACTS_ERROR:String = contacts:get:contacts:error

-

Dispatched when an error occurs while retrieving the contact list. The message field will contain a description of the error that occurred. -

GET_CONTACTS_EXTENDEDConstant 
public static const GET_CONTACTS_EXTENDED:String = contacts:get:contacts:extended

-

Dispatched after a successful call to getContactListExtendedAsync The data field will contain the array of contacts that were retrieved. -

GET_CONTACTS_MODIFIEDConstant 
public static const GET_CONTACTS_MODIFIED:String = contacts:get:contacts:modified

-

Dispatched after a successful call to getContactListModifiedSince The data field will contain the array of contacts that were retrieved. -

SAVE_IMAGES_COMPLETEConstant 
public static const SAVE_IMAGES_COMPLETE:String = contacts:save:images:complete

-

Dispatched when a call to saveContactImages completes successfully. -

-

- data will contain an array of objects, each containing a contactId + + data will contain an array of objects, each containing a contactId and an imagePath that can be used to access the contact image -

SAVE_IMAGES_ERRORConstant 
public static const SAVE_IMAGES_ERROR:String = contacts:save:images:error

-

Dispatched if an error occurred when saving the contact images -

-





\ No newline at end of file +





\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsJSONEvent.html b/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsJSONEvent.html index 2e9ab4ed917..5f2870081fc 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsJSONEvent.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/events/ContactsJSONEvent.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.events.ContactsJSONEvent
Packagecom.distriqt.extension.contacts.events
Classpublic class ContactsJSONEvent
InheritanceContactsJSONEvent Inheritance flash.events.Event

-

Dispatched regarding JSON retrieval events -

-



Public Properties
 PropertyDefined By
  json : String
- +



Public Properties
 PropertyDefined By
  json : String
The JSON data associated with this event -
ContactsJSONEvent
Public Methods
 MethodDefined By
  
ContactsJSONEvent(type:String, json:String, bubbles:Boolean = false, cancelable:Boolean = false)
Constructor
ContactsJSONEvent
  
clone():Event
[override]
ContactsJSONEvent
Public Constants
 ConstantDefined By
  GET_CONTACTS_JSON : String = contacts:get:contacts:json
[static] - Dispatched when the JSON representation of the contact list has been retrieved.
ContactsJSONEvent
  GET_CONTACTS_JSON_ERROR : String = contacts:get:contacts:json:error
[static] - Dispatched when an error occurs retrieving the JSON representation of the contact list.
ContactsJSONEvent
  GET_CONTACTS_MODIFIED_JSON : String = contacts:get:contacts:modified:json
[static] - Dispatched when the JSON representation of the modified contact list has been retrieved.
ContactsJSONEvent
Property Detail
jsonproperty
public var json:String

-

The JSON data associated with this event -

Constructor Detail
ContactsJSONEvent()Constructor
public function ContactsJSONEvent(type:String, json:String, bubbles:Boolean = false, cancelable:Boolean = false)

Constructor

Parameters
type:String
 
json:String
 
bubbles:Boolean (default = false)
 
cancelable:Boolean (default = false)
Method Detail
clone()method
override public function clone():Event

Returns
Event
Constant Detail
GET_CONTACTS_JSONConstant
public static const GET_CONTACTS_JSON:String = contacts:get:contacts:json

-

Dispatched when the JSON representation of the contact list has been retrieved. -

-

- The json variable will contain the json string representation of the contact list -

+ + The json variable will contain the json string representation of the contact list

GET_CONTACTS_JSON_ERRORConstant 
public static const GET_CONTACTS_JSON_ERROR:String = contacts:get:contacts:json:error

-

Dispatched when an error occurs retrieving the JSON representation of the contact list. -

GET_CONTACTS_MODIFIED_JSONConstant 
public static const GET_CONTACTS_MODIFIED_JSON:String = contacts:get:contacts:modified:json

-

Dispatched when the JSON representation of the modified contact list has been retrieved. -

-

- The json variable will contain the json string representation of the contact list -

-





\ No newline at end of file + + The json variable will contain the json string representation of the contact list +





\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/events/class-list.html b/asdocs/contacts/com/distriqt/extension/contacts/events/class-list.html index bb57ec409fb..0a6f306cc57 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/events/class-list.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/events/class-list.html @@ -1 +1 @@ -com.distriqt.extension.contacts.events - distriqt // Contacts

Package com.distriqt.extension.contacts.events

Classes
AuthorisationEvent
ContactsEvent
ContactsJSONEvent
\ No newline at end of file +com.distriqt.extension.contacts.events - distriqt // Contacts

Package com.distriqt.extension.contacts.events

Classes
AuthorisationEvent
ContactsEvent
ContactsJSONEvent
\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/events/package-detail.html b/asdocs/contacts/com/distriqt/extension/contacts/events/package-detail.html index 01c20c56c6e..da678350e2f 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/events/package-detail.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/events/package-detail.html @@ -14,7 +14,5 @@  
 ContactsEvent The event dispatched by the Contacts Extension
 ContactsJSONEvent - Dispatched regarding JSON retrieval events - -

\ No newline at end of file +

\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/Address.html b/asdocs/contacts/com/distriqt/extension/contacts/model/Address.html index 51a322a1a42..b24be2f4a62 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/Address.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/Address.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.model.Address
Property Detail
propertiesproperty
public var properties:Vector.<ContactProperty>

Constructor Detail
Address()Constructor
public function Address()

+ -->

Property Detail
labelproperty
public var label:String

propertiesproperty 
public var properties:Vector.<ContactProperty>

Constructor Detail
Address()Constructor
public function Address()

Constructor

Method Detail
createFromObject()method
public function createFromObject(data:Object):void

Parameters
data:Object

fromObject()method 
public static function fromObject(data:Object):Address

Parameters
data:Object

Returns
Address
toString()method 
public function toString():String

Returns
String
Constant Detail
LABEL_CITYConstant
public static const LABEL_CITY:String = city

Label for the contact property representing the city of this address @@ -41,4 +41,4 @@

LABEL_STREETConstant 
public static const LABEL_STREET:String = street

Label for the contact property representing the street of this address. This should include any street number and name, eg 15 Credible St -





\ No newline at end of file +





\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/Contact.html b/asdocs/contacts/com/distriqt/extension/contacts/model/Contact.html index ccf6b9b2ada..dd5d8a24f83 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/Contact.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/Contact.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.model.Contact
Packagecom.distriqt.extension.contacts.model
Classpublic class ContactDate
InheritanceContactDate Inheritance Object



Public Properties
 PropertyDefined By
  dateString : String
- The date string in the format dd-mm-yyyy -
ContactDate
  label : String
- A label associated with this date value -
ContactDate
Public Methods
 MethodDefined By
  
ContactDate(label:String, dateString:String)
Constructor
ContactDate
Property Detail
dateStringproperty
public var dateString:String

-

The date string in the format dd-mm-yyyy -

labelproperty 
public var label:String

-

A label associated with this date value -

Constructor Detail
ContactDate()Constructor
public function ContactDate(label:String, dateString:String)

Constructor -

Parameters
label:String
 
dateString:String




\ No newline at end of file +

Parameters
label:String
 
dateString:String




\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/ContactOrganisation.html b/asdocs/contacts/com/distriqt/extension/contacts/model/ContactOrganisation.html index 1574d73b85d..1a23e7319eb 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/ContactOrganisation.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/ContactOrganisation.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.model.ContactOrganisation
Packagecom.distriqt.extension.contacts.model
Classpublic class ContactOrganisation
InheritanceContactOrganisation Inheritance Object



Public Properties
 PropertyDefined By
  name : String
ContactOrganisation
  title : String
ContactOrganisation
Public Methods
 MethodDefined By
  
ContactOrganisation
Property Detail
nameproperty
public var name:String

titleproperty 
public var title:String

Constructor Detail
ContactOrganisation()Constructor
public function ContactOrganisation()







\ No newline at end of file + -->
Property Detail
nameproperty
public var name:String

titleproperty 
public var title:String

Constructor Detail
ContactOrganisation()Constructor
public function ContactOrganisation()







\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/ContactProperty.html b/asdocs/contacts/com/distriqt/extension/contacts/model/ContactProperty.html index 6124bb02d5a..dc7949003da 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/ContactProperty.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/ContactProperty.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.model.ContactProperty
Packagecom.distriqt.extension.contacts.model
Classpublic class ContactProperty
InheritanceContactProperty Inheritance Object



Public Properties
 PropertyDefined By
  isPrimary : Boolean
ContactProperty
  label : String
ContactProperty
  value : String
ContactProperty
Public Methods
 MethodDefined By
  
ContactProperty(label:String, value:String, isPrimary:Boolean = false)
ContactProperty
Property Detail
isPrimaryproperty
public var isPrimary:Boolean

labelproperty 
public var label:String

valueproperty 
public var value:String

Constructor Detail
ContactProperty()Constructor
public function ContactProperty(label:String, value:String, isPrimary:Boolean = false)



Parameters
label:String
 
value:String
 
isPrimary:Boolean (default = false)




\ No newline at end of file + -->
Property Detail
isPrimaryproperty
public var isPrimary:Boolean

labelproperty 
public var label:String

valueproperty 
public var value:String

Constructor Detail
ContactProperty()Constructor
public function ContactProperty(label:String, value:String, isPrimary:Boolean = false)



Parameters
label:String
 
value:String
 
isPrimary:Boolean (default = false)




\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/InstantMessageService.html b/asdocs/contacts/com/distriqt/extension/contacts/model/InstantMessageService.html index 1efd6c47d38..bbb96ce374e 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/InstantMessageService.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/InstantMessageService.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.model.InstantMessageService
Packagecom.distriqt.extension.contacts.model
Classpublic class InstantMessageService
InheritanceInstantMessageService Inheritance Object

-



Public Properties
 PropertyDefined By
  service : String
+



Public Properties
 PropertyDefined By
  label : String
+
InstantMessageService
  service : String
The name of the service the username is applicable for, eg Skype @@ -19,11 +20,12 @@ Username for the service -
InstantMessageService
Public Methods
 MethodDefined By
  
InstantMessageService(service:String, username:String)
+
InstantMessageService
Public Methods
 MethodDefined By
  
InstantMessageService(service:String, username:String, label:String)
Constructor -
InstantMessageService
Property Detail
serviceproperty
public var service:String

+ -->

Property Detail
labelproperty
public var label:String

+

serviceproperty 
public var service:String

The name of the service the username is applicable for, eg Skype

@@ -31,6 +33,6 @@

Username for the service

-

Constructor Detail
InstantMessageService()Constructor
public function InstantMessageService(service:String, username:String)

+

Constructor Detail
InstantMessageService()Constructor
public function InstantMessageService(service:String, username:String, label:String)

Constructor -

Parameters
service:String
 
username:String




\ No newline at end of file +

Parameters
service:String
 
username:String
 
label:String
Method Detail
fromObject()method
public static function fromObject(data:Object):InstantMessageService

Parameters
data:Object

Returns
InstantMessageService




\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/SocialService.html b/asdocs/contacts/com/distriqt/extension/contacts/model/SocialService.html index 2fe61fe3f05..1ba43dfc1c3 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/SocialService.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/SocialService.html @@ -1,4 +1,4 @@ -com.distriqt.extension.contacts.model.SocialService
Packagecom.distriqt.extension.contacts.model
Classpublic class SocialService
InheritanceSocialService Inheritance Object

-



Public Properties
 PropertyDefined By
  service : String
+



Public Properties
 PropertyDefined By
  identifier : String
+
SocialService
  label : String
+
SocialService
  service : String
Social profile service
SocialService
  url : String
Social profile URL @@ -19,9 +21,11 @@ Social profile username
SocialService
Public Methods
 MethodDefined By
  
SocialService(service:String, username:String, url:String)
Constructor -
SocialService
Property Detail
serviceproperty
public var service:String

+ -->

Property Detail
identifierproperty
public var identifier:String

+

labelproperty 
public var label:String

+

serviceproperty 
public var service:String

Social profile service

urlproperty 
public var url:String

Social profile URL @@ -29,4 +33,4 @@ Social profile username

Constructor Detail
SocialService()Constructor
public function SocialService(service:String, username:String, url:String)

Constructor -

Parameters
service:String
 
username:String
 
url:String




\ No newline at end of file +

Parameters
service:String
 
username:String
 
url:String
Method Detail
fromObject()method
public static function fromObject(data:Object):SocialService

Parameters
data:Object

Returns
SocialService




\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/class-list.html b/asdocs/contacts/com/distriqt/extension/contacts/model/class-list.html index ad965204c14..9faacbf569c 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/class-list.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/class-list.html @@ -1 +1 @@ -com.distriqt.extension.contacts.model - distriqt // Contacts

Package com.distriqt.extension.contacts.model

Classes
Address
Contact
ContactDate
ContactOrganisation
ContactProperty
InstantMessageService
SocialService
\ No newline at end of file +com.distriqt.extension.contacts.model - distriqt // Contacts

Package com.distriqt.extension.contacts.model

Classes
Address
Contact
ContactDate
ContactOrganisation
ContactProperty
InstantMessageService
SocialService
\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/model/package-detail.html b/asdocs/contacts/com/distriqt/extension/contacts/model/package-detail.html index b82e21c4d43..616216a2315 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/model/package-detail.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/model/package-detail.html @@ -22,4 +22,4 @@ available to your application.
 ContactDate  
 ContactOrganisation 
 ContactProperty 
 InstantMessageService  
 SocialService -  

\ No newline at end of file +  

\ No newline at end of file diff --git a/asdocs/contacts/com/distriqt/extension/contacts/package-detail.html b/asdocs/contacts/com/distriqt/extension/contacts/package-detail.html index 5ba17d70786..e08e9bf30ad 100644 --- a/asdocs/contacts/com/distriqt/extension/contacts/package-detail.html +++ b/asdocs/contacts/com/distriqt/extension/contacts/package-detail.html @@ -11,6 +11,8 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("com.distriqt.extension.contacts"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,true,false);} -->



Classes
 ClassDescription
 AuthorisationStatus -  
 Contacts +  
 ContactPickerOptions + Controls available options for the contact picker +
 Contacts - This class represents the Contacts extension.

\ No newline at end of file + This class represents the Contacts extension.

\ No newline at end of file diff --git a/asdocs/contacts/index-list.html b/asdocs/contacts/index-list.html index be2485f68e3..f6ceb9d5c46 100644 --- a/asdocs/contacts/index-list.html +++ b/asdocs/contacts/index-list.html @@ -67,4 +67,4 @@

Index

Z - \ No newline at end of file + \ No newline at end of file diff --git a/asdocs/contacts/index.html b/asdocs/contacts/index.html index cc953c55479..1445d36e50b 100644 --- a/asdocs/contacts/index.html +++ b/asdocs/contacts/index.html @@ -37,4 +37,4 @@

Frame Alert

- \ No newline at end of file + \ No newline at end of file diff --git a/asdocs/contacts/package-frame.html b/asdocs/contacts/package-frame.html index 916677cff5f..04255c56c2d 100644 --- a/asdocs/contacts/package-frame.html +++ b/asdocs/contacts/package-frame.html @@ -15,4 +15,4 @@

Frame Alert

- \ No newline at end of file + \ No newline at end of file diff --git a/asdocs/contacts/package-list.html b/asdocs/contacts/package-list.html index f0f127606e8..ba736dea586 100644 --- a/asdocs/contacts/package-list.html +++ b/asdocs/contacts/package-list.html @@ -1 +1 @@ -Package List - distriqt // Contacts

Packages

com.distriqt.extension.contacts
com.distriqt.extension.contacts.events
com.distriqt.extension.contacts.model
\ No newline at end of file +Package List - distriqt // Contacts

Packages

com.distriqt.extension.contacts
com.distriqt.extension.contacts.events
com.distriqt.extension.contacts.model
\ No newline at end of file diff --git a/asdocs/contacts/package-summary.html b/asdocs/contacts/package-summary.html index 7bdc22eb469..5d0c5d74925 100644 --- a/asdocs/contacts/package-summary.html +++ b/asdocs/contacts/package-summary.html @@ -10,4 +10,4 @@ if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) {titleBar_setSubTitle("All Packages"); titleBar_setSubNav(false,false,false,false,false,false,false,false,false,false,false ,false,false,false,false,false);} --> - \ No newline at end of file + \ No newline at end of file diff --git a/asdocs/contacts/title-bar.html b/asdocs/contacts/title-bar.html index 2e7ef3a5906..7a93064dfd5 100644 --- a/asdocs/contacts/title-bar.html +++ b/asdocs/contacts/title-bar.html @@ -38,4 +38,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/js/3e86e93e.0d253a19.js b/assets/js/3e86e93e.0d253a19.js deleted file mode 100644 index 0a792c33bcb..00000000000 --- a/assets/js/3e86e93e.0d253a19.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunknativeextensions_documentation=self.webpackChunknativeextensions_documentation||[]).push([[49786],{3905:function(e,t,n){n.d(t,{Zo:function(){return s},kt:function(){return u}});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var d=r.createContext({}),c=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=c(e.components);return r.createElement(d.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},v=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,d=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),v=c(n),u=i,m=v["".concat(d,".").concat(u)]||v[u]||p[u]||a;return n?r.createElement(m,o(o({ref:t},s),{},{components:n})):r.createElement(m,o({ref:t},s))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=v;var l={};for(var d in t)hasOwnProperty.call(t,d)&&(l[d]=t[d]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var c=2;c=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var d=r.createContext({}),c=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=c(e.components);return r.createElement(d.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},v=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,d=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),v=c(n),u=i,m=v["".concat(d,".").concat(u)]||v[u]||p[u]||a;return n?r.createElement(m,o(o({ref:t},s),{},{components:n})):r.createElement(m,o({ref:t},s))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=v;var l={};for(var d in t)hasOwnProperty.call(t,d)&&(l[d]=t[d]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var c=2;c Project Settings from the secondary navigation menu.","sidebar":"unityads"},"unityads/interstitials":{"id":"unityads/interstitials","title":"Interstitials","description":"You must initialise the SDK before attempting to load and display ads.","sidebar":"unityads"},"vibration/add-the-extension":{"id":"vibration/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"vibration"},"vibration/add-the-plugin":{"id":"vibration/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"vibration"},"vibration/changelog":{"id":"vibration/changelog","title":"changelog","description":"2023.01.25 [v5.2.0]","sidebar":"vibration"},"vibration/feedback-generators":{"id":"vibration/feedback-generators","title":"Feedback Generators","description":"Haptic feedback provides a tactile response, such as a tap, that draws attention and reinforces both actions and events. While many system-provided interface elements (for example, pickers, switches, and sliders) automatically provide haptic feedback, you can use feedback generators to add your own feedback to custom views and controls.","sidebar":"vibration"},"vibration/haptic-engine":{"id":"vibration/haptic-engine","title":"Haptic Engine","description":"Compose and play haptic patterns to customize your app\u2019s feedback.","sidebar":"vibration"},"vibration/index":{"id":"vibration/index","title":"Vibration","description":"The Vibration extension provides access to a device\'s native vibration capabilities.","sidebar":"vibration"},"vibration/unity":{"id":"vibration/unity","title":"Unity","description":"Contents"},"vibration/vibrate":{"id":"vibration/vibrate","title":"Vibrate","description":"To make the device vibrate is a simple matter of calling the vibrate function.","sidebar":"vibration"},"volume/add-the-extension":{"id":"volume/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"volume"},"volume/changelog":{"id":"volume/changelog","title":"changelog","description":"2023.01.25 [v3.2.0]","sidebar":"volume"},"volume/index":{"id":"volume/index","title":"Volume","description":"The Volume extension","sidebar":"volume"},"volume/silent-switch":{"id":"volume/silent-switch","title":"Silent Switch","description":"Currently this is only available for the iOS silent switch. It does not work with the","sidebar":"volume"},"volume/streams":{"id":"volume/streams","title":"Streams","description":"Android","sidebar":"volume"},"volume/volume-control":{"id":"volume/volume-control","title":"Volume Control","description":"Retrieving and setting the volume","sidebar":"volume"},"webp/add-the-extension":{"id":"webp/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"webp"},"webp/changelog":{"id":"webp/changelog","title":"changelog","description":"2023.02.01 [v4.1.0]","sidebar":"webp"},"webp/index":{"id":"webp/index","title":"WebP","description":"The WebP extension","sidebar":"webp"},"webp/load-a-webp-file":{"id":"webp/load-a-webp-file","title":"Load a WebP File","description":"If you have access to a WebP file you can use the loadWebPBitmapData function","sidebar":"webp"},"webp/parse-webp-data":{"id":"webp/parse-webp-data","title":"Parse WebP Data","description":"If you load data from a URL or other data source you can use the parseWebP","sidebar":"webp"},"webp/webploader":{"id":"webp/webploader","title":"WebPLoader","description":"Asynchronous Loading using the WebPLoader","sidebar":"webp"},"windowsstore/add-the-extension":{"id":"windowsstore/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"windowsstore"},"windowsstore/changelog":{"id":"windowsstore/changelog","title":"changelog","description":"2023.02.01 [v1.4.0]","sidebar":"windowsstore"},"windowsstore/consumables":{"id":"windowsstore/consumables","title":"Consumables","description":"Consumable products can be consumed by the user and purchased again.","sidebar":"windowsstore"},"windowsstore/index":{"id":"windowsstore/index","title":"WindowsStore","description":"The WindowsStore extension","sidebar":"windowsstore"},"windowsstore/initialise-the-extension":{"id":"windowsstore/initialise-the-extension","title":"Initialise the Extension","description":"You should perform this once in your application by calling the setup() method. This initialises the extension and internally sets up the native extension implementation.","sidebar":"windowsstore"},"windowsstore/make-purchase":{"id":"windowsstore/make-purchase","title":"Make Purchase","description":"In order to purchase a product you will construct a PurchaseRequest object and pass it to the makePurchase function.","sidebar":"windowsstore"},"windowsstore/products":{"id":"windowsstore/products","title":"Products","description":"Query product information","sidebar":"windowsstore"},"windowsstore/purchases":{"id":"windowsstore/purchases","title":"Purchases","description":"Get Purchases","sidebar":"windowsstore"},"windowsstore/windows-desktop-app-converter":{"id":"windowsstore/windows-desktop-app-converter","title":"Windows-Desktop App Converter","description":"The Desktop App Converter can be used to turn your AIR application into an appex installer for the Windows Store. This is an important process to be able to convert your AIR app into a UWP application.","sidebar":"windowsstore"},"windowsstore/windows-developer-account":{"id":"windowsstore/windows-developer-account","title":"Windows-Developer Account","description":"The first step is to sign up for a Windows Developer account. You must have an account","sidebar":"windowsstore"},"windowsstore/windows-overview":{"id":"windowsstore/windows-overview","title":"Windows-Overview","description":"Getting your AIR application to run on the Windows Store requires you to go through","sidebar":"windowsstore"},"ziputils/add-the-extension":{"id":"ziputils/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"ziputils"},"ziputils/changelog":{"id":"ziputils/changelog","title":"changelog","description":"2023.01.27 [v3.1.0]","sidebar":"ziputils"},"ziputils/index":{"id":"ziputils/index","title":"ZipUtils","description":"The ZipUtils extension","sidebar":"ziputils"},"ziputils/unzipping-a-file":{"id":"ziputils/unzipping-a-file","title":"Unzipping a file","description":"To unzip a file call the unzip function. This will unzip the specified zip file","sidebar":"ziputils"},"ziputils/zipping":{"id":"ziputils/zipping","title":"Zipping","description":"To compress an entire directory into a zip file you use the zip() function.","sidebar":"ziputils"}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunknativeextensions_documentation=self.webpackChunknativeextensions_documentation||[]).push([[80053],{1109:function(e){e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"someSidebar":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Tutorials","href":"/docs/tutorials/","docId":"tutorials/index"},{"type":"link","label":"FAQs","href":"/docs/faqs/","docId":"faqs/index"},{"type":"category","label":"Extensions","collapsed":false,"items":[{"type":"link","label":"Adverts","href":"/docs/adverts/","docId":"adverts/index"},{"type":"link","label":"AppGroupDefaults","href":"/docs/appgroupdefaults","docId":"appgroupdefaults/index"},{"type":"link","label":"AppleSignIn","href":"/docs/applesignin","docId":"applesignin/index"},{"type":"link","label":"Application","href":"/docs/application","docId":"application/index"},{"type":"link","label":"ApplicationRater","href":"/docs/applicationrater/","docId":"applicationrater/index"},{"type":"link","label":"AudioRecorder","href":"/docs/audiorecorder","docId":"audiorecorder/index"},{"type":"link","label":"Battery","href":"/docs/battery","docId":"battery/index"},{"type":"link","label":"Beacon","href":"/docs/beacon","docId":"beacon/index"},{"type":"link","label":"Bluetooth","href":"/docs/bluetooth","docId":"bluetooth/index"},{"type":"link","label":"BluetoothLE","href":"/docs/bluetoothle","docId":"bluetoothle/index"},{"type":"link","label":"Branch","href":"/docs/branch/","docId":"branch/index"},{"type":"link","label":"Calendar","href":"/docs/calendar","docId":"calendar/index"},{"type":"link","label":"Camera","href":"/docs/camera","docId":"camera/index"},{"type":"link","label":"CameraRollExtended","href":"/docs/camerarollextended","docId":"camerarollextended/index"},{"type":"link","label":"CameraUI","href":"/docs/cameraui","docId":"cameraui/index"},{"type":"link","label":"CloudStorage","href":"/docs/cloudstorage","docId":"cloudstorage/index"},{"type":"link","label":"Compass","href":"/docs/compass","docId":"compass/index"},{"type":"link","label":"Contacts","href":"/docs/contacts","docId":"contacts/index"},{"type":"link","label":"DeviceMotion","href":"/docs/devicemotion","docId":"devicemotion/index"},{"type":"link","label":"Dialog","href":"/docs/dialog","docId":"dialog/index"},{"type":"link","label":"DynamicIcon","href":"/docs/dynamicicon","docId":"dynamicicon/index"},{"type":"link","label":"Exceptions","href":"/docs/exceptions/","docId":"exceptions/index"},{"type":"link","label":"ExpansionFiles","href":"/docs/expansionfiles","docId":"expansionfiles/index"},{"type":"link","label":"FacebookAPI","href":"/docs/facebookapi/","docId":"facebookapi/index"},{"type":"link","label":"Firebase","href":"/docs/firebase/","docId":"firebase/index"},{"type":"link","label":"Flurry","href":"/docs/flurry","docId":"flurry/index"},{"type":"link","label":"ForceTouch","href":"/docs/forcetouch","docId":"forcetouch/index"},{"type":"link","label":"GameServices","href":"/docs/gameservices","docId":"gameservices/index"},{"type":"link","label":"GoogleAnalytics","href":"/docs/googleanalytics","docId":"googleanalytics/index"},{"type":"link","label":"GoogleIdentity","href":"/docs/googleidentity/","docId":"googleidentity/index"},{"type":"link","label":"GoogleTagManager","href":"/docs/googletagmanager","docId":"googletagmanager/index"},{"type":"link","label":"Gyroscope","href":"/docs/gyroscope","docId":"gyroscope/index"},{"type":"link","label":"IDFA","href":"/docs/idfa/","docId":"idfa/index"},{"type":"link","label":"Image","href":"/docs/image","docId":"image/index"},{"type":"link","label":"InAppBilling","href":"/docs/inappbilling/","docId":"inappbilling/index"},{"type":"link","label":"IronSource","href":"/docs/ironsource/","docId":"ironsource/index"},{"type":"link","label":"Job Scheduler","href":"/docs/jobscheduler/","docId":"jobscheduler/index"},{"type":"link","label":"LocalAuth","href":"/docs/localauth/","docId":"localauth/index"},{"type":"link","label":"Location","href":"/docs/location/","docId":"location/index"},{"type":"link","label":"MediaPlayer","href":"/docs/mediaplayer","docId":"mediaplayer/index"},{"type":"link","label":"Memory","href":"/docs/memory/","docId":"memory/index"},{"type":"link","label":"NativeMaps","href":"/docs/nativemaps/","docId":"nativemaps/index"},{"type":"link","label":"NativeWebView","href":"/docs/nativewebview/","docId":"nativewebview/index"},{"type":"link","label":"NetworkInfo","href":"/docs/networkinfo/","docId":"networkinfo/index"},{"type":"link","label":"NFC","href":"/docs/nfc/","docId":"nfc/index"},{"type":"link","label":"Notifications","href":"/docs/notifications/","docId":"notifications/index"},{"type":"link","label":"OCR","href":"/docs/ocr/","docId":"ocr/index"},{"type":"link","label":"PackageManager","href":"/docs/packagemanager/","docId":"packagemanager/index"},{"type":"link","label":"PDFReader","href":"/docs/pdfreader/","docId":"pdfreader/index"},{"type":"link","label":"Permissions","href":"/docs/permissions/","docId":"permissions/index"},{"type":"link","label":"PushNotifications","href":"/docs/pushnotifications/","docId":"pushnotifications/index"},{"type":"link","label":"Restart App","href":"/docs/restartapp/","docId":"restartapp/index"},{"type":"link","label":"Root Checker","href":"/docs/rootchecker/","docId":"rootchecker/index"},{"type":"link","label":"Scanner","href":"/docs/scanner/","docId":"scanner/index"},{"type":"link","label":"Share","href":"/docs/share/","docId":"share/index"},{"type":"link","label":"SystemGestures","href":"/docs/systemgestures/","docId":"systemgestures/index"},{"type":"link","label":"UnityAds","href":"/docs/unityads/","docId":"unityads/index"},{"type":"link","label":"Vibration","href":"/docs/vibration/","docId":"vibration/index"},{"type":"link","label":"Volume","href":"/docs/volume/","docId":"volume/index"},{"type":"link","label":"WebP","href":"/docs/webp/","docId":"webp/index"},{"type":"link","label":"WindowsStore","href":"/docs/windowsstore/","docId":"windowsstore/index"},{"type":"link","label":"ZipUtils","href":"/docs/ziputils/","docId":"ziputils/index"}],"collapsible":true}],"adverts":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Adverts","href":"/docs/adverts/","docId":"adverts/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/adverts/add-the-extension","docId":"adverts/add-the-extension"},{"type":"category","label":"Platforms","items":[{"type":"link","label":"Google AdMob","href":"/docs/adverts/platform/admob","docId":"adverts/platform/admob/index"},{"type":"link","label":"Huawei Ads Kit","href":"/docs/adverts/platform/huawei","docId":"adverts/platform/huawei/index"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Initialise Platform","href":"/docs/adverts/initialise-platform","docId":"adverts/initialise-platform"},{"type":"link","label":"Advertising Identifier","href":"/docs/adverts/advertising-identifier","docId":"adverts/advertising-identifier"},{"type":"link","label":"Banner Adverts","href":"/docs/adverts/banner-adverts","docId":"adverts/banner-adverts"},{"type":"link","label":"Interstitials","href":"/docs/adverts/interstitials","docId":"adverts/interstitials"},{"type":"link","label":"Rewarded Video Ads","href":"/docs/adverts/rewarded-video-ads","docId":"adverts/rewarded-video-ads"},{"type":"link","label":"Rewarded Interstitial Ads","href":"/docs/adverts/rewarded-interstitial-ads","docId":"adverts/rewarded-interstitial-ads"},{"type":"link","label":"Server Side Verification","href":"/docs/adverts/server-side-verification","docId":"adverts/server-side-verification"},{"type":"link","label":"Native Ads","href":"/docs/adverts/native-ads","docId":"adverts/native-ads"},{"type":"link","label":"App Open Ads","href":"/docs/adverts/app-open-ads","docId":"adverts/app-open-ads"},{"type":"link","label":"Life Time Value (LTV)","href":"/docs/adverts/life-time-value","docId":"adverts/life-time-value"},{"type":"link","label":"Targeting","href":"/docs/adverts/targeting","docId":"adverts/targeting"},{"type":"link","label":"Test Ads","href":"/docs/adverts/test-ads","docId":"adverts/test-ads"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Consent","items":[{"type":"link","label":"User Messaging Platform","href":"/docs/adverts/user-messaging-platform","docId":"adverts/user-messaging-platform"},{"type":"link","label":"Consent","href":"/docs/adverts/consent","docId":"adverts/consent"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Troubleshooting","href":"/docs/adverts/troubleshooting","docId":"adverts/troubleshooting"},{"type":"link","label":"Migrating to version 14.0","href":"/docs/adverts/migrating-to-version-14.0","docId":"adverts/migrating-to-version-14.0"},{"type":"link","label":"Migrating to version 13.6","href":"/docs/adverts/migrating-to-version-13.6","docId":"adverts/migrating-to-version-13.6"},{"type":"link","label":"Migrating to version 13","href":"/docs/adverts/migrating-to-version-13","docId":"adverts/migrating-to-version-13"},{"type":"link","label":"Migrating to version 12","href":"/docs/adverts/migrating-to-version-12","docId":"adverts/migrating-to-version-12"},{"type":"link","label":"Migrating to version 10","href":"/docs/adverts/migrating-to-version-10","docId":"adverts/migrating-to-version-10"},{"type":"link","label":"Migrating from version 4","href":"/docs/adverts/migrating-from-version-4","docId":"adverts/migrating-from-version-4"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/adverts/migrating-to-androidx","docId":"adverts/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Mediation","items":[{"type":"link","label":"AdColony","href":"/docs/adverts/mediation/adcolony","docId":"adverts/mediation/adcolony/index"},{"type":"link","label":"AppLovin","href":"/docs/adverts/mediation/applovin","docId":"adverts/mediation/applovin/index"},{"type":"link","label":"Facebook Audience","href":"/docs/adverts/mediation/facebookaudience","docId":"adverts/mediation/facebookaudience/index"},{"type":"link","label":"IronSource","href":"/docs/adverts/mediation/ironsource","docId":"adverts/mediation/ironsource/index"},{"type":"link","label":"Pangle","href":"/docs/adverts/mediation/pangle","docId":"adverts/mediation/pangle/index"},{"type":"link","label":"Tapjoy","href":"/docs/adverts/mediation/tapjoy","docId":"adverts/mediation/tapjoy/index"},{"type":"link","label":"UnityAds","href":"/docs/adverts/mediation/unityads","docId":"adverts/mediation/unityads/index"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/adverts/changelog","docId":"adverts/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/adverts/"},{"type":"link","label":"asdocs - mediators","href":"https://docs.airnativeextensions.com/asdocs/adverts-mediation/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Adverts/issues/new"}],"collapsed":true,"collapsible":true}],"appconfig":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"AppConfig","href":"/docs/appconfig/","docId":"appconfig/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/appconfig/add-the-extension","docId":"appconfig/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/appconfig/setup","docId":"appconfig/setup"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Usage","href":"/docs/appconfig/usage","docId":"appconfig/usage"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/appconfig/changelog","docId":"appconfig/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/appconfig/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-AppConfig/issues/new"}],"collapsed":true,"collapsible":true}],"appgroupdefaults":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"AppGroupDefaults","href":"/docs/appgroupdefaults","docId":"appgroupdefaults/index"},{"type":"category","label":"Get Started","items":[{"type":"category","label":"Setup","collapsed":false,"items":[{"type":"link","label":"iOS","href":"/docs/appgroupdefaults/ios","docId":"appgroupdefaults/ios"},{"type":"link","label":"Android","href":"/docs/appgroupdefaults/android","docId":"appgroupdefaults/android"}],"collapsible":true},{"type":"link","label":"AIR","href":"/docs/appgroupdefaults/add-the-extension","docId":"appgroupdefaults/add-the-extension"},{"type":"link","label":"Unity","href":"/docs/appgroupdefaults/add-the-plugin","docId":"appgroupdefaults/add-the-plugin"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Usage","href":"/docs/appgroupdefaults/usage","docId":"appgroupdefaults/usage"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/appgroupdefaults/changelog","docId":"appgroupdefaults/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/appgroupdefaults/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-AppGroupDefaults/issues/new"}],"collapsed":true,"collapsible":true}],"applesignin":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"AppleSignIn","href":"/docs/applesignin","docId":"applesignin/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/applesignin/add-the-extension","docId":"applesignin/add-the-extension"},{"type":"link","label":"Setup Application","href":"/docs/applesignin/setup-application","docId":"applesignin/setup-application"},{"type":"link","label":"Setup Auth Server","href":"/docs/applesignin/setup-auth-server","docId":"applesignin/setup-auth-server"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Login with Apple Id","href":"/docs/applesignin/login-with-apple-id","docId":"applesignin/login-with-apple-id"},{"type":"link","label":"Get User Credentials","href":"/docs/applesignin/get-user-credentials","docId":"applesignin/get-user-credentials"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/applesignin/changelog","docId":"applesignin/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/applesignin/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-AppleSignIn/issues/new"}],"collapsed":true,"collapsible":true}],"application":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Application","href":"/docs/application","docId":"application/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/application/add-the-extension","docId":"application/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Device Information","items":[{"type":"link","label":"Device Information","href":"/docs/application/device-information/device","docId":"application/device-information/device"},{"type":"link","label":"Unique Device ID","href":"/docs/application/device-information/unique-device-id","docId":"application/device-information/unique-device-id"},{"type":"link","label":"Device State","href":"/docs/application/device-information/device-state","docId":"application/device-information/device-state"},{"type":"link","label":"Operating System","href":"/docs/application/device-information/operating-system","docId":"application/device-information/operating-system"},{"type":"link","label":"Orientation Events","href":"/docs/application/device-information/orientation-events","docId":"application/device-information/orientation-events"},{"type":"link","label":"Phone Number","href":"/docs/application/device-information/phone-number","docId":"application/device-information/phone-number"},{"type":"link","label":"Year Class","href":"/docs/application/device-information/year-class","docId":"application/device-information/year-class"},{"type":"link","label":"Accessibility","href":"/docs/application/device-information/accessibility","docId":"application/device-information/accessibility"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Display and Keyboard","items":[{"type":"link","label":"Display","href":"/docs/application/display/","docId":"application/display/display"},{"type":"link","label":"Cutouts","href":"/docs/application/display/cutouts","docId":"application/display/cutouts"},{"type":"link","label":"Dark Mode","href":"/docs/application/display/dark-mode","docId":"application/display/dark-mode"},{"type":"link","label":"Display Metrics","href":"/docs/application/display/display-metrics","docId":"application/display/display-metrics"},{"type":"link","label":"Soft Keyboard","href":"/docs/application/display/soft-keyboard","docId":"application/display/soft-keyboard"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Alarms and State Events","items":[{"type":"link","label":"Alarm Manager","href":"/docs/application/alarm-manager","docId":"application/alarm-manager"},{"type":"link","label":"Auto Start","href":"/docs/application/auto-start","docId":"application/auto-start"},{"type":"link","label":"Application State Events","href":"/docs/application/application-state-events","docId":"application/application-state-events"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Storing User Data","items":[{"type":"link","label":"Defaults","href":"/docs/application/defaults","docId":"application/defaults"},{"type":"link","label":"Keychain","href":"/docs/application/keychain","docId":"application/keychain"},{"type":"link","label":"Settings","href":"/docs/application/settings","docId":"application/settings"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Helpers","items":[{"type":"link","label":"General Helpers","href":"/docs/application/general-helpers","docId":"application/general-helpers"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/application/migrating-to-androidx","docId":"application/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/application/changelog","docId":"application/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/application/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Application/issues/new"}],"collapsed":true,"collapsible":true}],"applicationrater":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"ApplicationRater","href":"/docs/applicationrater/","docId":"applicationrater/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/applicationrater/add-the-extension","docId":"applicationrater/add-the-extension"},{"type":"link","label":"Unity","href":"/docs/applicationrater/add-the-plugin","docId":"applicationrater/add-the-plugin"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Application ID","href":"/docs/applicationrater/application-id","docId":"applicationrater/application-id"},{"type":"link","label":"Application Rate Dialog","href":"/docs/applicationrater/application-rate-dialog","docId":"applicationrater/application-rate-dialog"},{"type":"link","label":"Application Rate Dialog - States","href":"/docs/applicationrater/application-rate-dialog---states","docId":"applicationrater/application-rate-dialog---states"},{"type":"link","label":"Requesting Review","href":"/docs/applicationrater/requesting-review","docId":"applicationrater/requesting-review"},{"type":"link","label":"Handling Stores","href":"/docs/applicationrater/handling-stores","docId":"applicationrater/handling-stores"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Review Controller","items":[{"type":"link","label":"Review Controller","href":"/docs/applicationrater/review-controller","docId":"applicationrater/review-controller"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/applicationrater/changelog","docId":"applicationrater/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/applicationrater/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-ApplicationRater/issues/new"}],"collapsed":true,"collapsible":true}],"applovinsdk":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"App Lovin","href":"/docs/applovinsdk/","docId":"applovinsdk/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/applovinsdk/add-the-extension","docId":"applovinsdk/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Initialisation","href":"/docs/applovinsdk/initialise","docId":"applovinsdk/initialise"},{"type":"link","label":"Interstitials","href":"/docs/applovinsdk/interstitials","docId":"applovinsdk/interstitials"},{"type":"link","label":"Rewarded Video","href":"/docs/applovinsdk/rewarded-video","docId":"applovinsdk/rewarded-video"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Mediation","items":[{"type":"link","label":"AdMob","href":"/docs/applovinsdk/mediation/admob","docId":"applovinsdk/mediation/admob/admob"},{"type":"link","label":"Facebook Audience","href":"/docs/applovinsdk/mediation/facebook","docId":"applovinsdk/mediation/facebook/facebook"},{"type":"link","label":"IronSource","href":"/docs/applovinsdk/mediation/ironsource","docId":"applovinsdk/mediation/ironsource/ironsource"},{"type":"link","label":"UnityAds","href":"/docs/applovinsdk/mediation/unityads","docId":"applovinsdk/mediation/unityads/unityads"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/applovinsdk/changelog","docId":"applovinsdk/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/applovinsdk/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-AppLovinSDK/issues/new"}],"collapsed":true,"collapsible":true}],"audiorecorder":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"AudioRecorder","href":"/docs/audiorecorder","docId":"audiorecorder/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/audiorecorder/add-the-extension","docId":"audiorecorder/add-the-extension"},{"type":"link","label":"Requesting Authorisation","href":"/docs/audiorecorder/requesting-authorisation","docId":"audiorecorder/requesting-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Recording Audio","href":"/docs/audiorecorder/recording-audio","docId":"audiorecorder/recording-audio"},{"type":"link","label":"Playback","href":"/docs/audiorecorder/playback","docId":"audiorecorder/playback"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v3.1","href":"/docs/audiorecorder/migrating-to-v3.1","docId":"audiorecorder/migrating-to-v3.1"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/audiorecorder/changelog","docId":"audiorecorder/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/audiorecorder/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-AudioRecorder/issues/new"}],"collapsed":true,"collapsible":true}],"battery":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Battery","href":"/docs/battery","docId":"battery/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/battery/add-the-extension","docId":"battery/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Battery Info","href":"/docs/battery/battery-info","docId":"battery/battery-info"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/battery/changelog","docId":"battery/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/battery/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Battery/issues/new"}],"collapsed":true,"collapsible":true}],"beacon":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Beacon","href":"/docs/beacon","docId":"beacon/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/beacon/add-the-extension","docId":"beacon/add-the-extension"},{"type":"link","label":"Requesting Authorisation","href":"/docs/beacon/requesting-authorisation","docId":"beacon/requesting-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Monitoring a Region","href":"/docs/beacon/monitoring-a-region","docId":"beacon/monitoring-a-region"},{"type":"link","label":"Broadcasting","href":"/docs/beacon/broadcasting","docId":"beacon/broadcasting"},{"type":"link","label":"Events","href":"/docs/beacon/events","docId":"beacon/events"},{"type":"link","label":"Tools and Resources","href":"/docs/beacon/tools-and-resources","docId":"beacon/tools-and-resources"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v5.1","href":"/docs/beacon/migrating-to-v5.1","docId":"beacon/migrating-to-v5.1"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/beacon/changelog","docId":"beacon/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/beacon/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Beacon/issues/new"}],"collapsed":true,"collapsible":true}],"bluetooth":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Bluetooth","href":"/docs/bluetooth","docId":"bluetooth/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/bluetooth/add-the-extension","docId":"bluetooth/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Connecting","href":"/docs/bluetooth/connecting","docId":"bluetooth/connecting"}],"collapsed":true,"collapsible":true},{"type":"category","label":"FAQ","items":[{"type":"link","label":"iOS","href":"/docs/bluetooth/ios","docId":"bluetooth/ios"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/bluetooth/changelog","docId":"bluetooth/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/bluetooth/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Bluetooth/issues/new"}],"collapsed":true,"collapsible":true}],"bluetoothle":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"BluetoothLE","href":"/docs/bluetoothle","docId":"bluetoothle/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/bluetoothle/add-the-extension","docId":"bluetoothle/add-the-extension"},{"type":"link","label":"Request Authorisation","href":"/docs/bluetoothle/request-authorisation","docId":"bluetoothle/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Adapter State","href":"/docs/bluetoothle/adapter-state","docId":"bluetoothle/adapter-state"},{"type":"link","label":"Centrals and Peripherals","href":"/docs/bluetoothle/centrals-and-peripherals","docId":"bluetoothle/centrals-and-peripherals"},{"type":"link","label":"Central Manager","href":"/docs/bluetoothle/central-manager","docId":"bluetoothle/central-manager"},{"type":"link","label":"Peripheral Manager","href":"/docs/bluetoothle/peripheral-manager","docId":"bluetoothle/peripheral-manager"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/bluetoothle/migrating-to-androidx","docId":"bluetoothle/migrating-to-androidx"},{"type":"link","label":"Migrating to v4.2","href":"/docs/bluetoothle/migrating-to-v4.2","docId":"bluetoothle/migrating-to-v4.2"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/bluetoothle/changelog","docId":"bluetoothle/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/bluetoothle/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-BluetoothLE/issues/new"}],"collapsed":true,"collapsible":true}],"branch":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Branch","href":"/docs/branch/","docId":"branch/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/branch/add-the-extension","docId":"branch/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Initialisation","href":"/docs/branch/initialisation","docId":"branch/initialisation"},{"type":"link","label":"Deep Links","href":"/docs/branch/deep-links","docId":"branch/deep-links"},{"type":"link","label":"User Identity","href":"/docs/branch/user-identity","docId":"branch/user-identity"},{"type":"link","label":"Link Parameters","href":"/docs/branch/link-parameters","docId":"branch/link-parameters"},{"type":"link","label":"Referral Credits","href":"/docs/branch/referral-credits","docId":"branch/referral-credits"},{"type":"link","label":"Event Tracking","href":"/docs/branch/event-tracking","docId":"branch/event-tracking"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Branch Universal Objects","items":[{"type":"link","label":"Branch Universal Objects","href":"/docs/branch/branch-universal-objects","docId":"branch/branch-universal-objects"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/branch/changelog","docId":"branch/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/branch/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-BranchIO/issues/new"}],"collapsed":true,"collapsible":true}],"calendar":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Calendar","href":"/docs/calendar","docId":"calendar/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/calendar/add-the-extension","docId":"calendar/add-the-extension"},{"type":"link","label":"Request Authorisation","href":"/docs/calendar/request-authorisation","docId":"calendar/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Get Events","href":"/docs/calendar/get-events","docId":"calendar/get-events"},{"type":"link","label":"Add Events","href":"/docs/calendar/add-events","docId":"calendar/add-events"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v5.1","href":"/docs/calendar/migrating-to-v5.1","docId":"calendar/migrating-to-v5.1"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/calendar/migrating-to-androidx","docId":"calendar/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/calendar/changelog","docId":"calendar/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/calendar/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Calendar/issues/new"}],"collapsed":true,"collapsible":true}],"camera":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Camera","href":"/docs/camera","docId":"camera/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/camera/add-the-extension","docId":"camera/add-the-extension"},{"type":"link","label":"Requesting Authorisation","href":"/docs/camera/requesting-authorisation","docId":"camera/requesting-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Selecting a Device","href":"/docs/camera/selecting-a-device","docId":"camera/selecting-a-device"},{"type":"link","label":"Connecting","href":"/docs/camera/connecting","docId":"camera/connecting"},{"type":"link","label":"Preview Frames","href":"/docs/camera/preview-frames","docId":"camera/preview-frames"},{"type":"link","label":"Capturing Images","href":"/docs/camera/capturing-images","docId":"camera/capturing-images"},{"type":"link","label":"Camera Modes","href":"/docs/camera/camera-modes","docId":"camera/camera-modes"},{"type":"link","label":"Parameters-Flash","href":"/docs/camera/parameters-flash","docId":"camera/parameters-flash"},{"type":"link","label":"Parameters-Focus","href":"/docs/camera/parameters-focus","docId":"camera/parameters-focus"},{"type":"link","label":"Parameters-Exposure","href":"/docs/camera/parameters-exposure","docId":"camera/parameters-exposure"},{"type":"link","label":"Parameters-White Balance","href":"/docs/camera/parameters-white-balance","docId":"camera/parameters-white-balance"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v6.1","href":"/docs/camera/migrating-to-v6.1","docId":"camera/migrating-to-v6.1"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/camera/migrating-to-androidx","docId":"camera/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/camera/changelog","docId":"camera/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/camera/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Camera/issues/new"}],"collapsed":true,"collapsible":true}],"camerarollextended":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"CameraRollExtended","href":"/docs/camerarollextended","docId":"camerarollextended/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/camerarollextended/add-the-extension","docId":"camerarollextended/add-the-extension"},{"type":"link","label":"Request Authorisation","href":"/docs/camerarollextended/request-authorisation","docId":"camerarollextended/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Browse for an Asset","href":"/docs/camerarollextended/browse-for-an-asset","docId":"camerarollextended/browse-for-an-asset"},{"type":"link","label":"Loading an Asset","href":"/docs/camerarollextended/loading-an-asset","docId":"camerarollextended/loading-an-asset"},{"type":"link","label":"File Access","href":"/docs/camerarollextended/file-access","docId":"camerarollextended/file-access"},{"type":"link","label":"Adding Images and Video","href":"/docs/camerarollextended/adding-files","docId":"camerarollextended/adding-files"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v6.4","href":"/docs/camerarollextended/migrating-to-v6.4","docId":"camerarollextended/migrating-to-v6.4"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/camerarollextended/migrating-to-androidx","docId":"camerarollextended/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/camerarollextended/changelog","docId":"camerarollextended/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/camerarollextended/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-CameraRollExtended/issues/new"}],"collapsed":true,"collapsible":true}],"cameraui":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"CameraUI","href":"/docs/cameraui","docId":"cameraui/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/cameraui/add-the-extension","docId":"cameraui/add-the-extension"},{"type":"link","label":"Requesting Authorisation","href":"/docs/cameraui/requesting-authorisation","docId":"cameraui/requesting-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Capture Media","href":"/docs/cameraui/capture-media","docId":"cameraui/capture-media"},{"type":"link","label":"Camera UI Options","href":"/docs/cameraui/camera-ui-options","docId":"cameraui/camera-ui-options"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v3.5","href":"/docs/cameraui/migrating-to-v3.5","docId":"cameraui/migrating-to-v3.5"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/cameraui/migrating-to-androidx","docId":"cameraui/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","collapsed":false,"items":[{"type":"link","label":"changelog","href":"/docs/cameraui/changelog","docId":"cameraui/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/cameraui/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-CameraUI/issues/new"}],"collapsible":true}],"chartboost":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Chartboost","href":"/docs/chartboost/","docId":"chartboost/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Account Setup","href":"/docs/chartboost/setup","docId":"chartboost/setup"},{"type":"link","label":"Add the Extension","href":"/docs/chartboost/add-the-extension","docId":"chartboost/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Initialise","href":"/docs/chartboost/initialise","docId":"chartboost/initialise"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","collapsed":false,"items":[{"type":"link","label":"changelog","href":"/docs/chartboost/changelog","docId":"chartboost/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/chartboost/"},{"type":"link","label":"Contact Support","href":"http://github.com/airnativeextensions/ANE-Chartboost/issues/new"}],"collapsible":true}],"cloudstorage":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"CloudStorage","href":"/docs/cloudstorage","docId":"cloudstorage/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/cloudstorage/add-the-extension","docId":"cloudstorage/add-the-extension"},{"type":"link","label":"Unity","href":"/docs/cloudstorage/add-the-plugin","docId":"cloudstorage/add-the-plugin"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Key-Value Storage","href":"/docs/cloudstorage/key-value-storage","docId":"cloudstorage/key-value-storage"},{"type":"link","label":"Document Store","href":"/docs/cloudstorage/document-store","docId":"cloudstorage/document-store"},{"type":"link","label":"Android Testing","href":"/docs/cloudstorage/android-testing","docId":"cloudstorage/android-testing"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/cloudstorage/changelog","docId":"cloudstorage/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/cloudstorage/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-CloudStorage/issues/new"}],"collapsed":true,"collapsible":true}],"compass":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Compass","href":"/docs/compass","docId":"compass/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/compass/add-the-extension","docId":"compass/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Heading","href":"/docs/compass/heading","docId":"compass/heading"},{"type":"link","label":"Request Authorisation","href":"/docs/compass/request-authorisation","docId":"compass/request-authorisation"},{"type":"link","label":"Magnetic Field Sensor","href":"/docs/compass/magnetic-field-sensor","docId":"compass/magnetic-field-sensor"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/compass/changelog","docId":"compass/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/compass/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Compass/issues/new"}],"collapsed":true,"collapsible":true}],"contacts":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Contacts","href":"/docs/contacts","docId":"contacts/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/contacts/add-the-extension","docId":"contacts/add-the-extension"},{"type":"link","label":"Request Authorisation","href":"/docs/contacts/request-authorisation","docId":"contacts/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Access the Contact List","items":[{"type":"link","label":"Retrieving the Contact List","href":"/docs/contacts/retrieving-the-contact-list","docId":"contacts/retrieving-the-contact-list"},{"type":"link","label":"Contact Images","href":"/docs/contacts/contact-images","docId":"contacts/contact-images"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Contact Selection","items":[{"type":"link","label":"Contact Picker UI","href":"/docs/contacts/contact-picker-ui","docId":"contacts/contact-picker-ui"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v5.1","href":"/docs/contacts/migrating-to-v5.1","docId":"contacts/migrating-to-v5.1"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/contacts/migrating-to-androidx","docId":"contacts/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/contacts/changelog","docId":"contacts/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/contacts/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Contacts/issues/new"}],"collapsed":true,"collapsible":true}],"debug":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Debug","href":"/docs/debug","docId":"debug/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/debug/add-the-extension","docId":"debug/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Usage","href":"/docs/debug/usage","docId":"debug/usage"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/debug/changelog","docId":"debug/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/debug/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Debug/issues/new"}],"collapsed":true,"collapsible":true}],"devicemotion":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"DeviceMotion","href":"/docs/devicemotion","docId":"devicemotion/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/devicemotion/add-the-extension","docId":"devicemotion/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Register for Updates","href":"/docs/devicemotion/register-for-updates","docId":"devicemotion/register-for-updates"},{"type":"link","label":"Algorithms and Format","href":"/docs/devicemotion/algorithms-and-format","docId":"devicemotion/algorithms-and-format"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/devicemotion/changelog","docId":"devicemotion/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/devicemotion/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-DeviceMotion/issues/new"}],"collapsed":true,"collapsible":true}],"dialog":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Dialog","href":"/docs/dialog","docId":"dialog/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/dialog/add-the-extension","docId":"dialog/add-the-extension"},{"type":"link","label":"Dialog Views and Builders","href":"/docs/dialog/dialog-views-and-builders","docId":"dialog/dialog-views-and-builders"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Toast","href":"/docs/dialog/toast","docId":"dialog/toast"},{"type":"link","label":"Alerts","href":"/docs/dialog/alerts","docId":"dialog/alerts"},{"type":"link","label":"Text View Alert","href":"/docs/dialog/text-view-alert","docId":"dialog/text-view-alert"},{"type":"link","label":"Action Sheet","href":"/docs/dialog/action-sheet","docId":"dialog/action-sheet"},{"type":"link","label":"Progress Dialog","href":"/docs/dialog/progress-dialog","docId":"dialog/progress-dialog"},{"type":"link","label":"Activity Dialog","href":"/docs/dialog/activity-dialog","docId":"dialog/activity-dialog"},{"type":"link","label":"Custom Picker","href":"/docs/dialog/custom-picker","docId":"dialog/custom-picker"},{"type":"link","label":"Date Time Dialog","href":"/docs/dialog/date-time-dialog","docId":"dialog/date-time-dialog"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Additional Features","items":[{"type":"link","label":"AIR fallback","href":"/docs/dialog/air-fallback","docId":"dialog/air-fallback"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/dialog/migrating-to-androidx","docId":"dialog/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/dialog/changelog","docId":"dialog/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/dialog/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Dialog/issues/new"}],"collapsed":true,"collapsible":true}],"dynamicicon":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"DynamicIcon","href":"/docs/dynamicicon","docId":"dynamicicon/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/dynamicicon/add-the-extension","docId":"dynamicicon/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Adding Icons","href":"/docs/dynamicicon/adding-icons","docId":"dynamicicon/adding-icons"},{"type":"link","label":"Change Icon","href":"/docs/dynamicicon/change-icon","docId":"dynamicicon/change-icon"},{"type":"link","label":"Packaging","href":"/docs/dynamicicon/packaging","docId":"dynamicicon/packaging"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/dynamicicon/changelog","docId":"dynamicicon/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/dynamicicon/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-DyanmicIcon/issues/new"}],"collapsed":true,"collapsible":true}],"exceptions":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Exceptions","href":"/docs/exceptions/","docId":"exceptions/index"},{"type":"link","label":"Add the Extension","href":"/docs/exceptions/add-the-extension","docId":"exceptions/add-the-extension"},{"type":"link","label":"Usage","href":"/docs/exceptions/usage","docId":"exceptions/usage"},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/exceptions/changelog","docId":"exceptions/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/exceptions/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Exceptions/issues/new"}],"collapsed":true,"collapsible":true}],"expansionfiles":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"ExpansionFiles","href":"/docs/expansionfiles","docId":"expansionfiles/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/expansionfiles/add-the-extension","docId":"expansionfiles/add-the-extension"},{"type":"link","label":"Request Authorisation","href":"/docs/expansionfiles/request-authorisation","docId":"expansionfiles/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Setup your Expansion Files","items":[{"type":"link","label":"Setup Licensing","href":"/docs/expansionfiles/setup-licensing","docId":"expansionfiles/setup-licensing"},{"type":"link","label":"Uploading Expansion Files","href":"/docs/expansionfiles/uploading-expansion-files","docId":"expansionfiles/uploading-expansion-files"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Downloading Expansion Files","href":"/docs/expansionfiles/downloading-expansion-files","docId":"expansionfiles/downloading-expansion-files"}],"collapsed":true,"collapsible":true},{"type":"category","label":"JOBB Files","items":[{"type":"link","label":"JOBB Files","href":"/docs/expansionfiles/jobb-files","docId":"expansionfiles/jobb-files"},{"type":"link","label":"Mounting an OBB File","href":"/docs/expansionfiles/mounting-an-obb-file","docId":"expansionfiles/mounting-an-obb-file"},{"type":"link","label":"Reading an OBB File","href":"/docs/expansionfiles/reading-an-obb-file","docId":"expansionfiles/reading-an-obb-file"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v4.2","href":"/docs/expansionfiles/migrating-to-v4.2","docId":"expansionfiles/migrating-to-v4.2"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/expansionfiles/migrating-to-androidx","docId":"expansionfiles/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/expansionfiles/changelog","docId":"expansionfiles/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/expansionfiles/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-ExpansionFiles/issues/new"}],"collapsed":true,"collapsible":true}],"facebookapi":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"FacebookAPI","href":"/docs/facebookapi/","docId":"facebookapi/index"},{"type":"link","label":"Get Started","href":"/docs/facebookapi/get-started","docId":"facebookapi/get-started"},{"type":"category","label":"Core","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/core/overview","docId":"facebookapi/core/overview"},{"type":"link","label":"Add the Extension","href":"/docs/facebookapi/core/add-the-extension","docId":"facebookapi/core/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/facebookapi/core/initialise-the-extension","docId":"facebookapi/core/initialise-the-extension"},{"type":"category","label":"App Events","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/core/app-events/overview","docId":"facebookapi/core/app-events/overview"},{"type":"link","label":"User Properties","href":"/docs/facebookapi/core/app-events/user-properties","docId":"facebookapi/core/app-events/user-properties"},{"type":"link","label":"Automatic Logging","href":"/docs/facebookapi/core/app-events/automatic-logging","docId":"facebookapi/core/app-events/automatic-logging"},{"type":"link","label":"Logging","href":"/docs/facebookapi/core/app-events/logging","docId":"facebookapi/core/app-events/logging"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Graph API","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/core/graph-api/overview","docId":"facebookapi/core/graph-api/overview"},{"type":"link","label":"Basics","href":"/docs/facebookapi/core/graph-api/basics","docId":"facebookapi/core/graph-api/basics"},{"type":"link","label":"Batch","href":"/docs/facebookapi/core/graph-api/batch","docId":"facebookapi/core/graph-api/batch"},{"type":"link","label":"Examples","href":"/docs/facebookapi/core/graph-api/examples","docId":"facebookapi/core/graph-api/examples"}],"collapsed":true,"collapsible":true},{"type":"category","label":"App Links","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/core/app-links/overview","docId":"facebookapi/core/app-links/overview"},{"type":"link","label":"Support Incoming Links","href":"/docs/facebookapi/core/app-links/support","docId":"facebookapi/core/app-links/support"},{"type":"link","label":"Handling Incoming Links","href":"/docs/facebookapi/core/app-links/handling-incoming-links","docId":"facebookapi/core/app-links/handling-incoming-links"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Login","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/login/overview","docId":"facebookapi/login/overview"},{"type":"link","label":"Add the Extension","href":"/docs/facebookapi/login/add-the-extension","docId":"facebookapi/login/add-the-extension"},{"type":"link","label":"Facebook Login","href":"/docs/facebookapi/login/facebook-login","docId":"facebookapi/login/facebook-login"},{"type":"link","label":"Access Token","href":"/docs/facebookapi/login/access-token","docId":"facebookapi/login/access-token"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Share","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/share/overview","docId":"facebookapi/share/overview"},{"type":"link","label":"Add the Extension","href":"/docs/facebookapi/share/add-the-extension","docId":"facebookapi/share/add-the-extension"},{"type":"link","label":"Content","href":"/docs/facebookapi/share/content","docId":"facebookapi/share/content"},{"type":"link","label":"Share Dialog","href":"/docs/facebookapi/share/share-dialog","docId":"facebookapi/share/share-dialog"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Gaming Services","items":[{"type":"link","label":"Overview","href":"/docs/facebookapi/gamingservices/overview","docId":"facebookapi/gamingservices/overview"},{"type":"link","label":"Add the Extension","href":"/docs/facebookapi/gamingservices/add-the-extension","docId":"facebookapi/gamingservices/add-the-extension"},{"type":"link","label":"Game Request Dialog","href":"/docs/facebookapi/gamingservices/game-request-dialog","docId":"facebookapi/gamingservices/game-request-dialog"},{"type":"link","label":"Friend Finder Dialog","href":"/docs/facebookapi/gamingservices/friend-finder-dialog","docId":"facebookapi/gamingservices/friend-finder-dialog"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"iOS Signing","href":"/docs/facebookapi/signing","docId":"facebookapi/signing"},{"type":"link","label":"Migrating to Version 10","href":"/docs/facebookapi/migrating-to-version-10","docId":"facebookapi/migrating-to-version-10"},{"type":"link","label":"Migrating to Version 9","href":"/docs/facebookapi/migrating-to-version-9","docId":"facebookapi/migrating-to-version-9"},{"type":"link","label":"Migrating to Version 8","href":"/docs/facebookapi/migrating-to-version-8","docId":"facebookapi/migrating-to-version-8"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/facebookapi/migrating-to-androidx","docId":"facebookapi/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/facebookapi/changelog","docId":"facebookapi/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/facebookapi/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-FacebookAPI/issues/new"}],"collapsed":true,"collapsible":true}],"facebookapi-legacy":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"FacebookAPI","href":"/docs/facebookapi-legacy/","docId":"facebookapi-legacy/index"},{"type":"category","label":"Setup Facebook","items":[{"type":"link","label":"Facebook Application","href":"/docs/facebookapi-legacy/facebook-application","docId":"facebookapi-legacy/facebook-application"},{"type":"link","label":"Facebook Android App","href":"/docs/facebookapi-legacy/facebook-android-app","docId":"facebookapi-legacy/facebook-android-app"},{"type":"link","label":"Facebook iOS App","href":"/docs/facebookapi-legacy/facebook-ios-app","docId":"facebookapi-legacy/facebook-ios-app"},{"type":"link","label":"Advanced Facebook Settings","href":"/docs/facebookapi-legacy/advanced-facebook-settings","docId":"facebookapi-legacy/advanced-facebook-settings"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Setup the Extension","items":[{"type":"link","label":"Add the Extension","href":"/docs/facebookapi-legacy/add-the-extension","docId":"facebookapi-legacy/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/facebookapi-legacy/initialise-the-extension","docId":"facebookapi-legacy/initialise-the-extension"},{"type":"link","label":"Initialise Facebook App","href":"/docs/facebookapi-legacy/initialise-facebook-app","docId":"facebookapi-legacy/initialise-facebook-app"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Facebook Login","items":[{"type":"link","label":"Login - Overview","href":"/docs/facebookapi-legacy/login---overview","docId":"facebookapi-legacy/login---overview"},{"type":"link","label":"Login - Facebook Login","href":"/docs/facebookapi-legacy/login---facebook-login","docId":"facebookapi-legacy/login---facebook-login"},{"type":"link","label":"Login - Access Token","href":"/docs/facebookapi-legacy/login---access-token","docId":"facebookapi-legacy/login---access-token"}],"collapsed":true,"collapsible":true},{"type":"category","label":"App Events","items":[{"type":"link","label":"App Events - Overview","href":"/docs/facebookapi-legacy/app-events---overview","docId":"facebookapi-legacy/app-events---overview"},{"type":"link","label":"App Events - User Properties","href":"/docs/facebookapi-legacy/app-events---user-properties","docId":"facebookapi-legacy/app-events---user-properties"},{"type":"link","label":"App Events - Automatic Logging","href":"/docs/facebookapi-legacy/app-events---automatic-logging","docId":"facebookapi-legacy/app-events---automatic-logging"},{"type":"link","label":"App Events - Logging","href":"/docs/facebookapi-legacy/app-events---logging","docId":"facebookapi-legacy/app-events---logging"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Sharing","items":[{"type":"link","label":"Sharing - Overview","href":"/docs/facebookapi-legacy/sharing---overview","docId":"facebookapi-legacy/sharing---overview"},{"type":"link","label":"Sharing - Content","href":"/docs/facebookapi-legacy/sharing---content","docId":"facebookapi-legacy/sharing---content"},{"type":"link","label":"Sharing - Share Dialog","href":"/docs/facebookapi-legacy/sharing---share-dialog","docId":"facebookapi-legacy/sharing---share-dialog"},{"type":"link","label":"Sharing - Message Dialog","href":"/docs/facebookapi-legacy/sharing---message-dialog","docId":"facebookapi-legacy/sharing---message-dialog"},{"type":"link","label":"Sharing - Open Graph Stories","href":"/docs/facebookapi-legacy/sharing---open-graph-stories","docId":"facebookapi-legacy/sharing---open-graph-stories"},{"type":"link","label":"Sharing - Share API","href":"/docs/facebookapi-legacy/sharing---share-api","docId":"facebookapi-legacy/sharing---share-api"}],"collapsed":true,"collapsible":true},{"type":"category","label":"App Links","items":[{"type":"link","label":"App Links - Overview","href":"/docs/facebookapi-legacy/app-links---overview","docId":"facebookapi-legacy/app-links---overview"},{"type":"link","label":"App Links - Incoming Links","href":"/docs/facebookapi-legacy/app-links---incoming-links","docId":"facebookapi-legacy/app-links---incoming-links"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Games","items":[{"type":"link","label":"Games - Overview","href":"/docs/facebookapi-legacy/games---overview","docId":"facebookapi-legacy/games---overview"},{"type":"link","label":"Games - Game Request Dialog","href":"/docs/facebookapi-legacy/games---game-request-dialog","docId":"facebookapi-legacy/games---game-request-dialog"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Graph API","items":[{"type":"link","label":"Graph API - Overview","href":"/docs/facebookapi-legacy/graph-api---overview","docId":"facebookapi-legacy/graph-api---overview"},{"type":"link","label":"Graph API - Basics","href":"/docs/facebookapi-legacy/graph-api---basics","docId":"facebookapi-legacy/graph-api---basics"},{"type":"link","label":"Graph API - Batch","href":"/docs/facebookapi-legacy/graph-api---batch","docId":"facebookapi-legacy/graph-api---batch"},{"type":"link","label":"Graph API - Examples","href":"/docs/facebookapi-legacy/graph-api---examples","docId":"facebookapi-legacy/graph-api---examples"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/facebookapi-legacy/migrating-to-androidx","docId":"facebookapi-legacy/migrating-to-androidx"},{"type":"link","label":"Account Kit - Deprecation","href":"/docs/facebookapi-legacy/account-kit---deprecation","docId":"facebookapi-legacy/account-kit---deprecation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/facebookapi-legacy/changelog","docId":"facebookapi-legacy/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/facebookapi-legacy/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-FacebookAPI/issues/new"}],"collapsed":true,"collapsible":true}],"firebase":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Firebase","href":"/docs/firebase/","docId":"firebase/index"},{"type":"category","label":"Setup Firebase for your application","items":[{"type":"link","label":"Create a Firebase Project","href":"/docs/firebase/setup/create-a-firebase-project","docId":"firebase/setup/create-a-firebase-project"},{"type":"link","label":"Configuration Files","href":"/docs/firebase/setup/configuration-files","docId":"firebase/setup/configuration-files"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Core / Analytics","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/core/introduction","docId":"firebase/core/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/core/add-the-extensions","docId":"firebase/core/add-the-extensions"},{"type":"link","label":"Initialise","href":"/docs/firebase/core/initialise","docId":"firebase/core/initialise"},{"type":"link","label":"Analytics","href":"/docs/firebase/core/analytics","docId":"firebase/core/analytics"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Develop","collapsed":false,"items":[{"type":"category","label":"Authentication","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/auth/introduction","docId":"firebase/auth/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/auth/add-the-extensions","docId":"firebase/auth/add-the-extensions"},{"type":"link","label":"Initialise","href":"/docs/firebase/auth/initialise","docId":"firebase/auth/initialise"},{"type":"link","label":"Manage Users","href":"/docs/firebase/auth/manage-users","docId":"firebase/auth/manage-users"},{"type":"category","label":"Providers","items":[{"type":"link","label":"Email","href":"/docs/firebase/auth/provider/email","docId":"firebase/auth/provider/email"},{"type":"link","label":"Email Link","href":"/docs/firebase/auth/provider/email-link","docId":"firebase/auth/provider/email-link"},{"type":"link","label":"Anonymous","href":"/docs/firebase/auth/provider/anonymous","docId":"firebase/auth/provider/anonymous"},{"type":"link","label":"Google Identity","href":"/docs/firebase/auth/provider/google-identity","docId":"firebase/auth/provider/google-identity"},{"type":"link","label":"GitHub","href":"/docs/firebase/auth/provider/github","docId":"firebase/auth/provider/github"},{"type":"link","label":"Microsoft","href":"/docs/firebase/auth/provider/microsoft","docId":"firebase/auth/provider/microsoft"},{"type":"link","label":"Apple","href":"/docs/firebase/auth/provider/apple","docId":"firebase/auth/provider/apple"},{"type":"link","label":"Facebook","href":"/docs/firebase/auth/provider/facebook","docId":"firebase/auth/provider/facebook"},{"type":"link","label":"Twitter","href":"/docs/firebase/auth/provider/twitter","docId":"firebase/auth/provider/twitter"},{"type":"link","label":"Phone","href":"/docs/firebase/auth/provider/phone","docId":"firebase/auth/provider/phone"},{"type":"link","label":"Custom Auth","href":"/docs/firebase/auth/provider/custom-auth","docId":"firebase/auth/provider/custom-auth"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Link Multiple Providers","href":"/docs/firebase/auth/link-multiple-providers","docId":"firebase/auth/link-multiple-providers"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Realtime Database","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/database/introduction","docId":"firebase/database/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/database/add-the-extensions","docId":"firebase/database/add-the-extensions"},{"type":"link","label":"Initialise","href":"/docs/firebase/database/initialise","docId":"firebase/database/initialise"},{"type":"link","label":"Configure Database Rules","href":"/docs/firebase/database/configure-database-rules","docId":"firebase/database/configure-database-rules"},{"type":"category","label":"Read and Write Data","items":[{"type":"link","label":"Write Data","href":"/docs/firebase/database/write-data","docId":"firebase/database/write-data"},{"type":"link","label":"Read Data and Change Events","href":"/docs/firebase/database/read-data-and-change-events","docId":"firebase/database/read-data-and-change-events"},{"type":"link","label":"Delete Data","href":"/docs/firebase/database/delete-data","docId":"firebase/database/delete-data"},{"type":"link","label":"Transactions","href":"/docs/firebase/database/transactions","docId":"firebase/database/transactions"},{"type":"link","label":"Lists","href":"/docs/firebase/database/lists","docId":"firebase/database/lists"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Offline","items":[{"type":"link","label":"Offline","href":"/docs/firebase/database/offline","docId":"firebase/database/offline"},{"type":"link","label":"Disconnect","href":"/docs/firebase/database/disconnect","docId":"firebase/database/disconnect"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Cloud Firestore","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/firestore/introduction","docId":"firebase/firestore/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/firestore/add-the-extension","docId":"firebase/firestore/add-the-extension"},{"type":"category","label":"Add and manage data","items":[{"type":"link","label":"Data model (external)","href":"https://firebase.google.com/docs/firestore/data-model"},{"type":"link","label":"Structure data (external)","href":"https://firebase.google.com/docs/firestore/manage-data/structure-data"},{"type":"link","label":"Data types (external)","href":"https://firebase.google.com/docs/firestore/manage-data/data-types"},{"type":"link","label":"Add Data","href":"/docs/firebase/firestore/add-data","docId":"firebase/firestore/add-data"},{"type":"link","label":"Transactions and batched writes","href":"/docs/firebase/firestore/transactions-and-batched-writes","docId":"firebase/firestore/transactions-and-batched-writes"},{"type":"link","label":"Delete data","href":"/docs/firebase/firestore/delete-data","docId":"firebase/firestore/delete-data"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Query data","items":[{"type":"link","label":"Get data","href":"/docs/firebase/firestore/get-data","docId":"firebase/firestore/get-data"},{"type":"link","label":"Get realtime updates","href":"/docs/firebase/firestore/get-realtime-updates","docId":"firebase/firestore/get-realtime-updates"},{"type":"link","label":"Perform simple and compound queries","href":"/docs/firebase/firestore/perform-simple-and-compound-queries","docId":"firebase/firestore/perform-simple-and-compound-queries"},{"type":"link","label":"Order and limit data","href":"/docs/firebase/firestore/order-and-limit-data","docId":"firebase/firestore/order-and-limit-data"},{"type":"link","label":"Paginate data with query cursors","href":"/docs/firebase/firestore/paginate-data-with-query-cursors","docId":"firebase/firestore/paginate-data-with-query-cursors"},{"type":"link","label":"Index types (external)","href":"https://firebase.google.com/docs/firestore/query-data/index-overview"},{"type":"link","label":"Manage indexes (external)","href":"https://firebase.google.com/docs/firestore/query-data/indexing"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Security","items":[{"type":"link","label":"Get started (external)","href":"https://firebase.google.com/docs/firestore/security/get-started"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Enable offline data","href":"/docs/firebase/firestore/enable-offline-data","docId":"firebase/firestore/enable-offline-data"},{"type":"category","label":"Further reading","items":[{"type":"link","label":"Solutions (external)","href":"https://firebase.google.com/docs/firestore/solutions/"},{"type":"link","label":"Cloud Functions (external)","href":"https://firebase.google.com/docs/firestore/extend-with-functions"},{"type":"link","label":"User REST API (external)","href":"https://firebase.google.com/docs/firestore/use-rest-api"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Storage","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/storage/introduction","docId":"firebase/storage/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/storage/add-the-extensions","docId":"firebase/storage/add-the-extensions"},{"type":"link","label":"References","href":"/docs/firebase/storage/references","docId":"firebase/storage/references"},{"type":"link","label":"Upload Files","href":"/docs/firebase/storage/upload-files","docId":"firebase/storage/upload-files"},{"type":"link","label":"Download Files","href":"/docs/firebase/storage/download-files","docId":"firebase/storage/download-files"},{"type":"link","label":"File Metadata","href":"/docs/firebase/storage/file-metadata","docId":"firebase/storage/file-metadata"},{"type":"link","label":"Delete Files","href":"/docs/firebase/storage/delete-files","docId":"firebase/storage/delete-files"},{"type":"link","label":"List Files","href":"/docs/firebase/storage/list-files","docId":"firebase/storage/list-files"}],"collapsed":true,"collapsible":true}],"collapsible":true},{"type":"category","label":"Quality","collapsed":false,"items":[{"type":"category","label":"Crashlytics","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/crashlytics/introduction","docId":"firebase/crashlytics/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/crashlytics/add-the-extension","docId":"firebase/crashlytics/add-the-extension"},{"type":"link","label":"Usage","href":"/docs/firebase/crashlytics/usage","docId":"firebase/crashlytics/usage"},{"type":"link","label":"Testing","href":"/docs/firebase/crashlytics/testing","docId":"firebase/crashlytics/testing"},{"type":"link","label":"Uploading dSYMs","href":"/docs/firebase/crashlytics/uploading-dsyms","docId":"firebase/crashlytics/uploading-dsyms"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Performance Monitoring","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/performance/introduction","docId":"firebase/performance/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/performance/add-the-extension","docId":"firebase/performance/add-the-extension"},{"type":"link","label":"Traces","href":"/docs/firebase/performance/traces","docId":"firebase/performance/traces"},{"type":"link","label":"Disable Monitoring","href":"/docs/firebase/performance/disable-monitoring","docId":"firebase/performance/disable-monitoring"}],"collapsed":true,"collapsible":true}],"collapsible":true},{"type":"category","label":"Grow","collapsed":false,"items":[{"type":"category","label":"Cloud Messaging","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/fcm/introduction","docId":"firebase/fcm/introduction"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Remote Config","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/remoteconfig/introduction","docId":"firebase/remoteconfig/introduction"},{"type":"link","label":"Set Initial Values","href":"/docs/firebase/remoteconfig/set-initial-values","docId":"firebase/remoteconfig/set-initial-values"},{"type":"link","label":"Add the extension","href":"/docs/firebase/remoteconfig/add-the-extensions","docId":"firebase/remoteconfig/add-the-extensions"},{"type":"link","label":"Initialise","href":"/docs/firebase/remoteconfig/initialise","docId":"firebase/remoteconfig/initialise"},{"type":"link","label":"Usage","href":"/docs/firebase/remoteconfig/usage","docId":"firebase/remoteconfig/usage"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Dynamic Links","items":[{"type":"link","label":"Introduction","href":"/docs/firebase/dynamiclinks/introduction","docId":"firebase/dynamiclinks/introduction"},{"type":"link","label":"Add the extension","href":"/docs/firebase/dynamiclinks/add-the-extension","docId":"firebase/dynamiclinks/add-the-extension"},{"type":"link","label":"Initialise","href":"/docs/firebase/dynamiclinks/initialise","docId":"firebase/dynamiclinks/initialise"},{"type":"link","label":"Create Dynamic Links","href":"/docs/firebase/dynamiclinks/create-dynamic-links","docId":"firebase/dynamiclinks/create-dynamic-links"},{"type":"link","label":"Receive Dynamic Links","href":"/docs/firebase/dynamiclinks/receive-dynamic-links","docId":"firebase/dynamiclinks/receive-dynamic-links"},{"type":"link","label":"Testing","href":"/docs/firebase/dynamiclinks/testing","docId":"firebase/dynamiclinks/testing"}],"collapsed":true,"collapsible":true}],"collapsible":true},{"type":"category","label":"Migration Guides","items":[{"type":"link","label":"Migrating to v6","href":"/docs/firebase/migrating-to-v6","docId":"firebase/migrating-to-v6"},{"type":"link","label":"Migrating to v4","href":"/docs/firebase/migrating-to-v4","docId":"firebase/migrating-to-v4"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"Firebase Console","href":"https://console.firebase.google.com/"},{"type":"link","label":"changelog","href":"/docs/firebase/changelog","docId":"firebase/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/firebase/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Firebase/issues/new"}],"collapsed":true,"collapsible":true}],"flurry":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Flurry","href":"/docs/flurry","docId":"flurry/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/flurry/add-the-extension","docId":"flurry/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/flurry/initialise-the-extension","docId":"flurry/initialise-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Analytics","items":[{"type":"link","label":"Sessions","href":"/docs/flurry/analytics-sessions","docId":"flurry/analytics-sessions"},{"type":"link","label":"Events","href":"/docs/flurry/analytics-events","docId":"flurry/analytics-events"},{"type":"link","label":"Standard Events","href":"/docs/flurry/analytics-standard-events","docId":"flurry/analytics-standard-events"},{"type":"link","label":"User Properties","href":"/docs/flurry/user-properties","docId":"flurry/user-properties"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Migration Guides","items":[{"type":"link","label":"Migrating to v6.0","href":"/docs/flurry/migrating-to-v6","docId":"flurry/migrating-to-v6"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/flurry/changelog","docId":"flurry/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/flurry/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Flurry/issues/new"}],"collapsed":true,"collapsible":true}],"forcetouch":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"ForceTouch","href":"/docs/forcetouch","docId":"forcetouch/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/forcetouch/add-the-extension","docId":"forcetouch/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Force Touch Events","href":"/docs/forcetouch/force-touch-events","docId":"forcetouch/force-touch-events"},{"type":"link","label":"App Shortcuts","href":"/docs/forcetouch/app-shortcuts","docId":"forcetouch/app-shortcuts"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/forcetouch/changelog","docId":"forcetouch/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/forcetouch/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-ForceTouch/issues/new"}],"collapsed":true,"collapsible":true}],"gameservices":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"GameServices","href":"/docs/gameservices","docId":"gameservices/index"},{"type":"category","label":"Services","collapsed":false,"items":[{"type":"category","label":"Apple Game Center","items":[{"type":"link","label":"Setup","href":"/docs/gameservices/service/gamecenter/setup","docId":"gameservices/service/gamecenter/setup"},{"type":"link","label":"Add the Extension","href":"/docs/gameservices/service/gamecenter/add-the-extension","docId":"gameservices/service/gamecenter/add-the-extension"},{"type":"link","label":"Troubleshooting","href":"/docs/gameservices/service/gamecenter/troubleshooting","docId":"gameservices/service/gamecenter/troubleshooting"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Google Play Games","items":[{"type":"link","label":"Setup","href":"/docs/gameservices/service/playgames/setup","docId":"gameservices/service/playgames/setup"},{"type":"link","label":"Add the Extension","href":"/docs/gameservices/service/playgames/add-the-extension","docId":"gameservices/service/playgames/add-the-extension"},{"type":"link","label":"Troubleshooting","href":"/docs/gameservices/service/playgames/troubleshooting","docId":"gameservices/service/playgames/troubleshooting"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Huawei Game Services","items":[{"type":"link","label":"Setup","href":"/docs/gameservices/service/huawei/setup","docId":"gameservices/service/huawei/setup"},{"type":"link","label":"Add the Extension","href":"/docs/gameservices/service/huawei/add-the-extension","docId":"gameservices/service/huawei/add-the-extension"},{"type":"link","label":"Troubleshooting","href":"/docs/gameservices/service/huawei/troubleshooting","docId":"gameservices/service/huawei/troubleshooting"}],"collapsed":true,"collapsible":true}],"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Initialise the Service","href":"/docs/gameservices/initialise-the-service","docId":"gameservices/initialise-the-service"},{"type":"link","label":"Sign In","href":"/docs/gameservices/sign-in","docId":"gameservices/sign-in"},{"type":"link","label":"Leaderboards","href":"/docs/gameservices/leaderboards","docId":"gameservices/leaderboards"},{"type":"link","label":"Achievements","href":"/docs/gameservices/achievements","docId":"gameservices/achievements"},{"type":"category","label":"Saved Games","items":[{"type":"link","label":"Usage","href":"/docs/gameservices/saved-games","docId":"gameservices/saved-games"},{"type":"link","label":"Conflicts","href":"/docs/gameservices/saved-games---conflicts","docId":"gameservices/saved-games---conflicts"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Turn Based Multiplayer","items":[{"type":"link","label":"Key Concepts","href":"/docs/gameservices/turn-based-multiplayer---key-concepts","docId":"gameservices/turn-based-multiplayer---key-concepts"},{"type":"link","label":"Implementation Overview","href":"/docs/gameservices/turn-based-multiplayer---implementation-overview","docId":"gameservices/turn-based-multiplayer---implementation-overview"},{"type":"link","label":"Implementation","href":"/docs/gameservices/turn-based-multiplayer---implementation","docId":"gameservices/turn-based-multiplayer---implementation"},{"type":"link","label":"Invitations","href":"/docs/gameservices/turn-based-multiplayer---invitations","docId":"gameservices/turn-based-multiplayer---invitations"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Quests and Events","href":"/docs/gameservices/quests-and-events","docId":"gameservices/quests-and-events"},{"type":"link","label":"Screen Recording","href":"/docs/gameservices/screen-recording","docId":"gameservices/screen-recording"},{"type":"category","label":"User Interface","items":[{"type":"link","label":"UI Elements","href":"/docs/gameservices/user-interface","docId":"gameservices/user-interface"},{"type":"link","label":"Access Point","href":"/docs/gameservices/access-point","docId":"gameservices/access-point"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Troubleshooting","href":"/docs/gameservices/troubleshooting","docId":"gameservices/troubleshooting"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/gameservices/migrating-to-androidx","docId":"gameservices/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/gameservices/changelog","docId":"gameservices/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/gameservices/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-GameServices/issues/new"}],"collapsed":true,"collapsible":true}],"googleanalytics":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"GoogleAnalytics","href":"/docs/googleanalytics","docId":"googleanalytics/index"},{"type":"category","label":"Setup the Extension","items":[{"type":"link","label":"Add the Extension","href":"/docs/googleanalytics/add-the-extension","docId":"googleanalytics/add-the-extension"},{"type":"link","label":"Tracking IDs","href":"/docs/googleanalytics/tracking-ids","docId":"googleanalytics/tracking-ids"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Create a Tracker","href":"/docs/googleanalytics/create-a-tracker","docId":"googleanalytics/create-a-tracker"},{"type":"link","label":"Sending Hits and Events","href":"/docs/googleanalytics/sending-hits-and-events","docId":"googleanalytics/sending-hits-and-events"},{"type":"link","label":"Ecommerce","href":"/docs/googleanalytics/ecommerce","docId":"googleanalytics/ecommerce"},{"type":"link","label":"Enhanced Ecommerce","href":"/docs/googleanalytics/enhanced-ecommerce","docId":"googleanalytics/enhanced-ecommerce"},{"type":"link","label":"Notes","href":"/docs/googleanalytics/notes","docId":"googleanalytics/notes"},{"type":"link","label":"Install Referrer","href":"/docs/googleanalytics/install-referrer","docId":"googleanalytics/install-referrer"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/googleanalytics/migrating-to-androidx","docId":"googleanalytics/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/googleanalytics/changelog","docId":"googleanalytics/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/googleanalytics/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-GoogleAnalytics/issues/new"}],"collapsed":true,"collapsible":true}],"googleidentity":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"GoogleIdentity","href":"/docs/googleidentity/","docId":"googleidentity/index"},{"type":"category","label":"Setup your Google Project","items":[{"type":"link","label":"Google Developers Console project","href":"/docs/googleidentity/google-developers-console-project","docId":"googleidentity/google-developers-console-project"},{"type":"link","label":"Android Certificate","href":"/docs/googleidentity/android-certificate","docId":"googleidentity/android-certificate"},{"type":"link","label":"Google Identity Options","href":"/docs/googleidentity/google-identity-options","docId":"googleidentity/google-identity-options"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Setup the Extension","items":[{"type":"link","label":"Add the Extension","href":"/docs/googleidentity/add-the-extension","docId":"googleidentity/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Setup","href":"/docs/googleidentity/setup","docId":"googleidentity/setup"},{"type":"link","label":"Signing In","href":"/docs/googleidentity/signing-in","docId":"googleidentity/signing-in"},{"type":"link","label":"Disconnect","href":"/docs/googleidentity/disconnect","docId":"googleidentity/disconnect"},{"type":"link","label":"User Information","href":"/docs/googleidentity/user-information","docId":"googleidentity/user-information"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Additional","items":[{"type":"link","label":"Authenticate with a backend server","href":"/docs/googleidentity/authenticate-with-a-backend-server","docId":"googleidentity/authenticate-with-a-backend-server"},{"type":"link","label":"Enabling Server-Side Access","href":"/docs/googleidentity/enabling-server-side-access","docId":"googleidentity/enabling-server-side-access"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Troubleshooting","href":"/docs/googleidentity/troubleshooting","docId":"googleidentity/troubleshooting"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/googleidentity/migrating-to-androidx","docId":"googleidentity/migrating-to-androidx"},{"type":"link","label":"Migrating from version 1","href":"/docs/googleidentity/migrating-from-version-1","docId":"googleidentity/migrating-from-version-1"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/googleidentity/changelog","docId":"googleidentity/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/googleidentity/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-GoogleIdentity/issues/new"}],"collapsed":true,"collapsible":true}],"googletagmanager":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"GoogleTagManager","href":"/docs/googletagmanager","docId":"googletagmanager/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Google Tag Manager Setup","href":"/docs/googletagmanager/google-tag-manager-setup","docId":"googletagmanager/google-tag-manager-setup"},{"type":"link","label":"Add the Extension","href":"/docs/googletagmanager/add-the-extension","docId":"googletagmanager/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Log events and variables","href":"/docs/googletagmanager/log-events","docId":"googletagmanager/log-events"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/googletagmanager/changelog","docId":"googletagmanager/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/googletagmanager/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-GoogleTagManager/issues/new"},{"type":"category","label":"Legacy","items":[{"type":"link","label":"Containers","href":"/docs/googletagmanager/legacy/containers","docId":"googletagmanager/legacy/containers"},{"type":"link","label":"DataLayer","href":"/docs/googletagmanager/legacy/datalayer","docId":"googletagmanager/legacy/datalayer"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true}],"gyroscope":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Gyroscope","href":"/docs/gyroscope","docId":"gyroscope/index"},{"type":"link","label":"Add the Extension","href":"/docs/gyroscope/add-the-extension","docId":"gyroscope/add-the-extension"},{"type":"link","label":"Sensor Updates","href":"/docs/gyroscope/sensor-updates","docId":"gyroscope/sensor-updates"},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/gyroscope/changelog","docId":"gyroscope/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/gyroscope/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Gyroscope/issues/new"}],"collapsed":true,"collapsible":true}],"health":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Health","href":"/docs/health/","docId":"health/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/health/add-the-extension","docId":"health/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/health/setup","docId":"health/setup"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Availablility & Updates","href":"/docs/health/check-for-updates","docId":"health/check-for-updates"},{"type":"link","label":"Authorisation","href":"/docs/health/authorisation","docId":"health/authorisation"},{"type":"link","label":"Querying Data","href":"/docs/health/queries","docId":"health/queries"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/health/changelog","docId":"health/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/health/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Health/issues/new"}],"collapsed":true,"collapsible":true}],"idfa":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"IDFA","href":"/docs/idfa/","docId":"idfa/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/idfa/add-the-extension","docId":"idfa/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Get Advertising Identifier","href":"/docs/idfa/get-advertising-identifier","docId":"idfa/get-advertising-identifier"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating","href":"/docs/idfa/migrating","docId":"idfa/migrating"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/idfa/migrating-to-androidx","docId":"idfa/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/idfa/changelog","docId":"idfa/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/idfa/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-IDFA/issues/new"}],"collapsed":true,"collapsible":true}],"image":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Image","href":"/docs/image","docId":"image/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/image/add-the-extension","docId":"image/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Saving BitmapData to File","href":"/docs/image/saving-bitmapdata-to-file","docId":"image/saving-bitmapdata-to-file"},{"type":"link","label":"Loading BitmapData from File","href":"/docs/image/loading-bitmapdata-from-file","docId":"image/loading-bitmapdata-from-file"},{"type":"link","label":"Encoding BitmapData to ByteArray","href":"/docs/image/encoding-bitmapdata-to-bytearray","docId":"image/encoding-bitmapdata-to-bytearray"},{"type":"link","label":"Decoding ByteArray to BitmapData","href":"/docs/image/decoding-bytearray-to-bitmapdata","docId":"image/decoding-bytearray-to-bitmapdata"},{"type":"link","label":"Transformations","href":"/docs/image/transformations","docId":"image/transformations"},{"type":"link","label":"Capturing a Screenshot","href":"/docs/image/capturing-a-screenshot","docId":"image/capturing-a-screenshot"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v5.2","href":"/docs/image/migrating-to-v5.2","docId":"image/migrating-to-v5.2"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/image/migrating-to-androidx","docId":"image/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/image/changelog","docId":"image/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/image/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Image/issues/new"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Deprecated","items":[{"type":"link","label":"Saving BitmapData to the Camera Roll","href":"/docs/image/saving-bitmapdata-to-the-camera-roll","docId":"image/saving-bitmapdata-to-the-camera-roll"},{"type":"link","label":"Authorisation","href":"/docs/image/request-authorisation","docId":"image/request-authorisation"}],"collapsed":true,"collapsible":true}],"inappbilling":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"InAppBilling","href":"/docs/inappbilling/","docId":"inappbilling/index"},{"type":"link","label":"Overview","href":"/docs/inappbilling/overview","docId":"inappbilling/overview"},{"type":"link","label":"Add the Extension","href":"/docs/inappbilling/add-the-extension","docId":"inappbilling/add-the-extension"},{"type":"category","label":"Billing Services","items":[{"type":"category","label":"Apple In-App Purchases","items":[{"type":"link","label":"Add the Extension","href":"/docs/inappbilling/add-the-extension","docId":"inappbilling/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/inappbilling/apple/apple-in-app-purchases","docId":"inappbilling/apple/apple-in-app-purchases"},{"type":"link","label":"Server Side Verification","href":"/docs/inappbilling/apple/server-side-verification","docId":"inappbilling/apple/server-side-verification"},{"type":"link","label":"Testing","href":"/docs/inappbilling/apple/testing","docId":"inappbilling/apple/testing"},{"type":"link","label":"Troubleshooting","href":"/docs/inappbilling/apple/troubleshooting","docId":"inappbilling/apple/troubleshooting"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Google Play Billing","items":[{"type":"link","label":"Add the Extension","href":"/docs/inappbilling/add-the-extension","docId":"inappbilling/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/inappbilling/google/google-play-inapp-billing","docId":"inappbilling/google/google-play-inapp-billing"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Amazon In-App Purchasing","items":[{"type":"link","label":"Add the Extension","href":"/docs/inappbilling/amazon/add-the-extension","docId":"inappbilling/amazon/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/inappbilling/amazon/amazon-in-app-purchasing","docId":"inappbilling/amazon/amazon-in-app-purchasing"},{"type":"link","label":"Testing","href":"/docs/inappbilling/amazon/testing","docId":"inappbilling/amazon/testing"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Huawei AppGallery","items":[{"type":"link","label":"Add the Extension","href":"/docs/inappbilling/huawei/add-the-extension","docId":"inappbilling/huawei/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/inappbilling/huawei/huawei-appgallery","docId":"inappbilling/huawei/huawei-appgallery"},{"type":"link","label":"Testing","href":"/docs/inappbilling/huawei/testing","docId":"inappbilling/huawei/testing"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Samsung In-App Purchases","items":[{"type":"link","label":"Add the Extension","href":"/docs/inappbilling/samsung/add-the-extension","docId":"inappbilling/samsung/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/inappbilling/samsung/samsung-in-app-purchases","docId":"inappbilling/samsung/samsung-in-app-purchases"},{"type":"link","label":"Testing","href":"/docs/inappbilling/samsung/testing","docId":"inappbilling/samsung/testing"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","collapsed":false,"items":[{"type":"link","label":"Setup Billing Service","href":"/docs/inappbilling/billing-service","docId":"inappbilling/billing-service"},{"type":"link","label":"Products","href":"/docs/inappbilling/products","docId":"inappbilling/products"},{"type":"link","label":"Make a Purchase","href":"/docs/inappbilling/make-a-purchase","docId":"inappbilling/make-a-purchase"},{"type":"link","label":"Pending Purchases","href":"/docs/inappbilling/pending-purchases","docId":"inappbilling/pending-purchases"},{"type":"link","label":"Restore Purchases","href":"/docs/inappbilling/restore-purchases","docId":"inappbilling/restore-purchases"},{"type":"link","label":"Get Purchases","href":"/docs/inappbilling/get-purchases","docId":"inappbilling/get-purchases"},{"type":"link","label":"Consuming Purchases","href":"/docs/inappbilling/consuming-purchases","docId":"inappbilling/consuming-purchases"},{"type":"link","label":"Change a Purchase","href":"/docs/inappbilling/change-a-purchase","docId":"inappbilling/change-a-purchase"},{"type":"link","label":"Promotions","href":"/docs/inappbilling/promotions","docId":"inappbilling/promotions"},{"type":"link","label":"Application Receipt","href":"/docs/inappbilling/application-receipt","docId":"inappbilling/application-receipt"},{"type":"category","label":"Subscription Offers","items":[{"type":"link","label":"Subscription Offers","href":"/docs/inappbilling/subscription-offers","docId":"inappbilling/subscription-offers"},{"type":"link","label":"Introductory Prices","href":"/docs/inappbilling/introductory-prices","docId":"inappbilling/introductory-prices"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Testing","href":"/docs/inappbilling/testing","docId":"inappbilling/testing"}],"collapsible":true},{"type":"category","label":"In-App Updates","items":[{"type":"link","label":"In App Updates","href":"/docs/inappbilling/in-app-updates","docId":"inappbilling/in-app-updates"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migration v14","href":"/docs/inappbilling/migration-v14","docId":"inappbilling/migration-v14"},{"type":"link","label":"Migration (v12 and below)","href":"/docs/inappbilling/migration","docId":"inappbilling/migration"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Advanced","items":[{"type":"link","label":"User Data","href":"/docs/inappbilling/user-data","docId":"inappbilling/user-data"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/inappbilling/changelog","docId":"inappbilling/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/inappbilling/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-InAppBilling/issues/new"}],"collapsed":true,"collapsible":true}],"ironsource":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"IronSource","href":"/docs/ironsource/","docId":"ironsource/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/ironsource/add-the-extension","docId":"ironsource/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Initialisation","href":"/docs/ironsource/initialisation","docId":"ironsource/initialisation"},{"type":"link","label":"Interstitials","href":"/docs/ironsource/interstitials","docId":"ironsource/interstitials"},{"type":"link","label":"Rewarded Video","href":"/docs/ironsource/rewarded-video","docId":"ironsource/rewarded-video"},{"type":"link","label":"Banner Ads","href":"/docs/ironsource/banner-ads","docId":"ironsource/banner-ads"},{"type":"link","label":"Offerwall","href":"/docs/ironsource/offerwall","docId":"ironsource/offerwall"},{"type":"link","label":"Errors","href":"/docs/ironsource/errors","docId":"ironsource/errors"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Mediation","items":[{"type":"link","label":"AdColony","href":"/docs/ironsource/mediation/adcolony","docId":"ironsource/mediation/adcolony/adcolony"},{"type":"link","label":"AdMob","href":"/docs/ironsource/mediation/admob","docId":"ironsource/mediation/admob/admob"},{"type":"link","label":"Amazon","href":"/docs/ironsource/mediation/amazon","docId":"ironsource/mediation/amazon/amazon"},{"type":"link","label":"AppLovin","href":"/docs/ironsource/mediation/applovin","docId":"ironsource/mediation/applovin/applovin"},{"type":"link","label":"Chartboost","href":"/docs/ironsource/mediation/chartboost","docId":"ironsource/mediation/chartboost/chartboost"},{"type":"link","label":"Facebook Audience","href":"/docs/ironsource/mediation/facebook-audience","docId":"ironsource/mediation/facebook-audience/facebook-audience"},{"type":"link","label":"Tapjoy","href":"/docs/ironsource/mediation/tapjoy","docId":"ironsource/mediation/tapjoy/tapjoy"},{"type":"link","label":"UnityAds","href":"/docs/ironsource/mediation/unityads","docId":"ironsource/mediation/unityads/unityads"},{"type":"link","label":"Vungle","href":"/docs/ironsource/mediation/vungle","docId":"ironsource/mediation/vungle/vungle"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/ironsource/migrating-to-androidx","docId":"ironsource/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/ironsource/changelog","docId":"ironsource/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/ironsource/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-IronSource/issues/new"}],"collapsed":true,"collapsible":true}],"jobscheduler":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Job Scheduler","href":"/docs/jobscheduler/","docId":"jobscheduler/index"},{"type":"link","label":"Add the Extension","href":"/docs/jobscheduler/add-the-extension","docId":"jobscheduler/add-the-extension"},{"type":"link","label":"Application Termination","href":"/docs/jobscheduler/application-termination","docId":"jobscheduler/application-termination"},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/jobscheduler/changelog","docId":"jobscheduler/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/jobscheduler/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-JobScheduler/issues/new"}],"collapsed":true,"collapsible":true}],"localauth":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"LocalAuth","href":"/docs/localauth/","docId":"localauth/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/localauth/add-the-extension","docId":"localauth/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Biometric Authentication","href":"/docs/localauth/biometric-authentication","docId":"localauth/biometric-authentication"},{"type":"link","label":"Authorisation","href":"/docs/localauth/request-authorisation","docId":"localauth/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/localauth/changelog","docId":"localauth/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/localauth/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-LocalAuth/issues/new"}],"collapsed":true,"collapsible":true}],"location":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Location","href":"/docs/location/","docId":"location/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/location/add-the-extension","docId":"location/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/location/initialise-the-extension","docId":"location/initialise-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Request Authorisation","href":"/docs/location/request-authorisation","docId":"location/request-authorisation"},{"type":"link","label":"Device Location Settings","href":"/docs/location/device-location-settings","docId":"location/device-location-settings"},{"type":"link","label":"Location Monitoring","href":"/docs/location/location-monitoring","docId":"location/location-monitoring"},{"type":"link","label":"Geofences","href":"/docs/location/geofences","docId":"location/geofences"},{"type":"link","label":"Geocoding","href":"/docs/location/geocoding","docId":"location/geocoding"},{"type":"link","label":"Location Utils - Distance","href":"/docs/location/location-utils---distance","docId":"location/location-utils---distance"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Testing","items":[{"type":"link","label":"iOS Location Simulation","href":"/docs/location/ios-location-simulation","docId":"location/ios-location-simulation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Help","items":[{"type":"link","label":"Migrating to v4.5","href":"/docs/location/migrating-to-v4.5","docId":"location/migrating-to-v4.5"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/location/migrating-to-androidx","docId":"location/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/location/changelog","docId":"location/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/location/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Location/issues/new"}],"collapsed":true,"collapsible":true}],"mediaplayer":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"MediaPlayer","href":"/docs/mediaplayer","docId":"mediaplayer/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/mediaplayer/add-the-extension","docId":"mediaplayer/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Media Player View","items":[{"type":"link","label":"Media Player - Create","href":"/docs/mediaplayer/media-player---create","docId":"mediaplayer/media-player---create"},{"type":"link","label":"Media Player - Loading Media","href":"/docs/mediaplayer/media-player---loading-media","docId":"mediaplayer/media-player---loading-media"},{"type":"link","label":"Media Player - Control Playback","href":"/docs/mediaplayer/media-player---control-playback","docId":"mediaplayer/media-player---control-playback"},{"type":"link","label":"Media Player - Playback Events","href":"/docs/mediaplayer/media-player---playback-events","docId":"mediaplayer/media-player---playback-events"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Audio Player","items":[{"type":"link","label":"Audio Player","href":"/docs/mediaplayer/audio-player","docId":"mediaplayer/audio-player"},{"type":"link","label":"Audio Player - Background Audio","href":"/docs/mediaplayer/audio-player---background-audio","docId":"mediaplayer/audio-player---background-audio"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Sound Pool","items":[{"type":"link","label":"Sound Pool","href":"/docs/mediaplayer/sound-pool","docId":"mediaplayer/sound-pool"}],"collapsed":true,"collapsible":true},{"type":"category","label":"System Integration","items":[{"type":"link","label":"Remote Command Center","href":"/docs/mediaplayer/remote-command-center","docId":"mediaplayer/remote-command-center"},{"type":"link","label":"System Control","href":"/docs/mediaplayer/system-control","docId":"mediaplayer/system-control"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/mediaplayer/migrating-to-androidx","docId":"mediaplayer/migrating-to-androidx"},{"type":"link","label":"Migrating from version 1","href":"/docs/mediaplayer/migrating-from-version-1","docId":"mediaplayer/migrating-from-version-1"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/mediaplayer/changelog","docId":"mediaplayer/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/mediaplayer/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-MediaPlayer/issues/new"}],"collapsed":true,"collapsible":true}],"memory":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Memory","href":"/docs/memory/","docId":"memory/index"},{"type":"link","label":"Add the Extension","href":"/docs/memory/add-the-extension","docId":"memory/add-the-extension"},{"type":"link","label":"Usage","href":"/docs/memory/usage","docId":"memory/usage"},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/memory/changelog","docId":"memory/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/memory/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Memory/issues/new"}],"collapsed":true,"collapsible":true}],"message":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Message","href":"/docs/message/","docId":"message/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/message/add-the-extension","docId":"message/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Email","href":"/docs/message/email","docId":"message/email"},{"type":"link","label":"SMS","href":"/docs/message/sms","docId":"message/sms"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/message/migrating-to-androidx","docId":"message/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/message/changelog","docId":"message/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/message/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Message/issues/new"}],"collapsed":true,"collapsible":true}],"nativemaps":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"NativeMaps","href":"/docs/nativemaps/","docId":"nativemaps/index"},{"type":"category","label":"Setup your mapping provider","items":[{"type":"link","label":"Apple Maps","href":"/docs/nativemaps/apple-maps","docId":"nativemaps/apple-maps"},{"type":"link","label":"Google Maps","href":"/docs/nativemaps/google-maps","docId":"nativemaps/google-maps"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Setup the Extension","items":[{"type":"link","label":"Add the Extension","href":"/docs/nativemaps/add-the-extension","docId":"nativemaps/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/nativemaps/initialise-the-extension","docId":"nativemaps/initialise-the-extension"},{"type":"link","label":"Request Authorisation","href":"/docs/nativemaps/request-authorisation","docId":"nativemaps/request-authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Create a Map","href":"/docs/nativemaps/create-a-map","docId":"nativemaps/create-a-map"},{"type":"link","label":"Controlling the View","href":"/docs/nativemaps/controlling-the-view","docId":"nativemaps/controlling-the-view"},{"type":"link","label":"Touch Events","href":"/docs/nativemaps/touch-events","docId":"nativemaps/touch-events"},{"type":"category","label":"Overlays","items":[{"type":"link","label":"Overlays","href":"/docs/nativemaps/overlays","docId":"nativemaps/overlays"},{"type":"link","label":"Overlays - Markers","href":"/docs/nativemaps/overlays---markers","docId":"nativemaps/overlays---markers"},{"type":"link","label":"Overlays - Polylines","href":"/docs/nativemaps/overlays---polylines","docId":"nativemaps/overlays---polylines"},{"type":"link","label":"Overlays - Polygons","href":"/docs/nativemaps/overlays---polygons","docId":"nativemaps/overlays---polygons"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v5.2","href":"/docs/nativemaps/migrating-to-v5.2","docId":"nativemaps/migrating-to-v5.2"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/nativemaps/migrating-to-androidx","docId":"nativemaps/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/nativemaps/changelog","docId":"nativemaps/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/nativemaps/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-NativeMaps/issues/new"}],"collapsed":true,"collapsible":true}],"nativetext":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Native Text","href":"/docs/nativetext/","docId":"nativetext/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/nativetext/add-the-extension","docId":"nativetext/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Keyboard Input","href":"/docs/nativetext/keyboard-input","docId":"nativetext/keyboard-input"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/nativetext/changelog","docId":"nativetext/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/nativetext/"},{"type":"link","label":"Contact Support","href":"http://github.com/airnativeextensions/ANE-NativeText/issues/new"}],"collapsed":true,"collapsible":true}],"nativewebview":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"NativeWebView","href":"/docs/nativewebview/","docId":"nativewebview/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/nativewebview/add-the-extension","docId":"nativewebview/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/nativewebview/initialise-the-extension","docId":"nativewebview/initialise-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Web View","items":[{"type":"link","label":"Create a WebView","href":"/docs/nativewebview/create-a-webview","docId":"nativewebview/create-a-webview"},{"type":"link","label":"WebView Information","href":"/docs/nativewebview/webview-information","docId":"nativewebview/webview-information"},{"type":"link","label":"Position Size Visibility","href":"/docs/nativewebview/position-size-visibility","docId":"nativewebview/position-size-visibility"},{"type":"link","label":"Loading Packaged Files","href":"/docs/nativewebview/loading-packaged-files","docId":"nativewebview/loading-packaged-files"},{"type":"link","label":"Screenshot","href":"/docs/nativewebview/screenshot","docId":"nativewebview/screenshot"},{"type":"link","label":"Communication","href":"/docs/nativewebview/communication","docId":"nativewebview/communication"},{"type":"link","label":"Location Changes","href":"/docs/nativewebview/location-changes","docId":"nativewebview/location-changes"},{"type":"link","label":"Removing the WebView","href":"/docs/nativewebview/removing-the-webview","docId":"nativewebview/removing-the-webview"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other Features","items":[{"type":"link","label":"Browser View","href":"/docs/nativewebview/browser-view","docId":"nativewebview/browser-view"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v5.4","href":"/docs/nativewebview/migrating-to-v5.4","docId":"nativewebview/migrating-to-v5.4"},{"type":"link","label":"Migrating to v5","href":"/docs/nativewebview/migrating-to-v5","docId":"nativewebview/migrating-to-v5"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/nativewebview/migrating-to-androidx","docId":"nativewebview/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/nativewebview/changelog","docId":"nativewebview/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/nativewebview/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-NativeWebView/issues/new"}],"collapsed":true,"collapsible":true}],"networkinfo":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"NetworkInfo","href":"/docs/networkinfo/","docId":"networkinfo/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/networkinfo/add-the-extension","docId":"networkinfo/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Network Change Monitoring","href":"/docs/networkinfo/network-change-monitoring","docId":"networkinfo/network-change-monitoring"},{"type":"link","label":"Telephony","href":"/docs/networkinfo/telephony","docId":"networkinfo/telephony"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/networkinfo/changelog","docId":"networkinfo/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/networkinfo/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-NetworkInfo/issues/new"}],"collapsed":true,"collapsible":true}],"nfc":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"NFC","href":"/docs/nfc/","docId":"nfc/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/nfc/add-the-extension","docId":"nfc/add-the-extension"},{"type":"link","label":"Unity","href":"/docs/nfc/add-the-plugin","docId":"nfc/add-the-plugin"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Scanning","items":[{"type":"link","label":"Overview","href":"/docs/nfc/scanning","docId":"nfc/scanning"},{"type":"link","label":"Dispatch Mode","href":"/docs/nfc/dispatch-mode","docId":"nfc/dispatch-mode"},{"type":"link","label":"Reader Mode","href":"/docs/nfc/reader-mode","docId":"nfc/reader-mode"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/nfc/changelog","docId":"nfc/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/nfc/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-NFC/issues/new"}],"collapsed":true,"collapsible":true}],"notifications":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Notifications","href":"/docs/notifications/","docId":"notifications/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/notifications/add-the-extension","docId":"notifications/add-the-extension"},{"type":"link","label":"Add the Extension - Windows","href":"/docs/notifications/add-the-extension---windows","docId":"notifications/add-the-extension---windows"},{"type":"link","label":"Request Authorisation","href":"/docs/notifications/request-authorisation","docId":"notifications/request-authorisation"},{"type":"link","label":"Setup your Service","href":"/docs/notifications/setup-your-service","docId":"notifications/setup-your-service"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Notifications","items":[{"type":"link","label":"Register for notifications","href":"/docs/notifications/register-for-notifications","docId":"notifications/register-for-notifications"},{"type":"link","label":"Displaying Notifications","href":"/docs/notifications/displaying-notifications","docId":"notifications/displaying-notifications"},{"type":"link","label":"Notification Types","href":"/docs/notifications/notification-types","docId":"notifications/notification-types"},{"type":"link","label":"Notification Icons","href":"/docs/notifications/notification-icons","docId":"notifications/notification-icons"},{"type":"link","label":"Emojis","href":"/docs/notifications/emojis","docId":"notifications/emojis"},{"type":"link","label":"Sounds","href":"/docs/notifications/sounds","docId":"notifications/sounds"},{"type":"link","label":"Receiving notifications","href":"/docs/notifications/receiving-notifications","docId":"notifications/receiving-notifications"},{"type":"link","label":"Delay and Repeat Interval","href":"/docs/notifications/delay-and-repeat-interval","docId":"notifications/delay-and-repeat-interval"},{"type":"link","label":"Cancel Notifications","href":"/docs/notifications/cancel-notifications","docId":"notifications/cancel-notifications"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other features","items":[{"type":"link","label":"Set Badge Number","href":"/docs/notifications/set-badge-number","docId":"notifications/set-badge-number"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v6.5","href":"/docs/notifications/migrating-to-6.5","docId":"notifications/migrating-to-6.5"},{"type":"link","label":"Migrating to v6.4","href":"/docs/notifications/migrating-to-6.4","docId":"notifications/migrating-to-6.4"},{"type":"link","label":"Migrating to v6.3","href":"/docs/notifications/migrating-to-6.3","docId":"notifications/migrating-to-6.3"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/notifications/migrating-to-androidx","docId":"notifications/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/notifications/changelog","docId":"notifications/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/notifications/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Notifications/issues/new"}],"collapsed":true,"collapsible":true}],"ocr":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"OCR","href":"/docs/ocr/","docId":"ocr/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/ocr/add-the-extension","docId":"ocr/add-the-extension"},{"type":"link","label":"Training Data","href":"/docs/ocr/training-data","docId":"ocr/training-data"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Recognising Text","href":"/docs/ocr/recognising-text","docId":"ocr/recognising-text"},{"type":"link","label":"Tips for Improving OCR Results","href":"/docs/ocr/tips-for-improving-ocr-results","docId":"ocr/tips-for-improving-ocr-results"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/ocr/migrating-to-androidx","docId":"ocr/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/ocr/changelog","docId":"ocr/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/ocr/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-OCR/issues/new"}],"collapsed":true,"collapsible":true}],"packagemanager":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"PackageManager","href":"/docs/packagemanager/","docId":"packagemanager/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/packagemanager/add-the-extension","docId":"packagemanager/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Package Events","href":"/docs/packagemanager/package-events","docId":"packagemanager/package-events"},{"type":"link","label":"Installing Apps","href":"/docs/packagemanager/installing-apps","docId":"packagemanager/installing-apps"},{"type":"link","label":"Installed Application Info","href":"/docs/packagemanager/installed-application-info","docId":"packagemanager/installed-application-info"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/packagemanager/migrating-to-androidx","docId":"packagemanager/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/packagemanager/changelog","docId":"packagemanager/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/packagemanager/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-PackageManager/issues/new"}],"collapsed":true,"collapsible":true}],"pdfreader":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"PDFReader","href":"/docs/pdfreader/","docId":"pdfreader/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/pdfreader/add-the-extension","docId":"pdfreader/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Create a PDF View","href":"/docs/pdfreader/create-a-pdf-view","docId":"pdfreader/create-a-pdf-view"},{"type":"link","label":"Pages","href":"/docs/pdfreader/pages","docId":"pdfreader/pages"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to AndroidX","href":"/docs/pdfreader/migrating-to-androidx","docId":"pdfreader/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/pdfreader/changelog","docId":"pdfreader/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/pdfreader/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-PDFReader/issues/new"}],"collapsed":true,"collapsible":true}],"permissions":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Permissions","href":"/docs/permissions/","docId":"permissions/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/permissions/add-the-extension","docId":"permissions/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Set Permissions","href":"/docs/permissions/set-permissions","docId":"permissions/set-permissions"},{"type":"link","label":"Requesting Access","href":"/docs/permissions/requesting-access","docId":"permissions/requesting-access"},{"type":"link","label":"File and Folder Access","href":"/docs/permissions/file-folder-access","docId":"permissions/file-folder-access"},{"type":"link","label":"System Settings","href":"/docs/permissions/system-settings","docId":"permissions/system-settings"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v3.4","href":"/docs/permissions/migrating-to-v3.4","docId":"permissions/migrating-to-v3.4"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/permissions/migrating-to-androidx","docId":"permissions/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/permissions/changelog","docId":"permissions/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/permissions/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Permissions/issues/new"}],"collapsed":true,"collapsible":true}],"pushnotifications":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"PushNotifications","href":"/docs/pushnotifications/","docId":"pushnotifications/index"},{"type":"link","label":"Add the Extension","href":"/docs/pushnotifications/add-the-extension","docId":"pushnotifications/add-the-extension"},{"type":"category","label":"Notification services","items":[{"type":"category","label":"Apple Push Notification Service","items":[{"type":"link","label":"Add the extension","href":"/docs/pushnotifications/apple/add-the-extension","docId":"pushnotifications/apple/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/pushnotifications/apple/apple-push-notification-service","docId":"pushnotifications/apple/apple-push-notification-service"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Firebase Messaging","items":[{"type":"link","label":"Add the extension","href":"/docs/pushnotifications/firebase/add-the-extension","docId":"pushnotifications/firebase/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/pushnotifications/firebase/firebase-cloud-messaging","docId":"pushnotifications/firebase/firebase-cloud-messaging"},{"type":"link","label":"Migrating to v10.1","href":"/docs/pushnotifications/migrating-to-v10.1","docId":"pushnotifications/migrating-to-v10.1"}],"collapsed":true,"collapsible":true},{"type":"category","label":"One Signal","items":[{"type":"link","label":"Add the extension","href":"/docs/pushnotifications/onesignal/add-the-extension","docId":"pushnotifications/onesignal/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/pushnotifications/onesignal/","docId":"pushnotifications/onesignal/onesignal"},{"type":"link","label":"Huawei","href":"/docs/pushnotifications/onesignal/huawei","docId":"pushnotifications/onesignal/huawei"},{"type":"link","label":"Migrating to v11.2","href":"/docs/pushnotifications/migrating-to-v11.2","docId":"pushnotifications/migrating-to-v11.2"},{"type":"link","label":"Migrating to v10.2","href":"/docs/pushnotifications/migrating-to-v10.2","docId":"pushnotifications/migrating-to-v10.2"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Windows","items":[{"type":"link","label":"Add the Extension","href":"/docs/pushnotifications/windows/add-the-extension","docId":"pushnotifications/windows/add-the-extension"},{"type":"link","label":"Setup","href":"/docs/pushnotifications/windows/windows-notification-service","docId":"pushnotifications/windows/windows-notification-service"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Azure Notifications","href":"/docs/pushnotifications/azure/azure-notifications","docId":"pushnotifications/azure/azure-notifications"},{"type":"link","label":"Pushy","href":"/docs/pushnotifications/pushy/","docId":"pushnotifications/pushy/pushy"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Setup, authorisation, and registration","items":[{"type":"link","label":"Setup your Service","href":"/docs/pushnotifications/setup-your-service","docId":"pushnotifications/setup-your-service"},{"type":"category","label":"Service Type Details","items":[{"type":"link","label":"Azure","href":"/docs/pushnotifications/azure/setup-your-service","docId":"pushnotifications/azure/setup-your-service"},{"type":"link","label":"OneSignal","href":"/docs/pushnotifications/onesignal/setup-your-service","docId":"pushnotifications/onesignal/setup-your-service"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Request Authorisation","href":"/docs/pushnotifications/request-authorisation","docId":"pushnotifications/request-authorisation"},{"type":"link","label":"Register for notifications","href":"/docs/pushnotifications/register-for-notifications","docId":"pushnotifications/register-for-notifications"},{"type":"link","label":"Topics","href":"/docs/pushnotifications/topics","docId":"pushnotifications/topics"},{"type":"link","label":"Tags","href":"/docs/pushnotifications/tags","docId":"pushnotifications/tags"},{"type":"link","label":"User Consent","href":"/docs/pushnotifications/user-consent","docId":"pushnotifications/user-consent"},{"type":"link","label":"InApp Messaging","href":"/docs/pushnotifications/inapp-messaging","docId":"pushnotifications/inapp-messaging"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Notifications","items":[{"type":"link","label":"Receiving notifications","href":"/docs/pushnotifications/receiving-notifications","docId":"pushnotifications/receiving-notifications"},{"type":"link","label":"Icons","href":"/docs/pushnotifications/icons","docId":"pushnotifications/icons"},{"type":"link","label":"Handling startup notifications","href":"/docs/pushnotifications/handling-startup-notifications","docId":"pushnotifications/handling-startup-notifications"},{"type":"link","label":"Notification Scenarios","href":"/docs/pushnotifications/notification-scenarios","docId":"pushnotifications/notification-scenarios"},{"type":"link","label":"Sounds","href":"/docs/pushnotifications/sounds","docId":"pushnotifications/sounds"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other features","items":[{"type":"link","label":"Set Badge Number","href":"/docs/pushnotifications/set-badge-number","docId":"pushnotifications/set-badge-number"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Payloads","items":[{"type":"link","label":"iOS APNS Payload","href":"/docs/pushnotifications/apple/ios-apns-payload","docId":"pushnotifications/apple/ios-apns-payload"},{"type":"link","label":"FCM-GCM Payload","href":"/docs/pushnotifications/firebase/fcm-gcm-payload","docId":"pushnotifications/firebase/fcm-gcm-payload"},{"type":"link","label":"Windows WNS Payload","href":"/docs/pushnotifications/windows/windows-wns-payload","docId":"pushnotifications/windows/windows-wns-payload"},{"type":"link","label":"Pushy Payload","href":"/docs/pushnotifications/pushy/pushy-payload","docId":"pushnotifications/pushy/pushy-payload"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Sending Messages","items":[{"type":"link","label":"iOS APNS Message","href":"/docs/pushnotifications/apple/ios-apns-message","docId":"pushnotifications/apple/ios-apns-message"},{"type":"link","label":"Firebase Cloud Message","href":"/docs/pushnotifications/firebase/firebase-cloud-message","docId":"pushnotifications/firebase/firebase-cloud-message"},{"type":"link","label":"Windows WNS Message","href":"/docs/pushnotifications/windows/windows-wns-message","docId":"pushnotifications/windows/windows-wns-message"},{"type":"link","label":"Pushy Message","href":"/docs/pushnotifications/pushy/pushy-message","docId":"pushnotifications/pushy/pushy-message"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v13.0","href":"/docs/pushnotifications/migrating-to-v13.0","docId":"pushnotifications/migrating-to-v13.0"},{"type":"link","label":"Migrating to v11.3","href":"/docs/pushnotifications/migrating-to-v11.3","docId":"pushnotifications/migrating-to-v11.3"},{"type":"link","label":"Migrating to v11.2","href":"/docs/pushnotifications/migrating-to-v11.2","docId":"pushnotifications/migrating-to-v11.2"},{"type":"link","label":"Migrating to v10.2","href":"/docs/pushnotifications/migrating-to-v10.2","docId":"pushnotifications/migrating-to-v10.2"},{"type":"link","label":"Migrating to v10.1","href":"/docs/pushnotifications/migrating-to-v10.1","docId":"pushnotifications/migrating-to-v10.1"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/pushnotifications/migrating-to-androidx","docId":"pushnotifications/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/pushnotifications/changelog","docId":"pushnotifications/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/pushnotifications/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-PushNotifications/issues/new"}],"collapsed":true,"collapsible":true}],"restartapp":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Restart App","href":"/docs/restartapp/","docId":"restartapp/index"},{"type":"link","label":"Add the Extension","href":"/docs/restartapp/add-the-extension","docId":"restartapp/add-the-extension"},{"type":"link","label":"Restart Application","href":"/docs/restartapp/restart-application","docId":"restartapp/restart-application"},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/restartapp/changelog","docId":"restartapp/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/restartapp/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-RestartApp/issues/new"}],"collapsed":true,"collapsible":true}],"rootchecker":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Root Checker","href":"/docs/rootchecker/","docId":"rootchecker/index"},{"type":"link","label":"Add the Extension","href":"/docs/rootchecker/add-the-extension","docId":"rootchecker/add-the-extension"},{"type":"link","label":"Root Check","href":"/docs/rootchecker/root-check","docId":"rootchecker/root-check"},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/rootchecker/changelog","docId":"rootchecker/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/rootchecker/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-RootChecker/issues/new"}],"collapsed":true,"collapsible":true}],"scanner":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Scanner","href":"/docs/scanner/","docId":"scanner/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/scanner/add-the-extension","docId":"scanner/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Requesting Access","href":"/docs/scanner/requesting-access","docId":"scanner/requesting-access"},{"type":"link","label":"Scanning","href":"/docs/scanner/scanning","docId":"scanner/scanning"},{"type":"link","label":"Scanning Bitmap Data","href":"/docs/scanner/scanning-bitmap-data","docId":"scanner/scanning-bitmap-data"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v5.1","href":"/docs/scanner/migrating-to-v5.1","docId":"scanner/migrating-to-v5.1"},{"type":"link","label":"Migrating to version 5","href":"/docs/scanner/migrating-to-version-5","docId":"scanner/migrating-to-version-5"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/scanner/migrating-to-androidx","docId":"scanner/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/scanner/changelog","docId":"scanner/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/scanner/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Scanner/issues/new"}],"collapsed":true,"collapsible":true}],"sensormanager":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"SensorManager","href":"/docs/sensormanager/","docId":"sensormanager/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/sensormanager/add-the-extension","docId":"sensormanager/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Proximity","href":"/docs/sensormanager/proximity","docId":"sensormanager/proximity"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/sensormanager/changelog","docId":"sensormanager/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/sensormanager/"},{"type":"link","label":"Contact Support","href":"http://github.com/airnativeextensions/ANE-SensorManager/issues/new"}],"collapsed":true,"collapsible":true}],"share":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Share","href":"/docs/share/","docId":"share/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/share/add-the-extension","docId":"share/add-the-extension"},{"type":"link","label":"Unity","href":"/docs/share/add-the-plugin","docId":"share/add-the-plugin"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Simple Share","href":"/docs/share/simple-share","docId":"share/simple-share"},{"type":"link","label":"Share Files","href":"/docs/share/share-files","docId":"share/share-files"},{"type":"link","label":"Launch Applications","href":"/docs/share/launch-applications","docId":"share/launch-applications"},{"type":"link","label":"Android Events","href":"/docs/share/android-events","docId":"share/android-events"},{"type":"link","label":"Positioning","href":"/docs/share/positioning","docId":"share/positioning"},{"type":"link","label":"Email","href":"/docs/share/email","docId":"share/email"},{"type":"link","label":"SMS","href":"/docs/share/sms","docId":"share/sms"}],"collapsed":true,"collapsible":true},{"type":"category","label":"iOS App Extension","items":[{"type":"link","label":"AppExtension - Introduction","href":"/docs/share/appextension---introduction","docId":"share/appextension---introduction"},{"type":"link","label":"AppExtension - Setup","href":"/docs/share/appextension---setup","docId":"share/appextension---setup"},{"type":"link","label":"AppExtension - Share Extension","href":"/docs/share/appextension---share-extension","docId":"share/appextension---share-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Troubleshooting","items":[{"type":"link","label":"Migrating to v7.4","href":"/docs/share/migrating-to-v7.4","docId":"share/migrating-to-v7.4"},{"type":"link","label":"Migrating from Message","href":"/docs/share/migrating-from-message","docId":"share/migrating-from-message"},{"type":"link","label":"Migrating to AndroidX","href":"/docs/share/migrating-to-androidx","docId":"share/migrating-to-androidx"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/share/changelog","docId":"share/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/share/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Share/issues/new"}],"collapsed":true,"collapsible":true}],"singular":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Singular","href":"/docs/singular/","docId":"singular/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/singular/add-the-extension","docId":"singular/add-the-extension"},{"type":"link","label":"Initialise","href":"/docs/singular/initialise","docId":"singular/initialise"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Tracking Events and Revenue","href":"/docs/singular/tracking-events","docId":"singular/tracking-events"},{"type":"link","label":"Advanced Options","href":"/docs/singular/advanced-options","docId":"singular/advanced-options"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/singular/changelog","docId":"singular/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/singular/"},{"type":"link","label":"Contact Support","href":"http://github.com/airnativeextensions/ANE-Singular/issues/new"}],"collapsed":true,"collapsible":true}],"speech":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Speech","href":"/docs/speech/","docId":"speech/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/speech/add-the-extension","docId":"speech/add-the-extension"},{"type":"link","label":"Authorisation","href":"/docs/speech/authorisation","docId":"speech/authorisation"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Text to Speech","href":"/docs/speech/texttospeech","docId":"speech/texttospeech"},{"type":"link","label":"Speech Recognition","href":"/docs/speech/recognition","docId":"speech/recognition"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/speech/changelog","docId":"speech/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/speech/"},{"type":"link","label":"Contact Support","href":"http://github.com/airnativeextensions/ANE-Speech/issues/new"}],"collapsed":true,"collapsible":true}],"systemgestures":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"SystemGestures","href":"/docs/systemgestures/","docId":"systemgestures/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/systemgestures/add-the-extension","docId":"systemgestures/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Defer System Gestures","href":"/docs/systemgestures/defer-system-gestures","docId":"systemgestures/defer-system-gestures"},{"type":"link","label":"Home Indicator","href":"/docs/systemgestures/home-indicator","docId":"systemgestures/home-indicator"},{"type":"link","label":"Native Gesture Events","href":"/docs/systemgestures/native-gesture-events","docId":"systemgestures/native-gesture-events"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/systemgestures/changelog","docId":"systemgestures/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/systemgestures/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-SystemGestures/issues/new"}],"collapsed":true,"collapsible":true}],"unityads":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"UnityAds","href":"/docs/unityads/","docId":"unityads/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/unityads/add-the-extension","docId":"unityads/add-the-extension"},{"type":"link","label":"Initialise","href":"/docs/unityads/initialise","docId":"unityads/initialise"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Interstitials","href":"/docs/unityads/interstitials","docId":"unityads/interstitials"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/unityads/changelog","docId":"unityads/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/unityads/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-UnityAds/issues/new"}],"collapsed":true,"collapsible":true}],"vibration":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Vibration","href":"/docs/vibration/","docId":"vibration/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"AIR","href":"/docs/vibration/add-the-extension","docId":"vibration/add-the-extension"},{"type":"link","label":"Unity","href":"/docs/vibration/add-the-plugin","docId":"vibration/add-the-plugin"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Vibrate","href":"/docs/vibration/vibrate","docId":"vibration/vibrate"},{"type":"link","label":"Feedback Generators","href":"/docs/vibration/feedback-generators","docId":"vibration/feedback-generators"},{"type":"link","label":"Haptic Engine","href":"/docs/vibration/haptic-engine","docId":"vibration/haptic-engine"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/vibration/changelog","docId":"vibration/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/vibration/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Vibration/issues/new"}],"collapsed":true,"collapsible":true}],"volume":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Volume","href":"/docs/volume/","docId":"volume/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/volume/add-the-extension","docId":"volume/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Volume Control","href":"/docs/volume/volume-control","docId":"volume/volume-control"},{"type":"link","label":"Streams","href":"/docs/volume/streams","docId":"volume/streams"},{"type":"link","label":"Silent Switch","href":"/docs/volume/silent-switch","docId":"volume/silent-switch"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/volume/changelog","docId":"volume/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/volume/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-Volume/issues/new"}],"collapsed":true,"collapsible":true}],"webp":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"WebP","href":"/docs/webp/","docId":"webp/index"},{"type":"category","label":"Get Started","items":[{"type":"link","label":"Add the Extension","href":"/docs/webp/add-the-extension","docId":"webp/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"WebPLoader","href":"/docs/webp/webploader","docId":"webp/webploader"},{"type":"link","label":"Load a WebP File","href":"/docs/webp/load-a-webp-file","docId":"webp/load-a-webp-file"},{"type":"link","label":"Parse WebP Data","href":"/docs/webp/parse-webp-data","docId":"webp/parse-webp-data"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/webp/changelog","docId":"webp/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/webp/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-WebP/issues/new"}],"collapsed":true,"collapsible":true}],"windowsstore":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"WindowsStore","href":"/docs/windowsstore/","docId":"windowsstore/index"},{"type":"category","label":"Setup the Extension","items":[{"type":"link","label":"Add the Extension","href":"/docs/windowsstore/add-the-extension","docId":"windowsstore/add-the-extension"},{"type":"link","label":"Initialise the Extension","href":"/docs/windowsstore/initialise-the-extension","docId":"windowsstore/initialise-the-extension"},{"type":"category","label":"Windows","items":[{"type":"link","label":"Windows-Overview","href":"/docs/windowsstore/windows-overview","docId":"windowsstore/windows-overview"},{"type":"link","label":"Windows-Developer Account","href":"/docs/windowsstore/windows-developer-account","docId":"windowsstore/windows-developer-account"},{"type":"link","label":"Windows-Desktop App Converter","href":"/docs/windowsstore/windows-desktop-app-converter","docId":"windowsstore/windows-desktop-app-converter"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Products","href":"/docs/windowsstore/products","docId":"windowsstore/products"},{"type":"link","label":"Purchases","href":"/docs/windowsstore/purchases","docId":"windowsstore/purchases"},{"type":"link","label":"Make Purchase","href":"/docs/windowsstore/make-purchase","docId":"windowsstore/make-purchase"},{"type":"link","label":"Consumables","href":"/docs/windowsstore/consumables","docId":"windowsstore/consumables"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/windowsstore/changelog","docId":"windowsstore/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/windowsstore/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-WindowsStore/issues/new"}],"collapsed":true,"collapsible":true}],"ziputils":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"ZipUtils","href":"/docs/ziputils/","docId":"ziputils/index"},{"type":"category","label":"Setup the Extension","items":[{"type":"link","label":"Add the Extension","href":"/docs/ziputils/add-the-extension","docId":"ziputils/add-the-extension"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Usage","items":[{"type":"link","label":"Unzipping a file","href":"/docs/ziputils/unzipping-a-file","docId":"ziputils/unzipping-a-file"},{"type":"link","label":"Zipping","href":"/docs/ziputils/zipping","docId":"ziputils/zipping"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Other","items":[{"type":"link","label":"changelog","href":"/docs/ziputils/changelog","docId":"ziputils/changelog"},{"type":"link","label":"asdocs","href":"https://docs.airnativeextensions.com/asdocs/ziputils/"},{"type":"link","label":"Contact Support","href":"http://github.com/distriqt/ANE-ZipUtils/issues/new"}],"collapsed":true,"collapsible":true}],"faqs":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"FAQs","href":"/docs/faqs/","docId":"faqs/index"},{"type":"link","label":"ld: unknown option","href":"/docs/faqs/ld-unknown-option","docId":"faqs/ld-unknown-option"},{"type":"link","label":"ld: warning","href":"/docs/faqs/ld-warning","docId":"faqs/ld-warning"},{"type":"link","label":"ld: framework not found ...","href":"/docs/faqs/ld-framework-not-found","docId":"faqs/ld-framework-not-found"},{"type":"link","label":"Error: The native extension context could not be created","href":"/docs/faqs/error-context-create","docId":"faqs/error-context-create"},{"type":"link","label":"404 error when accessing repository?","href":"/docs/faqs/error-404","docId":"faqs/error-404"}],"tutorials":[{"type":"link","label":"Home","href":"/docs/","docId":"index"},{"type":"link","label":"Tutorials","href":"/docs/tutorials/","docId":"tutorials/index"},{"type":"category","label":"Getting Started","items":[{"type":"link","label":"Adding an Extension","href":"/docs/tutorials/getting-started","docId":"tutorials/getting-started"},{"type":"category","label":"IDE","items":[{"type":"link","label":"IntelliJ","href":"/docs/tutorials/getting-started-intellij","docId":"tutorials/getting-started-intellij"},{"type":"link","label":"Flash Builder 4.6/4.7","href":"/docs/tutorials/getting-started-flashbuilder4.7","docId":"tutorials/getting-started-flashbuilder4.7"},{"type":"link","label":"Flash Builder 4.5","href":"/docs/tutorials/getting-started-flashbuilder4.5","docId":"tutorials/getting-started-flashbuilder4.5"},{"type":"link","label":"Flash Develop","href":"/docs/tutorials/getting-started-flashdevelop","docId":"tutorials/getting-started-flashdevelop"},{"type":"link","label":"Animate","href":"/docs/tutorials/getting-started-animate","docId":"tutorials/getting-started-animate"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Debugging","items":[{"type":"link","label":"Device Logs","href":"/docs/tutorials/device-logs","docId":"tutorials/device-logs"},{"type":"link","label":"Android Device Debugging","href":"/docs/tutorials/android-device-debugging","docId":"tutorials/android-device-debugging"}],"collapsed":true,"collapsible":true},{"type":"category","label":"iOS Development","items":[{"type":"link","label":"Icons, Launch Storyboards and the Assets Catalog","href":"/docs/tutorials/ios-icons-assets-car","docId":"tutorials/ios-icons-assets-car"},{"type":"link","label":"Launchscreen","href":"/docs/tutorials/ios-launchscreens","docId":"tutorials/ios-launchscreens"},{"type":"link","label":"iOS SDK","href":"/docs/tutorials/ios-sdk-custom","docId":"tutorials/ios-sdk-custom"},{"type":"link","label":"iOS SDK Versions","href":"/docs/tutorials/ios-sdk-versions","docId":"tutorials/ios-sdk-versions"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Android Development","items":[{"type":"link","label":"Android Splash Screen","href":"/docs/tutorials/android-splash-screen","docId":"tutorials/android-splash-screen"},{"type":"link","label":"Android Adaptive Icons","href":"/docs/tutorials/android-adaptive-icons","docId":"tutorials/android-adaptive-icons"},{"type":"link","label":"Android Resources","href":"/docs/tutorials/android-resources","docId":"tutorials/android-resources"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Windows Development","items":[{"type":"link","label":"Windows Store Packaging","href":"/docs/tutorials/windows-appx-packaging","docId":"tutorials/windows-appx-packaging"},{"type":"link","label":"Windows Store Packaging - Method 1","href":"/docs/tutorials/windows-appx-packaging-method1","docId":"tutorials/windows-appx-packaging-method1"},{"type":"link","label":"Windows Store Packaging - Method 2","href":"/docs/tutorials/windows-appx-packaging-method2","docId":"tutorials/windows-appx-packaging-method2"},{"type":"link","label":"Windows Store Packaging - Method 3","href":"/docs/tutorials/windows-appx-packaging-method3","docId":"tutorials/windows-appx-packaging-method3"}],"collapsed":true,"collapsible":true}]},"docs":{"adverts/add-the-extension":{"id":"adverts/add-the-extension","title":"Add the Extension","description":"Here we will show you how to add the extension to your development environment and make the necessary changes to your application descriptor to correctly support the extension.","sidebar":"adverts"},"adverts/advertising-identifier":{"id":"adverts/advertising-identifier","title":"Advertising Identifier","description":"We have made the decision to deprecate the advertising identifier functionality from the Adverts extension.","sidebar":"adverts"},"adverts/app-open-ads":{"id":"adverts/app-open-ads","title":"App Open Ads","description":"App open ads are a special ad format intended for publishers wishing to monetize their app load screens. App open ads can be closed at any time, and are designed to be shown when your users bring your app to the foreground.","sidebar":"adverts"},"adverts/banner-adverts":{"id":"adverts/banner-adverts","title":"Banner Adverts","description":"Banner advertisements are represented by the AdView class. You create an instance of this class using the extension and then use this instance to set properties, load and display the advert.","sidebar":"adverts"},"adverts/changelog":{"id":"adverts/changelog","title":"changelog","description":"2023.08.18 [v14.3.0]","sidebar":"adverts"},"adverts/consent":{"id":"adverts/consent","title":"Consent","description":"AdMob users must migrate to the User Messaging Platform to ensure you have access to the latest consent gathering tools. The consent sdk has been removed due to app rejections when it was included.","sidebar":"adverts"},"adverts/index":{"id":"adverts/index","title":"Adverts","description":"The Adverts extension gives you the ability to display adverts in your AIR application.","sidebar":"adverts"},"adverts/initialise-platform":{"id":"adverts/initialise-platform","title":"Initialise Platform","description":"Setup the platform","sidebar":"adverts"},"adverts/interstitials":{"id":"adverts/interstitials","title":"Interstitials","description":"The interstitials are fullscreen adverts that you can use to transition between","sidebar":"adverts"},"adverts/life-time-value":{"id":"adverts/life-time-value","title":"Life Time Value (LTV)","description":"When an impression occurs, the extension calls the paid event handler with its associated revenue data. By implementing this event handler, you can use the data to calculate a user\'s life time value, or forward the data downstream to other relevant systems.","sidebar":"adverts"},"adverts/mediation/adcolony/index":{"id":"adverts/mediation/adcolony/index","title":"AdColony","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from AdColony through Open Bidding or waterfall mediation. It covers how to add AdColony ads to an ad unit\'s mediation configuration, and how to integrate the AdColony SDK and adapter into an AIR app.","sidebar":"adverts"},"adverts/mediation/applovin/index":{"id":"adverts/mediation/applovin/index","title":"AppLovin","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from AppLovin Ads via mediation. It covers how to add AppLovin to an ad unit\'s mediation configuration , how to set up Ad Network Optimization (ANO), and how to integrate the AppLovin SDK and adapter into an Android app.","sidebar":"adverts"},"adverts/mediation/changelog":{"id":"adverts/mediation/changelog","title":"changelog","description":"2023.08.22 [v6.8.1]"},"adverts/mediation/facebookaudience/index":{"id":"adverts/mediation/facebookaudience/index","title":"Facebook Audience","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Facebook Audience Network via mediation.","sidebar":"adverts"},"adverts/mediation/index":{"id":"adverts/mediation/index","title":"Adverts-Mediation","description":"These extensions allow you to add mediation networks with advertising platforms using the Adverts ANE."},"adverts/mediation/ironsource/index":{"id":"adverts/mediation/ironsource/index","title":"IronSource","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from ironSource through mediation.","sidebar":"adverts"},"adverts/mediation/pangle/index":{"id":"adverts/mediation/pangle/index","title":"Pangle","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Pangle Ads via mediation.","sidebar":"adverts"},"adverts/mediation/tapjoy/index":{"id":"adverts/mediation/tapjoy/index","title":"Tapjoy","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Tapjoy through mediation.","sidebar":"adverts"},"adverts/mediation/unityads/index":{"id":"adverts/mediation/unityads/index","title":"UnityAds","description":"This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Unity Ads via mediation.","sidebar":"adverts"},"adverts/migrating-from-version-4":{"id":"adverts/migrating-from-version-4","title":"Migrating from version 4","description":"Version 5 completely changes the way adverts are displayed, including more control over the ad units that are displayed. Migration is simple as laid out below.","sidebar":"adverts"},"adverts/migrating-to-androidx":{"id":"adverts/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"adverts"},"adverts/migrating-to-version-10":{"id":"adverts/migrating-to-version-10","title":"Migrating to version 10","description":"Version 10 brings the latest consent gathering processes from Google utilising the User Messaging Platform and preparations for iOS 14\'s App Tracking Transparency framework requirement.","sidebar":"adverts"},"adverts/migrating-to-version-12":{"id":"adverts/migrating-to-version-12","title":"Migrating to version 12","description":"Version 12 brings the latest AdMob SDK which includes some significant changes to the Android SDK.","sidebar":"adverts"},"adverts/migrating-to-version-13":{"id":"adverts/migrating-to-version-13","title":"Migrating to version 13","description":"Version 13 brings the latest AdMob SDK which includes some significant changes to the SDK. This update includes:","sidebar":"adverts"},"adverts/migrating-to-version-13.6":{"id":"adverts/migrating-to-version-13.6","title":"Migrating to version 13.6","description":"Version 13.6 brings version 9+ of the AdMob iOS SDK which includes some significant changes to the SDK. Most of the changes have been handled internal to the extension however there is one important piece of information that you must be aware of:","sidebar":"adverts"},"adverts/migrating-to-version-14.0":{"id":"adverts/migrating-to-version-14.0","title":"Migrating to version 14.0","description":"Version 14.0 brings support for running the Adverts extension when using the runtimeInBackgroundThread configuration for AIR.","sidebar":"adverts"},"adverts/native-ads":{"id":"adverts/native-ads","title":"Native Ads","description":"Native ads allow you to customize the look and feel of the ads that appear in your app. You design the ads from the ground up: how they look, where they\u2019re placed, and how they work within your existing app design.","sidebar":"adverts"},"adverts/platform/admob/index":{"id":"adverts/platform/admob/index","title":"Google AdMob","description":"This section describes how to setup your AIR application to use AdMob with this extension.","sidebar":"adverts"},"adverts/platform/huawei/index":{"id":"adverts/platform/huawei/index","title":"Huawei Ads Kit","description":"This section describes how to setup your AIR application to use Huawei Ads Kit with this extension. Huawei devices use a variant of Android.","sidebar":"adverts"},"adverts/rewarded-interstitial-ads":{"id":"adverts/rewarded-interstitial-ads","title":"Rewarded Interstitial Ads","description":"Rewarded interstitial is a type of incentivized ad format that allows you offer rewards for ads that appear automatically during natural app transitions. Unlike rewarded ads, users aren\'t required to opt-in to view a rewarded interstitial.","sidebar":"adverts"},"adverts/rewarded-video-ads":{"id":"adverts/rewarded-video-ads","title":"Rewarded Video Ads","description":"Rewarded video ads are full-screen video ads that users have the option of watching in full in exchange for in-app rewards.","sidebar":"adverts"},"adverts/server-side-verification":{"id":"adverts/server-side-verification","title":"Server Side Verification","description":"Server-side verification callbacks are URL requests, with query parameters expanded by Google, that are sent by Google to an external system to notify it that a user should be rewarded for interacting with a rewarded or rewarded interstitial ad.","sidebar":"adverts"},"adverts/targeting":{"id":"adverts/targeting","title":"Targeting","description":"This guide explains how to provide targeting information to an ad request.","sidebar":"adverts"},"adverts/test-ads":{"id":"adverts/test-ads","title":"Test Ads","description":"It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.","sidebar":"adverts"},"adverts/troubleshooting":{"id":"adverts/troubleshooting","title":"Troubleshooting","description":"Common Issues","sidebar":"adverts"},"adverts/user-messaging-platform":{"id":"adverts/user-messaging-platform","title":"User Messaging Platform","description":"Obtaining Consent with the User Messaging Platform","sidebar":"adverts"},"appconfig/add-the-extension":{"id":"appconfig/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"appconfig"},"appconfig/changelog":{"id":"appconfig/changelog","title":"changelog","description":"2023.03.16 [v1.0.0]","sidebar":"appconfig"},"appconfig/index":{"id":"appconfig/index","title":"AppConfig","description":"The AppConfig extension gives you access to ...","sidebar":"appconfig"},"appconfig/setup":{"id":"appconfig/setup","title":"Setup","description":"Android Configuration","sidebar":"appconfig"},"appconfig/usage":{"id":"appconfig/usage","title":"Usage","description":"Get Values","sidebar":"appconfig"},"appgroupdefaults/add-the-extension":{"id":"appgroupdefaults/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"appgroupdefaults"},"appgroupdefaults/add-the-plugin":{"id":"appgroupdefaults/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"appgroupdefaults"},"appgroupdefaults/android":{"id":"appgroupdefaults/android","title":"Android Setup","description":"There are two methods available on Android to share settings between applications.","sidebar":"appgroupdefaults"},"appgroupdefaults/changelog":{"id":"appgroupdefaults/changelog","title":"changelog","description":"2023.01.12 [v4.2.0]","sidebar":"appgroupdefaults"},"appgroupdefaults/index":{"id":"appgroupdefaults/index","title":"AppGroupDefaults","description":"The AppGroup Defaults extension provides the ability to be able to share settings in a key-value store between your different applications installed on a users device.","sidebar":"appgroupdefaults"},"appgroupdefaults/ios":{"id":"appgroupdefaults/ios","title":"iOS Setup","description":"iOS requires set up of an \\"App Group\\" for your application(s).","sidebar":"appgroupdefaults"},"appgroupdefaults/unity":{"id":"appgroupdefaults/unity","title":"Unity","description":"Contents"},"appgroupdefaults/usage":{"id":"appgroupdefaults/usage","title":"Usage","description":"Setup","sidebar":"appgroupdefaults"},"applesignin/add-the-extension":{"id":"applesignin/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"applesignin"},"applesignin/changelog":{"id":"applesignin/changelog","title":"changelog","description":"2023.01.13 [v2.3.0]","sidebar":"applesignin"},"applesignin/get-user-credentials":{"id":"applesignin/get-user-credentials","title":"Get User Credentials","description":"This has proved highly unreliable on iOS and we currently don\'t recommend using this process. It seems to commonly return an error even though everything seems correct. We are waiting for feedback / updates from Apple on this","sidebar":"applesignin"},"applesignin/index":{"id":"applesignin/index","title":"AppleSignIn","description":"The AppleSignIn extension gives you the ability to sign in your users using the \\"Sign in with Apple\\" functionality on iOS / tvOS and Android.","sidebar":"applesignin"},"applesignin/login-with-apple-id":{"id":"applesignin/login-with-apple-id","title":"Login with Apple Id","description":"Login","sidebar":"applesignin"},"applesignin/setup-application":{"id":"applesignin/setup-application","title":"Setup Application","description":"This is an overview of the steps to enable Sign in with Apple in the developer console.","sidebar":"applesignin"},"applesignin/setup-auth-server":{"id":"applesignin/setup-auth-server","title":"Setup Auth Server","description":"Setup Auth Server","sidebar":"applesignin"},"application/add-the-extension":{"id":"application/add-the-extension","title":"Add the Extension","description":"Here we will show you how to add the extension to your development environment and make the necessary changes to your application descriptor to correctly support the extension.","sidebar":"application"},"application/alarm-manager":{"id":"application/alarm-manager","title":"Alarm Manager","description":"The Alarm Manager functionality allows you to use the Android Alarm manager to set your application to receive events","sidebar":"application"},"application/application-state-events":{"id":"application/application-state-events","title":"Application State Events","description":"The AIR standard ACTIVATE and DEACTIVATE events will inform your application when the AIR application loses focus. This is often used to stop application rendering and other operations that you wish to perform when your application enters the background or returns to the foreground.","sidebar":"application"},"application/auto-start":{"id":"application/auto-start","title":"Auto Start","description":"This is an Android only feature.","sidebar":"application"},"application/changelog":{"id":"application/changelog","title":"changelog","description":"2023.11.02 [v7.1.0]","sidebar":"application"},"application/defaults":{"id":"application/defaults","title":"Defaults","description":"The defaults allow you to setup some information for the user, to allow an application to","sidebar":"application"},"application/device-information/accessibility":{"id":"application/device-information/accessibility","title":"Accessibility","description":"The accessibility features allow you to check the current state of accessibility","sidebar":"application"},"application/device-information/device":{"id":"application/device-information/device","title":"Device Information","description":"Device functionality allows you to retrieve information about the device.","sidebar":"application"},"application/device-information/device-state":{"id":"application/device-information/device-state","title":"Device State","description":"Power Save Mode","sidebar":"application"},"application/device-information/operating-system":{"id":"application/device-information/operating-system","title":"Operating System","description":"You can also use the device functionality to retrieve information about the operating system","sidebar":"application"},"application/device-information/orientation-events":{"id":"application/device-information/orientation-events","title":"Orientation Events","description":"The orientation of the device is sometimes important to applications, irrespective of the orientation of the UI. The DeviceOrientationEvent will give you information about the orientation of the device even if your UI doesn\'t change.","sidebar":"application"},"application/device-information/phone-number":{"id":"application/device-information/phone-number","title":"Phone Number","description":"If you require access to the user\'s phone number you will need to request permission to access the phone state.","sidebar":"application"},"application/device-information/unique-device-id":{"id":"application/device-information/unique-device-id","title":"Unique Device ID","description":"Retrieving a Unique Device ID","sidebar":"application"},"application/device-information/year-class":{"id":"application/device-information/year-class","title":"Year Class","description":"The current Android device list has around more than 10k different handsets. So it\'s hard to know how your application will perform on different devices. All having different amount of RAM, CPU speed, number of cores etc.","sidebar":"application"},"application/display/cutouts":{"id":"application/display/cutouts","title":"Cutouts","description":"A display cutout (or notch) is an area on some devices that extends into the display surface to allow for an edge-to-edge experience while providing space for important sensors on the front of the device.","sidebar":"application"},"application/display/dark-mode":{"id":"application/display/dark-mode","title":"Dark Mode","description":"User Interface Style - Dark Mode","sidebar":"application"},"application/display/display":{"id":"application/display/display","title":"Display","description":"This is only applicable to Android currently as these modes don\'t have an equivalent on iOS.","sidebar":"application"},"application/display/display-metrics":{"id":"application/display/display-metrics","title":"Display Metrics","description":"This allows you to get information about the display on the current device.","sidebar":"application"},"application/display/soft-keyboard":{"id":"application/display/soft-keyboard","title":"Soft Keyboard","description":"Experimental","sidebar":"application"},"application/general-helpers":{"id":"application/general-helpers","title":"General Helpers","description":"This section details the available ANE work arounds for current issues","sidebar":"application"},"application/index":{"id":"application/index","title":"Application","description":"The Application extension gives you access to some additional application options that aren\'t availble in the default AIR SDK.","sidebar":"application"},"application/keychain":{"id":"application/keychain","title":"Keychain","description":"The keychain functionality is similar to the defaults however this data is stored in the users keychain encrypted storage.","sidebar":"application"},"application/migrating-to-androidx":{"id":"application/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"application"},"application/migrating-to-v6.12":{"id":"application/migrating-to-v6.12","title":"Migrating to v6.12","description":"v6.12 brings an updated process for requesting permissions on Android."},"application/settings":{"id":"application/settings","title":"Settings and Preferences","description":"In this section we will cover the native integration of settings or preferences in your application.","sidebar":"application"},"application/status-bar":{"id":"application/status-bar","title":"Status Bar","description":"Status Bar"},"applicationrater/add-the-extension":{"id":"applicationrater/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"applicationrater"},"applicationrater/add-the-plugin":{"id":"applicationrater/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"applicationrater"},"applicationrater/application-id":{"id":"applicationrater/application-id","title":"Application ID","description":"The application ID is the most important thing to set in the extension, an invalid value will take you to the wrong application, or fail altogether. This ID is unfortunately different on the different operating systems, it is generally related to an identifier in the particular stores.","sidebar":"applicationrater"},"applicationrater/application-rate-dialog":{"id":"applicationrater/application-rate-dialog","title":"Application Rate Dialog","description":"With this extension you can ask users of your application to return to the application stores and rate your application.","sidebar":"applicationrater"},"applicationrater/application-rate-dialog---states":{"id":"applicationrater/application-rate-dialog---states","title":"Application Rate Dialog - States","description":"There are several states that the service can be in:","sidebar":"applicationrater"},"applicationrater/changelog":{"id":"applicationrater/changelog","title":"changelog","description":"2023.06.13 [v6.3.2]","sidebar":"applicationrater"},"applicationrater/handling-stores":{"id":"applicationrater/handling-stores","title":"Handling Stores","description":"Retrieving the Store","sidebar":"applicationrater"},"applicationrater/index":{"id":"applicationrater/index","title":"ApplicationRater","description":"The Application Rater extension allows you to ask the user for feedback on your application by displaying a native dialog and asking them to rate your application in the appropriate application store. When the user agrees to rate your application they are taken to your applications page in the store.","sidebar":"applicationrater"},"applicationrater/requesting-review":{"id":"applicationrater/requesting-review","title":"Requesting Review","description":"If you don\'t wish to use the rate dialog you can use this extension to simply open the appropriate store page for your user to review your application.","sidebar":"applicationrater"},"applicationrater/review-controller":{"id":"applicationrater/review-controller","title":"Review Controller","description":"The review controller allows you to gather user reviews inside your application without redirecting them to the store. This process generally does not give you feedback about whether a user wrote a review however it does give you the ability to simplify a review request, presenting the review screens directly in your application.","sidebar":"applicationrater"},"applicationrater/unity":{"id":"applicationrater/unity","title":"unity","description":"- Overview"},"applovinsdk/add-the-extension":{"id":"applovinsdk/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"applovinsdk"},"applovinsdk/changelog":{"id":"applovinsdk/changelog","title":"changelog","description":"2023.05.25 [v2.16.0]","sidebar":"applovinsdk"},"applovinsdk/index":{"id":"applovinsdk/index","title":"App Lovin","description":"The AppLovinSDK extension","sidebar":"applovinsdk"},"applovinsdk/initialise":{"id":"applovinsdk/initialise","title":"Initialisation","description":"Initialising the extension","sidebar":"applovinsdk"},"applovinsdk/interstitials":{"id":"applovinsdk/interstitials","title":"Interstitials","description":"The interstitials are fullscreen adverts that you can use to transition between scenes in your application, such as after a game level.","sidebar":"applovinsdk"},"applovinsdk/mediation/admob/admob":{"id":"applovinsdk/mediation/admob/admob","title":"Mediation - AdMob","description":"Add the AdMob Adapter to Your Build","sidebar":"applovinsdk"},"applovinsdk/mediation/facebook/facebook":{"id":"applovinsdk/mediation/facebook/facebook","title":"Mediation - Facebook Audience","description":"Add the Facebook Audience Adapter to Your Build","sidebar":"applovinsdk"},"applovinsdk/mediation/ironsource/ironsource":{"id":"applovinsdk/mediation/ironsource/ironsource","title":"Mediation - IronSource","description":"Add the IronSource Adapter to Your Build","sidebar":"applovinsdk"},"applovinsdk/mediation/unityads/unityads":{"id":"applovinsdk/mediation/unityads/unityads","title":"Mediation - UnityAds","description":"Add the UnityAds Adapter to Your Build","sidebar":"applovinsdk"},"applovinsdk/rewarded-video":{"id":"applovinsdk/rewarded-video","title":"Rewarded Video","description":"Rewarded video ads are full-screen video ads that users have the option of watching in full in exchange for in-app rewards.","sidebar":"applovinsdk"},"audiorecorder/add-the-extension":{"id":"audiorecorder/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"audiorecorder"},"audiorecorder/changelog":{"id":"audiorecorder/changelog","title":"changelog","description":"2023.01.13 [v3.1.0]","sidebar":"audiorecorder"},"audiorecorder/index":{"id":"audiorecorder/index","title":"AudioRecorder","description":"AudioRecorder is an AIR Native Extension to record audio from the user\'s microphone to a file.","sidebar":"audiorecorder"},"audiorecorder/migrating-to-androidx":{"id":"audiorecorder/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X"},"audiorecorder/migrating-to-v3.1":{"id":"audiorecorder/migrating-to-v3.1","title":"Migrating to v3.1","description":"v3.1 brings an updated process for requesting permissions on Android.","sidebar":"audiorecorder"},"audiorecorder/playback":{"id":"audiorecorder/playback","title":"Playback","description":"Playback Recorded Audio","sidebar":"audiorecorder"},"audiorecorder/recording-audio":{"id":"audiorecorder/recording-audio","title":"Recording Audio","description":"Start","sidebar":"audiorecorder"},"audiorecorder/requesting-authorisation":{"id":"audiorecorder/requesting-authorisation","title":"Requesting Authorisation","description":"When you are going to be accessing the microphone you must check that your application has been allowed access.","sidebar":"audiorecorder"},"battery/add-the-extension":{"id":"battery/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"battery"},"battery/battery-info":{"id":"battery/battery-info","title":"Battery Info","description":"To retrieve the battery information you must call the getBatteryInfo function.","sidebar":"battery"},"battery/changelog":{"id":"battery/changelog","title":"changelog","description":"2023.05.18 [v4.1.1]","sidebar":"battery"},"battery/index":{"id":"battery/index","title":"Battery","description":"The Battery extension gives","sidebar":"battery"},"beacon/add-the-extension":{"id":"beacon/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"beacon"},"beacon/broadcasting":{"id":"beacon/broadcasting","title":"Broadcasting","description":"Broadcasting will make the device act as a beacon so that other devices can detect the device as if it were a beacon.","sidebar":"beacon"},"beacon/changelog":{"id":"beacon/changelog","title":"changelog","description":"2023.01.13 [v5.1.0]","sidebar":"beacon"},"beacon/events":{"id":"beacon/events","title":"Events","description":"When the application is running the application will receive region and ranging events directly.","sidebar":"beacon"},"beacon/index":{"id":"beacon/index","title":"Beacon","description":"The Beacon extension","sidebar":"beacon"},"beacon/migrating-to-androidx":{"id":"beacon/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X"},"beacon/migrating-to-v5.1":{"id":"beacon/migrating-to-v5.1","title":"Migrating to v5.1","description":"v5.1 brings an updated process for requesting permissions on Android.","sidebar":"beacon"},"beacon/monitoring-a-region":{"id":"beacon/monitoring-a-region","title":"Monitoring a Region","description":"A region of beacons is designated by a UUID and a simple identifier. You should always supply","sidebar":"beacon"},"beacon/requesting-authorisation":{"id":"beacon/requesting-authorisation","title":"Requesting Authorisation","description":"When you are going to be accessing the user\'s location by scanning for beacons you","sidebar":"beacon"},"beacon/tools-and-resources":{"id":"beacon/tools-and-resources","title":"Tools and Resources","description":"The following list are some useful tools for use during development","sidebar":"beacon"},"bluetooth/add-the-extension":{"id":"bluetooth/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"bluetooth"},"bluetooth/changelog":{"id":"bluetooth/changelog","title":"changelog","description":"2023.01.13 [v3.1.0]","sidebar":"bluetooth"},"bluetooth/connecting":{"id":"bluetooth/connecting","title":"Connecting","description":"Creating a connection between devices","sidebar":"bluetooth"},"bluetooth/index":{"id":"bluetooth/index","title":"Bluetooth","description":"The Bluetooth extension","sidebar":"bluetooth"},"bluetooth/ios":{"id":"bluetooth/ios","title":"iOS","description":"iOS support","sidebar":"bluetooth"},"bluetoothle/adapter-state":{"id":"bluetoothle/adapter-state","title":"Adapter State","description":"Checking the adapter state","sidebar":"bluetoothle"},"bluetoothle/add-the-extension":{"id":"bluetoothle/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"bluetoothle"},"bluetoothle/central-manager":{"id":"bluetoothle/central-manager","title":"Central Manager","description":"Acting as a Central","sidebar":"bluetoothle"},"bluetoothle/centrals-and-peripherals":{"id":"bluetoothle/centrals-and-peripherals","title":"Centrals and Peripherals","description":"In Bluetooth low energy communication, there are two key players: the central and the peripheral.","sidebar":"bluetoothle"},"bluetoothle/changelog":{"id":"bluetoothle/changelog","title":"changelog","description":"2023.01.13 [v4.2.0]","sidebar":"bluetoothle"},"bluetoothle/index":{"id":"bluetoothle/index","title":"BluetoothLE","description":"The BluetoothLE extension","sidebar":"bluetoothle"},"bluetoothle/migrating-to-androidx":{"id":"bluetoothle/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"bluetoothle"},"bluetoothle/migrating-to-v4.2":{"id":"bluetoothle/migrating-to-v4.2","title":"Migrating to v4.2","description":"v4.2 brings an updated process for requesting permissions on Android.","sidebar":"bluetoothle"},"bluetoothle/peripheral-manager":{"id":"bluetoothle/peripheral-manager","title":"Peripheral Manager","description":"Acting as a Peripheral","sidebar":"bluetoothle"},"bluetoothle/request-authorisation":{"id":"bluetoothle/request-authorisation","title":"Request Authorisation","description":"After initialising the extension you should check whether the user has given your application","sidebar":"bluetoothle"},"bolts/changelog":{"id":"bolts/changelog","title":"changelog","description":"2021.08.20 [v4.2.1]"},"branch/add-the-extension":{"id":"branch/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"branch"},"branch/branch-universal-objects":{"id":"branch/branch-universal-objects","title":"Branch Universal Objects","description":"This is the BranchUniversalObject (or BUO for short). Think of it like an empty box.","sidebar":"branch"},"branch/changelog":{"id":"branch/changelog","title":"changelog","description":"2023.05.08 [v5.4.0]","sidebar":"branch"},"branch/deep-links":{"id":"branch/deep-links","title":"Deep Links","description":"If your application is launched from a branch link you will receive an event with the branch parameters associated with that link.","sidebar":"branch"},"branch/event-tracking":{"id":"branch/event-tracking","title":"Event Tracking","description":"To track user events you will use the BranchEventBuilder to construct an event and then pass the output from this to the logEvent function. The builder has a range of helper functions to allow you to correctly construct the event data.","sidebar":"branch"},"branch/get-short-url":{"id":"branch/get-short-url","title":"Get Short URL","description":"Shortened links"},"branch/index":{"id":"branch/index","title":"Branch","description":"Branch IO Adobe AIR Native Extension for iOS and Android gives you access to the Branch SDK in your Adobe AIR application.","sidebar":"branch"},"branch/initialisation":{"id":"branch/initialisation","title":"Initialisation","description":"Initialise the Branch SDK","sidebar":"branch"},"branch/link-parameters":{"id":"branch/link-parameters","title":"Link Parameters","description":"Latest Referring Parameters","sidebar":"branch"},"branch/migrating-to-androidx":{"id":"branch/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X"},"branch/referral-credits":{"id":"branch/referral-credits","title":"Referral Credits","description":"Referral system rewarding functionality","sidebar":"branch"},"branch/testing":{"id":"branch/testing","title":"Testing","description":"If you\'re going to test, I\'d say testing the following should be a minimum:"},"branch/user-identity":{"id":"branch/user-identity","title":"User Identity","description":"Set Identity","sidebar":"branch"},"braze/add-the-extension":{"id":"braze/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc)."},"braze/analytics":{"id":"braze/analytics","title":"Analytics","description":"Tracking Sessions"},"braze/changelog":{"id":"braze/changelog","title":"changelog","description":"2023.10.09 [v0.1.6]"},"braze/content-cards":{"id":"braze/content-cards","title":"Content Cards","description":""},"braze/deep-linking":{"id":"braze/deep-linking","title":"Deep Linking","description":"Enabling"},"braze/in-app-messaging":{"id":"braze/in-app-messaging","title":"In-App Messaging","description":"In-app messages help you get content to your users without interrupting their day with a push notification. Customized and tailored in-app messages enhance the user experience and help your audience get the most value from your app. With various layouts and customization tools to choose from, in-app messages engage your users more than ever before."},"braze/index":{"id":"braze/index","title":"Braze","description":"The Braze extension"},"braze/integration":{"id":"braze/integration","title":"Integration","description":"Configure your application"},"braze/push-notifications":{"id":"braze/push-notifications","title":"Push Notifications","description":""},"braze/unity":{"id":"braze/unity","title":"Unity","description":"Contents"},"calendar/add-events":{"id":"calendar/add-events","title":"Add Events","description":"Adding an event can be done silently or with a UI allowing the user to fill in additional information.","sidebar":"calendar"},"calendar/add-the-extension":{"id":"calendar/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"calendar"},"calendar/changelog":{"id":"calendar/changelog","title":"changelog","description":"2023.01.16 [v5.1.0]","sidebar":"calendar"},"calendar/get-events":{"id":"calendar/get-events","title":"Get Events","description":"The example below shows retrieving the list of events from yesterday until 2 days in the future.","sidebar":"calendar"},"calendar/index":{"id":"calendar/index","title":"Calendar","description":"This extension gives you the ability to access the user\'s calendar. You can retrieve details on the events,","sidebar":"calendar"},"calendar/migrating-to-androidx":{"id":"calendar/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"calendar"},"calendar/migrating-to-v5.1":{"id":"calendar/migrating-to-v5.1","title":"Migrating to v5.1","description":"v5.1 brings an updated process for requesting permissions on Android.","sidebar":"calendar"},"calendar/request-authorisation":{"id":"calendar/request-authorisation","title":"Request Authorisation","description":"When you are going to be accessing the user\'s calendars you must check that your application has been allowed access. To this end the extension provides several helpers to check and request access to the contact list. Normal permission rules apply here.","sidebar":"calendar"},"camera/add-the-extension":{"id":"camera/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"camera"},"camera/camera-modes":{"id":"camera/camera-modes","title":"Camera Modes","description":"The CameraDevice supports two CameraModes, one for preview frames and another for image capture.","sidebar":"camera"},"camera/capturing-images":{"id":"camera/capturing-images","title":"Capturing Images","description":"There are two parts to image capture, a request and a result.","sidebar":"camera"},"camera/changelog":{"id":"camera/changelog","title":"changelog","description":"2023.09.04 [v6.2.0]","sidebar":"camera"},"camera/connecting":{"id":"camera/connecting","title":"Connecting","description":"Once you have determined the device you wish to use from the CameraDeviceInfo you will","sidebar":"camera"},"camera/index":{"id":"camera/index","title":"Camera","description":"The Camera extension provides access to advanced features of the camera not available through the AIR SDK.","sidebar":"camera"},"camera/migrating-to-androidx":{"id":"camera/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"camera"},"camera/migrating-to-v6.1":{"id":"camera/migrating-to-v6.1","title":"Migrating to v6.1","description":"v6.1 brings an updated process for requesting permissions on Android.","sidebar":"camera"},"camera/parameters-exposure":{"id":"camera/parameters-exposure","title":"Parameters-Exposure","description":"Exposure","sidebar":"camera"},"camera/parameters-flash":{"id":"camera/parameters-flash","title":"Parameters-Flash","description":"Flash","sidebar":"camera"},"camera/parameters-focus":{"id":"camera/parameters-focus","title":"Parameters-Focus","description":"Focus","sidebar":"camera"},"camera/parameters-white-balance":{"id":"camera/parameters-white-balance","title":"Parameters-White Balance","description":"White Balance","sidebar":"camera"},"camera/preview-frames":{"id":"camera/preview-frames","title":"Preview Frames","description":"Preview Frames","sidebar":"camera"},"camera/requesting-authorisation":{"id":"camera/requesting-authorisation","title":"Requesting Authorisation","description":"When you are going to be accessing the camera you must check that your application has been allowed access.","sidebar":"camera"},"camera/selecting-a-device":{"id":"camera/selecting-a-device","title":"Selecting a Device","description":"List Available Devices","sidebar":"camera"},"camerarollextended/add-the-extension":{"id":"camerarollextended/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"camerarollextended"},"camerarollextended/adding-files":{"id":"camerarollextended/adding-files","title":"Adding Images and Video","description":"Adding BitmapData","sidebar":"camerarollextended"},"camerarollextended/browse-for-an-asset":{"id":"camerarollextended/browse-for-an-asset","title":"Browse for an Asset","description":"To ask the user to select an asset (or multiple assets) you will need to call the browseForAsset() function.","sidebar":"camerarollextended"},"camerarollextended/changelog":{"id":"camerarollextended/changelog","title":"changelog","description":"2023.09.16 [v7.0.2]","sidebar":"camerarollextended"},"camerarollextended/file-access":{"id":"camerarollextended/file-access","title":"File Access","description":"Asynchronous Access","sidebar":"camerarollextended"},"camerarollextended/index":{"id":"camerarollextended/index","title":"CameraRollExtended","description":"The CameraRollExtended extension provides functionality for the user to select multiple assets from the device. Additionally you can use this extension to load the selected images from the device and use the loaded BitmapData objects in your application.","sidebar":"camerarollextended"},"camerarollextended/loading-an-asset":{"id":"camerarollextended/loading-an-asset","title":"Loading an Asset","description":"To load an image asset use the loadAsset() function passing an Asset reference and a constructed AssetRequest.","sidebar":"camerarollextended"},"camerarollextended/loading-as-asset---deprecated":{"id":"camerarollextended/loading-as-asset---deprecated","title":"Loading as Asset - Deprecated","description":"Deprecated API"},"camerarollextended/migrating-to-androidx":{"id":"camerarollextended/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"camerarollextended"},"camerarollextended/migrating-to-v6.4":{"id":"camerarollextended/migrating-to-v6.4","title":"Migrating to v6.4","description":"v6.4 brings an updated process for requesting permissions on Android.","sidebar":"camerarollextended"},"camerarollextended/migrating-to-v7.0":{"id":"camerarollextended/migrating-to-v7.0","title":"Migrating to v7.0","description":"v7.0 brings a complete rewrite of the authorisation process for Android. The API remains the same however there is a change to the manifest."},"camerarollextended/request-authorisation":{"id":"camerarollextended/request-authorisation","title":"Request Authorisation","description":"When you are going to be accessing the user\'s media you must check that your application has been allowed access.","sidebar":"camerarollextended"},"cameraui/add-the-extension":{"id":"cameraui/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"cameraui"},"cameraui/camera-ui-options":{"id":"cameraui/camera-ui-options","title":"Camera UI Options","description":"Save To Camera Roll","sidebar":"cameraui"},"cameraui/capture-media":{"id":"cameraui/capture-media","title":"Capture Media","description":"Capture an Image","sidebar":"cameraui"},"cameraui/changelog":{"id":"cameraui/changelog","title":"changelog","description":"2023.02.27 [v3.6.0]","sidebar":"cameraui"},"cameraui/index":{"id":"cameraui/index","title":"CameraUI","description":"The CameraUI extension provides a native user interface for capturing images and videos using the device camera.","sidebar":"cameraui"},"cameraui/migrating-to-androidx":{"id":"cameraui/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"cameraui"},"cameraui/migrating-to-v3.5":{"id":"cameraui/migrating-to-v3.5","title":"Migrating to v3.5","description":"v3.5 brings an updated process for requesting permissions on Android.","sidebar":"cameraui"},"cameraui/requesting-authorisation":{"id":"cameraui/requesting-authorisation","title":"Requesting Authorisation","description":"When you are going to be accessing the camera you must check that your application has been allowed access.","sidebar":"cameraui"},"chartboost/add-the-extension":{"id":"chartboost/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"chartboost"},"chartboost/changelog":{"id":"chartboost/changelog","title":"changelog","description":"2023.11.03 [v1.0.1]","sidebar":"chartboost"},"chartboost/index":{"id":"chartboost/index","title":"Chartboost","description":"The Chartboost extension","sidebar":"chartboost"},"chartboost/initialise":{"id":"chartboost/initialise","title":"Initialise","description":"To initialise the Chartboost SDK call the startWithConfig() method and provide your application configuration.","sidebar":"chartboost"},"chartboost/setup":{"id":"chartboost/setup","title":"Account Setup","description":"Create and set up your Chartboost account.","sidebar":"chartboost"},"cloudstorage/add-the-extension":{"id":"cloudstorage/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"cloudstorage"},"cloudstorage/add-the-plugin":{"id":"cloudstorage/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"cloudstorage"},"cloudstorage/android-testing":{"id":"cloudstorage/android-testing","title":"Android Testing","description":"The implemented backup manager works automatically without user interaction and saves and restores the registered shared preferences associated with the user. Simply change and save shared preferences under the file name which you registered your application with.","sidebar":"cloudstorage"},"cloudstorage/changelog":{"id":"cloudstorage/changelog","title":"changelog","description":"2023.01.17 [v6.1.0]","sidebar":"cloudstorage"},"cloudstorage/document-store":{"id":"cloudstorage/document-store","title":"Document Store","description":"Make sure you have added the entitlements to your application descriptor before attempting to","sidebar":"cloudstorage"},"cloudstorage/index":{"id":"cloudstorage/index","title":"CloudStorage","description":"The Cloud Storage extension","sidebar":"cloudstorage"},"cloudstorage/key-value-storage":{"id":"cloudstorage/key-value-storage","title":"Key-Value Storage","description":"The key-value storage system can be broken down into several main concepts:","sidebar":"cloudstorage"},"cloudstorage/unity":{"id":"cloudstorage/unity","title":"Unity","description":"- Overview"},"compass/add-the-extension":{"id":"compass/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"compass"},"compass/changelog":{"id":"compass/changelog","title":"changelog","description":"2023.01.17 [v4.1.0]","sidebar":"compass"},"compass/heading":{"id":"compass/heading","title":"Heading","description":"Heading Updates","sidebar":"compass"},"compass/index":{"id":"compass/index","title":"Compass","description":"The Compass extension gives access to two important sensor readings, the heading of the device and the magnetometer sensor data","sidebar":"compass"},"compass/magnetic-field-sensor":{"id":"compass/magnetic-field-sensor","title":"Magnetic Field Sensor","description":"The raw magnetic field values can be retrieved using this extension.","sidebar":"compass"},"compass/request-authorisation":{"id":"compass/request-authorisation","title":"Request Authorisation","description":"If you are going to be using the \\"true heading\\" on iOS then you are going to be accessing the user\'s location.","sidebar":"compass"},"contacts/add-the-extension":{"id":"contacts/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"contacts"},"contacts/changelog":{"id":"contacts/changelog","title":"changelog","description":"2023.11.23 [v6.0.1]","sidebar":"contacts"},"contacts/contact-images":{"id":"contacts/contact-images","title":"Contact Images","description":"A contact image is a BitmapData object attached to the Contact instance. There is no size restriction","sidebar":"contacts"},"contacts/contact-picker-ui":{"id":"contacts/contact-picker-ui","title":"Contact Picker UI","description":"This functionality allows you to display a native contact picker UI to allow the user to select a","sidebar":"contacts"},"contacts/index":{"id":"contacts/index","title":"Contacts","description":"The Contacts gives you the ability to access the user\'s contact list. You can retrieve details on a particular contact, get a list of the entire contact list or display a native UI picker to get a user selection. Included in this functionality is all the ability to request the correct iOS permissions.","sidebar":"contacts"},"contacts/migrating-to-androidx":{"id":"contacts/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"contacts"},"contacts/migrating-to-v5.1":{"id":"contacts/migrating-to-v5.1","title":"Migrating to v5.1","description":"v5.1 brings an updated process for requesting permissions on Android.","sidebar":"contacts"},"contacts/request-authorisation":{"id":"contacts/request-authorisation","title":"Request Authorisation","description":"When you are going to be accessing the user\'s contacts you must check that your application has","sidebar":"contacts"},"contacts/retrieving-the-contact-list":{"id":"contacts/retrieving-the-contact-list","title":"Retrieving the Contact List","description":"There are several ways to access the contact list. As the list is quite large and detailed a full","sidebar":"contacts"},"contentprovider/add-the-extension":{"id":"contentprovider/add-the-extension","title":"Add the Extension","description":"First step is always to add the extension to your development environment."},"contentprovider/add-the-plugin":{"id":"contentprovider/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment."},"contentprovider/changelog":{"id":"contentprovider/changelog","title":"changelog","description":"2021.11.29 [v0.1.0]"},"contentprovider/index":{"id":"contentprovider/index","title":"ContentProvider","description":"The ContentProvider extension gives you access to ..."},"contentprovider/unity":{"id":"contentprovider/unity","title":"Unity","description":"Contents"},"core/changelog":{"id":"core/changelog","title":"changelog","description":"2023.09.22 [v7.5.1]"},"debug/add-the-extension":{"id":"debug/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"debug"},"debug/changelog":{"id":"debug/changelog","title":"changelog","description":"2023.03.31 [v3.2.1]","sidebar":"debug"},"debug/index":{"id":"debug/index","title":"Debug","description":"The Debug extension gives you some useful tools to debug your application.","sidebar":"debug"},"debug/usage":{"id":"debug/usage","title":"Usage","description":"Native Logging","sidebar":"debug"},"devicemotion/add-the-extension":{"id":"devicemotion/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"devicemotion"},"devicemotion/algorithms-and-format":{"id":"devicemotion/algorithms-and-format","title":"Algorithms and Format","description":"Algorithm","sidebar":"devicemotion"},"devicemotion/changelog":{"id":"devicemotion/changelog","title":"changelog","description":"2023.01.17 [v4.2.0]","sidebar":"devicemotion"},"devicemotion/index":{"id":"devicemotion/index","title":"DeviceMotion","description":"Device motion is an extension that you can use for getting updates about the position or more precisely the orientation of the device in 3D space.","sidebar":"devicemotion"},"devicemotion/register-for-updates":{"id":"devicemotion/register-for-updates","title":"Register for Updates","description":"Registering for updates forms the core of this extension. The extension works by","sidebar":"devicemotion"},"dialog/action-sheet":{"id":"dialog/action-sheet","title":"Action Sheet","description":"Action sheets display a set of buttons representing several alternative choices to complete a","sidebar":"dialog"},"dialog/activity-dialog":{"id":"dialog/activity-dialog","title":"Activity Dialog","description":"The Activity dialog can be used to indicate some activity or process is occurring to the user.","sidebar":"dialog"},"dialog/add-the-extension":{"id":"dialog/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"dialog"},"dialog/air-fallback":{"id":"dialog/air-fallback","title":"AIR fallback","description":"Some of the dialogs have been giving implementations for use in the AIR simulator.","sidebar":"dialog"},"dialog/alerts":{"id":"dialog/alerts","title":"Alerts","description":"The alert dialog is a modal dialog that can display a title, a message and a series of actions.","sidebar":"dialog"},"dialog/changelog":{"id":"dialog/changelog","title":"changelog","description":"2023.01.17 [v8.7.0]","sidebar":"dialog"},"dialog/custom-picker":{"id":"dialog/custom-picker","title":"Custom Picker","description":"A picker dialog allows you get present a series of \'spinners\' to a user to select multiple values","sidebar":"dialog"},"dialog/date-time-dialog":{"id":"dialog/date-time-dialog","title":"Date Time Dialog","description":"The date/time dialog allows you to request input of a date and/or time from a user. It uses","sidebar":"dialog"},"dialog/dialog-views-and-builders":{"id":"dialog/dialog-views-and-builders","title":"Dialog Views and Builders","description":"Lifetime","sidebar":"dialog"},"dialog/index":{"id":"dialog/index","title":"Dialog","description":"The Dialog extension","sidebar":"dialog"},"dialog/migrating-to-androidx":{"id":"dialog/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"dialog"},"dialog/multi-select":{"id":"dialog/multi-select","title":"Multi Select","description":"A multi select dialog allows you to present a series of options to a user and allow the user to"},"dialog/progress-dialog":{"id":"dialog/progress-dialog","title":"Progress Dialog","description":"A progress dialog can be used to show the progress of a long running process, such as downloading a file.","sidebar":"dialog"},"dialog/text-view-alert":{"id":"dialog/text-view-alert","title":"Text View Alert","description":"The Text View Alert is very similar to the basic Alert with text inputs except it contains","sidebar":"dialog"},"dialog/toast":{"id":"dialog/toast","title":"Toast","description":"Displaying a toast is the simplest alert you can use. A toast is a small message displayed to the","sidebar":"dialog"},"dynamicicon/add-the-extension":{"id":"dynamicicon/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"dynamicicon"},"dynamicicon/adding-icons":{"id":"dynamicicon/adding-icons","title":"Adding Icons","description":"In order to add icons to your application you firstly need to create the icon assets and add them to your application. With Xcode 13 in the recent releases of AIR you can now use icons in an asset catalogue, (the same way as you provide your application icon). Alternatively you can use the legacy method of generating png files and including them in your application.","sidebar":"dynamicicon"},"dynamicicon/change-icon":{"id":"dynamicicon/change-icon","title":"Change Icon","description":"To change the application icon use the setAlternateIconName() function and pass the name of the icon you wish to use.","sidebar":"dynamicicon"},"dynamicicon/changelog":{"id":"dynamicicon/changelog","title":"changelog","description":"2023.01.18 [v1.1.0]","sidebar":"dynamicicon"},"dynamicicon/index":{"id":"dynamicicon/index","title":"DynamicIcon","description":"The DynamicIcon extension","sidebar":"dynamicicon"},"dynamicicon/packaging":{"id":"dynamicicon/packaging","title":"Packaging","description":"In order to change the contents of your IPA after packaging, we need to extract the IPA, change the contents (in particular the Info.plist file) and then importantly package and sign the IPA again.","sidebar":"dynamicicon"},"epos/add-the-extension":{"id":"epos/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc)."},"epos/changelog":{"id":"epos/changelog","title":"changelog","description":"2023.05.22 [v1.1.0]"},"epos/index":{"id":"epos/index","title":"Epos","description":"The Epos extension gives you access to Epson\'s Epos SDK for interacting with printers."},"epos/initialisation":{"id":"epos/initialisation","title":"Initialisation","description":"In order to access a printer you must first initialise an EposPrinter instance via the initPrinterWithOptions() method."},"epos/printing":{"id":"epos/printing","title":"Printing","description":"Once you have created your EposPrinter instance and initiated a connection you can print to the connected device by using a series of commands."},"exceptions/add-the-extension":{"id":"exceptions/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"exceptions"},"exceptions/changelog":{"id":"exceptions/changelog","title":"changelog","description":"2023.01.18 [v3.1.0]","sidebar":"exceptions"},"exceptions/index":{"id":"exceptions/index","title":"Exceptions","description":"Exceptions","sidebar":"exceptions"},"exceptions/usage":{"id":"exceptions/usage","title":"Usage","description":"This extension is very simple in the implementation, having only 2 main functions.","sidebar":"exceptions"},"expansionfiles/add-the-extension":{"id":"expansionfiles/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"expansionfiles"},"expansionfiles/changelog":{"id":"expansionfiles/changelog","title":"changelog","description":"2023.04.26 [v4.2.1]","sidebar":"expansionfiles"},"expansionfiles/downloading-expansion-files":{"id":"expansionfiles/downloading-expansion-files","title":"Downloading Expansion Files","description":"Once you have setup the Expansion Files ANE you should provide information about","sidebar":"expansionfiles"},"expansionfiles/index":{"id":"expansionfiles/index","title":"ExpansionFiles","description":"Please note this extension is still functional however Google has deprecated the expansion files functionality in favour of the newer \\"Play Asset Delivery\\".","sidebar":"expansionfiles"},"expansionfiles/jobb-files":{"id":"expansionfiles/jobb-files","title":"JOBB Files","description":"Creating an OBB file using the JOBB tool","sidebar":"expansionfiles"},"expansionfiles/migrating-to-androidx":{"id":"expansionfiles/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"expansionfiles"},"expansionfiles/migrating-to-v4.2":{"id":"expansionfiles/migrating-to-v4.2","title":"Migrating to v4.2","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"expansionfiles"},"expansionfiles/mounting-an-obb-file":{"id":"expansionfiles/mounting-an-obb-file","title":"Mounting an OBB File","description":"Mounting an OBB file makes the contents you packaged into the file previously","sidebar":"expansionfiles"},"expansionfiles/reading-an-obb-file":{"id":"expansionfiles/reading-an-obb-file","title":"Reading an OBB File","description":"Once you have completed mounting your OBB file, you can then start to read the","sidebar":"expansionfiles"},"expansionfiles/request-authorisation":{"id":"expansionfiles/request-authorisation","title":"Request Authorisation","description":"In order to save the downloaded expansion files you must check that your","sidebar":"expansionfiles"},"expansionfiles/setup-licensing":{"id":"expansionfiles/setup-licensing","title":"Setup Licensing","description":"Before you start adding license verification to your application, you need to set","sidebar":"expansionfiles"},"expansionfiles/uploading-expansion-files":{"id":"expansionfiles/uploading-expansion-files","title":"Uploading Expansion Files","description":"Each time you upload an APK using the Google Play Developer Console, you have the","sidebar":"expansionfiles"},"facebookapi-legacy/account-kit---add-the-extension":{"id":"facebookapi-legacy/account-kit---add-the-extension","title":"Account Kit - Add the Extension","description":"This is the legacy extension documentation. Find the new documentation here"},"facebookapi-legacy/account-kit---deprecation":{"id":"facebookapi-legacy/account-kit---deprecation","title":"Account Kit - Deprecation","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/account-kit---overview":{"id":"facebookapi-legacy/account-kit---overview","title":"Account Kit - Overview","description":"This is the legacy extension documentation. Find the new documentation here"},"facebookapi-legacy/account-kit---setup":{"id":"facebookapi-legacy/account-kit---setup","title":"Account Kit - Setup","description":"This is the legacy extension documentation. Find the new documentation here"},"facebookapi-legacy/account-kit---usage":{"id":"facebookapi-legacy/account-kit---usage","title":"Account Kit - Usage","description":"This is the legacy extension documentation. Find the new documentation here"},"facebookapi-legacy/add-the-extension":{"id":"facebookapi-legacy/add-the-extension","title":"Add the Extension","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/advanced-facebook-settings":{"id":"facebookapi-legacy/advanced-facebook-settings","title":"Advanced Facebook Settings","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/app-events---automatic-logging":{"id":"facebookapi-legacy/app-events---automatic-logging","title":"App Events - Automatic Logging","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/app-events---logging":{"id":"facebookapi-legacy/app-events---logging","title":"App Events - Logging","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/app-events---overview":{"id":"facebookapi-legacy/app-events---overview","title":"App Events - Overview","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/app-events---user-properties":{"id":"facebookapi-legacy/app-events---user-properties","title":"App Events - User Properties","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/app-invites---dialog":{"id":"facebookapi-legacy/app-invites---dialog","title":"App Invites - Dialog","description":"This is the legacy extension documentation. Find the new documentation here"},"facebookapi-legacy/app-links---incoming-links":{"id":"facebookapi-legacy/app-links---incoming-links","title":"App Links - Incoming Links","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/app-links---overview":{"id":"facebookapi-legacy/app-links---overview","title":"App Links - Overview","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/changelog":{"id":"facebookapi-legacy/changelog","title":"changelog","description":"2020.05.08 [v7.1.193]","sidebar":"facebookapi-legacy"},"facebookapi-legacy/facebook-android-app":{"id":"facebookapi-legacy/facebook-android-app","title":"Facebook Android App","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/facebook-application":{"id":"facebookapi-legacy/facebook-application","title":"Facebook Application","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/facebook-ios-app":{"id":"facebookapi-legacy/facebook-ios-app","title":"Facebook iOS App","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/games---game-request-dialog":{"id":"facebookapi-legacy/games---game-request-dialog","title":"Games - Game Request Dialog","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/games---overview":{"id":"facebookapi-legacy/games---overview","title":"Games - Overview","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/graph-api---basics":{"id":"facebookapi-legacy/graph-api---basics","title":"Graph API - Basics","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/graph-api---batch":{"id":"facebookapi-legacy/graph-api---batch","title":"Graph API - Batch","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/graph-api---examples":{"id":"facebookapi-legacy/graph-api---examples","title":"Graph API - Examples","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/graph-api---overview":{"id":"facebookapi-legacy/graph-api---overview","title":"Graph API - Overview","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/index":{"id":"facebookapi-legacy/index","title":"FacebookAPI","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/initialise-facebook-app":{"id":"facebookapi-legacy/initialise-facebook-app","title":"Initialise Facebook App","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/initialise-the-extension":{"id":"facebookapi-legacy/initialise-the-extension","title":"Initialise the Extension","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/login---access-token":{"id":"facebookapi-legacy/login---access-token","title":"Login - Access Token","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/login---facebook-login":{"id":"facebookapi-legacy/login---facebook-login","title":"Login - Facebook Login","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/login---overview":{"id":"facebookapi-legacy/login---overview","title":"Login - Overview","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/migrating-to-androidx":{"id":"facebookapi-legacy/migrating-to-androidx","title":"Migrating to AndroidX","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/sharing---content":{"id":"facebookapi-legacy/sharing---content","title":"Sharing - Content","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/sharing---message-dialog":{"id":"facebookapi-legacy/sharing---message-dialog","title":"Sharing - Message Dialog","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/sharing---open-graph-stories":{"id":"facebookapi-legacy/sharing---open-graph-stories","title":"Sharing - Open Graph Stories","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/sharing---overview":{"id":"facebookapi-legacy/sharing---overview","title":"Sharing - Overview","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/sharing---share-api":{"id":"facebookapi-legacy/sharing---share-api","title":"Sharing - Share API","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi-legacy/sharing---share-dialog":{"id":"facebookapi-legacy/sharing---share-dialog","title":"Sharing - Share Dialog","description":"This is the legacy extension documentation. Find the new documentation here","sidebar":"facebookapi-legacy"},"facebookapi/changelog":{"id":"facebookapi/changelog","title":"changelog","description":"2023.04.04 [v16.0.101]","sidebar":"facebookapi"},"facebookapi/core/add-the-extension":{"id":"facebookapi/core/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"facebookapi"},"facebookapi/core/app-events/automatic-logging":{"id":"facebookapi/core/app-events/automatic-logging","title":"Automatic Logging","description":"When you use the Facebook SDK, certain events in your app are automatically logged and collected for Facebook Analytics unless you disable automatic event logging. These events are relevant for all use cases - targeting, measurement and optimization.","sidebar":"facebookapi"},"facebookapi/core/app-events/logging":{"id":"facebookapi/core/app-events/logging","title":"Logging","description":"App events are the key actions that people take, such as launching your app, viewing content or making a purchase.","sidebar":"facebookapi"},"facebookapi/core/app-events/overview":{"id":"facebookapi/core/app-events/overview","title":"App Events","description":"Facebook Analytics for Apps helps you understand how people are using your desktop","sidebar":"facebookapi"},"facebookapi/core/app-events/user-properties":{"id":"facebookapi/core/app-events/user-properties","title":"User Properties","description":"App events allow you to measure user activity which, combined with Facebook Analytics,","sidebar":"facebookapi"},"facebookapi/core/app-links/handling-incoming-links":{"id":"facebookapi/core/app-links/handling-incoming-links","title":"Handling Incoming Links","description":"When someone taps a link posted from your app or taps the app attribution in an Open Graph story posted from your app in Facebook, they may be presented with the option to open your content in your app. Alternatively, they may be immediately directed to your app.","sidebar":"facebookapi"},"facebookapi/core/app-links/overview":{"id":"facebookapi/core/app-links/overview","title":"App Links","description":"App Links is an open omni-channel solution for deep linking to content in your mobile app","sidebar":"facebookapi"},"facebookapi/core/app-links/support":{"id":"facebookapi/core/app-links/support","title":"Support Incoming Links","description":"When people tap the Open / Play button on the invite or the Is Ready installation notification,","sidebar":"facebookapi"},"facebookapi/core/graph-api/basics":{"id":"facebookapi/core/graph-api/basics","title":"Basics","description":"The Graph API implementation involves several classes. A builder class GraphRequestBuilder","sidebar":"facebookapi"},"facebookapi/core/graph-api/batch":{"id":"facebookapi/core/graph-api/batch","title":"Batch","description":"If you have several requests you wish to batch together you can use the GraphRequestBatchBuilder to create a batch request.","sidebar":"facebookapi"},"facebookapi/core/graph-api/examples":{"id":"facebookapi/core/graph-api/examples","title":"Examples","description":"Some examples of using the Graph API","sidebar":"facebookapi"},"facebookapi/core/graph-api/overview":{"id":"facebookapi/core/graph-api/overview","title":"Graph API","description":"The Graph API is the primary way to get data into and out of the Facebook platform. It\'s an HTTP-based API that apps can use to programmatically query data, post new stories, manage ads, upload photos, and perform a wide variety of other tasks.","sidebar":"facebookapi"},"facebookapi/core/initialise-the-extension":{"id":"facebookapi/core/initialise-the-extension","title":"Initialise the Extension","description":"Core Extension","sidebar":"facebookapi"},"facebookapi/core/overview":{"id":"facebookapi/core/overview","title":"Core","description":"Facebook Core library provides the core components of the Facebook SDK including:","sidebar":"facebookapi"},"facebookapi/gamingservices/add-the-extension":{"id":"facebookapi/gamingservices/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"facebookapi"},"facebookapi/gamingservices/friend-finder-dialog":{"id":"facebookapi/gamingservices/friend-finder-dialog","title":"Friend Finder Dialog","description":"Expand your player base and build community by connecting your players with their Facebook friends. Player Finder lets users find friends to share their gaming experience with. Having more friends playing is associated with higher retention for new players playing top social and turn-based games.","sidebar":"facebookapi"},"facebookapi/gamingservices/game-request-dialog":{"id":"facebookapi/gamingservices/game-request-dialog","title":"Game Request Dialog","description":"Game requests give players a mechanism for inviting their friends to play a game. Requests are sent by a player to one or more friends, and always carry a call-to-action for the game. Recipients can be existing players or new players.","sidebar":"facebookapi"},"facebookapi/gamingservices/overview":{"id":"facebookapi/gamingservices/overview","title":"Gaming Services","description":"Facebook Gaming Services allow game developers to utilize Facebook\u2019s large social audience via the Facebook Login for Gaming, which enables engagement and promotes social features, such as Player Finder, Sharing for Gaming, and Gaming Activity, connecting games to Facebook\u2019s ecosystem. By building game communities, organic player acquisition, engagement and retention increases.","sidebar":"facebookapi"},"facebookapi/get-started":{"id":"facebookapi/get-started","title":"Get Started","description":"The Facebook SDK is the easiest way to integrate your app with Facebook. It enables:","sidebar":"facebookapi"},"facebookapi/index":{"id":"facebookapi/index","title":"FacebookAPI","description":"The FacebookAPI is a series of extensions that allow you to connect users with Facebook and utilise the Facebook SDK features including analytics, login and sharing.","sidebar":"facebookapi"},"facebookapi/login/access-token":{"id":"facebookapi/login/access-token","title":"Access Token","description":"When someone connects with an app using Facebook Login, the app will be able to obtain an access token which provides temporary, secure access to Facebook APIs.","sidebar":"facebookapi"},"facebookapi/login/add-the-extension":{"id":"facebookapi/login/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"facebookapi"},"facebookapi/login/facebook-login":{"id":"facebookapi/login/facebook-login","title":"Facebook Login","description":"In order to log a user in you will be calling the logInWithConfiguration() function and awaiting a login event. This function takes a LoginConfiguration instance as the parameter. The LoginConfiguration allows you to specify the required configuration for the login request, including permissions and login tracking.","sidebar":"facebookapi"},"facebookapi/login/overview":{"id":"facebookapi/login/overview","title":"Login","description":"Facebook Login is a secure, fast and convenient way for people to log into your app .","sidebar":"facebookapi"},"facebookapi/migrating-to-androidx":{"id":"facebookapi/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"facebookapi"},"facebookapi/migrating-to-version-10":{"id":"facebookapi/migrating-to-version-10","title":"Migrating to Version 10","description":"Version 10 of the FacebookAPI brings a major update to version 13 of the Facebook SDK.","sidebar":"facebookapi"},"facebookapi/migrating-to-version-8":{"id":"facebookapi/migrating-to-version-8","title":"Migrating to Version 8","description":"Version 8 of the FacebookAPI brings a complete rewrite and restructure of the API to bring it inline with the latest Facebook SDK and to remove a series of API elements that Facebook have deprecated and removed over time.","sidebar":"facebookapi"},"facebookapi/migrating-to-version-9":{"id":"facebookapi/migrating-to-version-9","title":"Migrating to Version 9","description":"Version 9 of the FacebookAPI brings a major internal update to the iOS SDK.","sidebar":"facebookapi"},"facebookapi/share/add-the-extension":{"id":"facebookapi/share/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"facebookapi"},"facebookapi/share/content":{"id":"facebookapi/share/content","title":"Content","description":"People can share the following kinds of content to Facebook:","sidebar":"facebookapi"},"facebookapi/share/overview":{"id":"facebookapi/share/overview","title":"Sharing - Overview","description":"This guide details how to enable sharing from your app to Facebook. When someone shares from your app, their content appears on their Timeline and may appear in their friends\' News Feeds.","sidebar":"facebookapi"},"facebookapi/share/share-dialog":{"id":"facebookapi/share/share-dialog","title":"Share Dialog","description":"To use the Facebook-built sharing experiences, you want to define your content as in the modeling content section, and then call the Share Dialog.","sidebar":"facebookapi"},"facebookapi/signing":{"id":"facebookapi/signing","title":"iOS Signing","description":"In some circumstances the AIR SDK doesn\'t correctly sign all the packaged frameworks in an application.","sidebar":"facebookapi"},"facebookaudience/changelog":{"id":"facebookaudience/changelog","title":"changelog","description":""},"faqs/error-404":{"id":"faqs/error-404","title":"404 error when accessing repository?","description":"If you have purchased the extension and you are getting a 404 error when browsing to the repository you may have to accept an invitation to our GitHub organisation. This is a step required by GitHub before we can give you access to the private repositories.","sidebar":"faqs"},"faqs/error-context-create":{"id":"faqs/error-context-create","title":"Error: The native extension context could not be created","description":"If you receive an error such as the one above, then most likely the extension has been included but not packaged with your application. You\'ll need to double check the project settings:","sidebar":"faqs"},"faqs/index":{"id":"faqs/index","title":"FAQs","description":"The following are questions that are asked quite often when developing with native extensions. They aren\'t applicable to any extension in particular but are about using our support system or using native extensions in general. For specific tutorials and information on a native extension see the dedicated page for the native extension.","sidebar":"faqs"},"faqs/ld-framework-not-found":{"id":"faqs/ld-framework-not-found","title":"ld: framework not found ...","description":"A very common error you may come across is the one shown below, a linker error:","sidebar":"faqs"},"faqs/ld-unknown-option":{"id":"faqs/ld-unknown-option","title":"ld: unknown option","description":"When packaging an iOS AIR application you may encounter the following error:","sidebar":"faqs"},"faqs/ld-warning":{"id":"faqs/ld-warning","title":"ld: warning","description":"When compiling an iOS AIR mobile application you may encounter errors of the following:","sidebar":"faqs"},"firebase/auth/add-the-extensions":{"id":"firebase/auth/add-the-extensions","title":"Auth - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/auth/initialise":{"id":"firebase/auth/initialise","title":"Auth - Initialise","description":"Authentication State","sidebar":"firebase"},"firebase/auth/introduction":{"id":"firebase/auth/introduction","title":"Auth - Introduction","description":"About","sidebar":"firebase"},"firebase/auth/link-multiple-providers":{"id":"firebase/auth/link-multiple-providers","title":"Auth - Link Multiple Providers","description":"You can allow users to sign in to your app using multiple authentication providers by","sidebar":"firebase"},"firebase/auth/manage-users":{"id":"firebase/auth/manage-users","title":"Auth - Manage Users","description":"If a user has signed in successfully you can get their account data","sidebar":"firebase"},"firebase/auth/provider/anonymous":{"id":"firebase/auth/provider/anonymous","title":"Auth - Provider - Anonymous","description":"The anonymous provider allows you to sign in a user without requiring any credential,","sidebar":"firebase"},"firebase/auth/provider/apple":{"id":"firebase/auth/provider/apple","title":"Auth - Provider - Apple","description":"You can let your users authenticate with Firebase using their Apple ID by using the Firebase SDK and the Apple Sign In extension to carry out the end-to-end OAuth 2.0 sign-in flow.","sidebar":"firebase"},"firebase/auth/provider/custom-auth":{"id":"firebase/auth/provider/custom-auth","title":"Auth - Provider - Custom Auth","description":"You can integrate Firebase Authentication with a custom authentication system by","sidebar":"firebase"},"firebase/auth/provider/email":{"id":"firebase/auth/provider/email","title":"Auth - Provider - Email","description":"The Email/Password provider allows you to sign in a user with an email address and password.","sidebar":"firebase"},"firebase/auth/provider/email-link":{"id":"firebase/auth/provider/email-link","title":"Auth - Provider - Email Link","description":"You can use Firebase Authentication to sign in a user by sending them an email containing a link,","sidebar":"firebase"},"firebase/auth/provider/facebook":{"id":"firebase/auth/provider/facebook","title":"Auth - Provider - Facebook","description":"You can let your users authenticate with Firebase using their Facebook accounts by integrating Facebook Login into your app.","sidebar":"firebase"},"firebase/auth/provider/github":{"id":"firebase/auth/provider/github","title":"Auth - Provider - GitHub","description":"","sidebar":"firebase"},"firebase/auth/provider/google-identity":{"id":"firebase/auth/provider/google-identity","title":"Auth - Provider - Google Identity","description":"You can let your users authenticate with Firebase using their Google Accounts by integrating Google Sign-In into your app.","sidebar":"firebase"},"firebase/auth/provider/microsoft":{"id":"firebase/auth/provider/microsoft","title":"Auth - Provider - Microsoft","description":"You can let your users authenticate with Firebase using OAuth providers like Microsoft Azure Active Directory by integrating web-based generic OAuth Login into your app using the Firebase SDK to carry out the end to end sign-in flow.","sidebar":"firebase"},"firebase/auth/provider/phone":{"id":"firebase/auth/provider/phone","title":"Auth - Provider - Phone","description":"You can use Firebase Authentication to sign in a user by sending an SMS message to the user\'s phone.","sidebar":"firebase"},"firebase/auth/provider/twitter":{"id":"firebase/auth/provider/twitter","title":"Auth - Provider - Twitter","description":"","sidebar":"firebase"},"firebase/changelog":{"id":"firebase/changelog","title":"changelog","description":"2023.07.13 [v8.0.1]","sidebar":"firebase"},"firebase/core/add-the-extensions":{"id":"firebase/core/add-the-extensions","title":"Core - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/core/analytics":{"id":"firebase/core/analytics","title":"Core - Analytics","description":"Once you have configured the core Firebase project you can use the analytics features in your AIR application.","sidebar":"firebase"},"firebase/core/initialise":{"id":"firebase/core/initialise","title":"Core - Initialise","description":"Application Configuration","sidebar":"firebase"},"firebase/core/introduction":{"id":"firebase/core/introduction","title":"Core - Introduction","description":"About","sidebar":"firebase"},"firebase/crash/add-the-extensions":{"id":"firebase/crash/add-the-extensions","title":"Crash - Add the extensions","description":"DEPRECATED"},"firebase/crash/introduction":{"id":"firebase/crash/introduction","title":"Crash - Introduction","description":"DEPRECATED"},"firebase/crash/usage":{"id":"firebase/crash/usage","title":"Crash - Usage","description":"DEPRECATED"},"firebase/crashlytics/add-the-extension":{"id":"firebase/crashlytics/add-the-extension","title":"Crashlytics - Add the extension","description":"The recent releases of the Crashlytics extension requires at least version 33.1.1.345 of the AIR SDK. Using anything less than this will mean you will not get crash reports delivered to the console on iOS!","sidebar":"firebase"},"firebase/crashlytics/introduction":{"id":"firebase/crashlytics/introduction","title":"Crashlytics - Introduction","description":"Get clear, actionable insight into app issues with this powerful crash reporting solution for Android and iOS.","sidebar":"firebase"},"firebase/crashlytics/testing":{"id":"firebase/crashlytics/testing","title":"Crashlytics - Testing","description":"Test your Firebase Crashlytics implementation","sidebar":"firebase"},"firebase/crashlytics/uploading-dsyms":{"id":"firebase/crashlytics/uploading-dsyms","title":"Crashlytics - Uploading dSYMs","description":"On Android your crash logs will appear in the dashboard in around 5 minutes however you will not see your iOS logs unless you upload the debugging information file generated for your iOS IPA.","sidebar":"firebase"},"firebase/crashlytics/usage":{"id":"firebase/crashlytics/usage","title":"Crashlytics - Usage","description":"Usage","sidebar":"firebase"},"firebase/database/add-the-extensions":{"id":"firebase/database/add-the-extensions","title":"Database - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/database/configure-database-rules":{"id":"firebase/database/configure-database-rules","title":"Database - Configure Database Rules","description":"Configure Firebase Database Rules","sidebar":"firebase"},"firebase/database/delete-data":{"id":"firebase/database/delete-data","title":"Database - Delete Data","description":"Delete Data","sidebar":"firebase"},"firebase/database/disconnect":{"id":"firebase/database/disconnect","title":"Database - Disconnect","description":"On Disconnect","sidebar":"firebase"},"firebase/database/initialise":{"id":"firebase/database/initialise","title":"Database - Initialise","description":"","sidebar":"firebase"},"firebase/database/introduction":{"id":"firebase/database/introduction","title":"Database - Introduction","description":"Realtime Database","sidebar":"firebase"},"firebase/database/lists":{"id":"firebase/database/lists","title":"Database - Lists","description":"Working with Lists of Data","sidebar":"firebase"},"firebase/database/offline":{"id":"firebase/database/offline","title":"Database - Offline","description":"Write data offline","sidebar":"firebase"},"firebase/database/read-data-and-change-events":{"id":"firebase/database/read-data-and-change-events","title":"Database - Read Data and Change Events","description":"Reading Data and Listening to Value Change events","sidebar":"firebase"},"firebase/database/transactions":{"id":"firebase/database/transactions","title":"Database - Transactions","description":"Transactions","sidebar":"firebase"},"firebase/database/write-data":{"id":"firebase/database/write-data","title":"Database - Write Data","description":"Get a DatabaseReference","sidebar":"firebase"},"firebase/dynamiclinks/add-the-extension":{"id":"firebase/dynamiclinks/add-the-extension","title":"DynamicLinks - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/dynamiclinks/create-dynamic-links":{"id":"firebase/dynamiclinks/create-dynamic-links","title":"DynamicLinks - Create Dynamic Links","description":"Create Dynamic Links","sidebar":"firebase"},"firebase/dynamiclinks/initialise":{"id":"firebase/dynamiclinks/initialise","title":"DynamicLinks - Initialise","description":"Setting Scheme","sidebar":"firebase"},"firebase/dynamiclinks/introduction":{"id":"firebase/dynamiclinks/introduction","title":"DynamicLinks - Introduction","description":"Dynamic Links are links that work the way you want, on multiple platforms, and whether or not your app is already installed.","sidebar":"firebase"},"firebase/dynamiclinks/receive-dynamic-links":{"id":"firebase/dynamiclinks/receive-dynamic-links","title":"DynamicLinks - Receive Dynamic Links","description":"Receive Dynamic Links","sidebar":"firebase"},"firebase/dynamiclinks/testing":{"id":"firebase/dynamiclinks/testing","title":"DynamicLinks - Testing","description":"Android","sidebar":"firebase"},"firebase/fcm/introduction":{"id":"firebase/fcm/introduction","title":"FCM - Introduction","description":"Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost.","sidebar":"firebase"},"firebase/firestore/add-data":{"id":"firebase/firestore/add-data","title":"Firestore - Add Data","description":"Add data","sidebar":"firebase"},"firebase/firestore/add-the-extension":{"id":"firebase/firestore/add-the-extension","title":"Firestore - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/firestore/delete-data":{"id":"firebase/firestore/delete-data","title":"Firestore - Delete data","description":"Delete documents","sidebar":"firebase"},"firebase/firestore/enable-offline-data":{"id":"firebase/firestore/enable-offline-data","title":"Firestore - Enable offline data","description":"Cloud Firestore supports offline data persistence. This feature caches a copy of the Cloud Firestore data that your app is actively using, so your app can access the data when the device is offline. You can write, read, listen to, and query the cached data. When the device comes back online, Cloud Firestore synchronizes any local changes made by your app to the data stored remotely in Cloud Firestore.","sidebar":"firebase"},"firebase/firestore/get-data":{"id":"firebase/firestore/get-data","title":"Firestore - Get data","description":"There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries:","sidebar":"firebase"},"firebase/firestore/get-realtime-updates":{"id":"firebase/firestore/get-realtime-updates","title":"Firestore - Get realtime updates","description":"You can listen to document updates by adding a listener for the DocumentReference.SNAPSHOT_EVENT or by calling the addSnapshotListener() method.","sidebar":"firebase"},"firebase/firestore/introduction":{"id":"firebase/firestore/introduction","title":"Firestore - Introduction","description":"Cloud Firestore","sidebar":"firebase"},"firebase/firestore/order-and-limit-data":{"id":"firebase/firestore/order-and-limit-data","title":"Firestore - Order and limit data","description":"Cloud Firestore provides powerful query functionality for specifying which documents you want to retrieve from a collection. These queries can also be used with either query() or addSnapshotListener(), as described in Get Data.","sidebar":"firebase"},"firebase/firestore/paginate-data-with-query-cursors":{"id":"firebase/firestore/paginate-data-with-query-cursors","title":"Firestore - Paginate data with query cursors","description":"With query cursors in Cloud Firestore, you can split data returned by a query into batches according to the parameters you define in your query.","sidebar":"firebase"},"firebase/firestore/perform-simple-and-compound-queries":{"id":"firebase/firestore/perform-simple-and-compound-queries","title":"Firestore - Perform simple and compound queries","description":"Cloud Firestore provides powerful query functionality for specifying which documents you want to retrieve from a collection. These queries can also be used with either query() or addSnapshotListener(), as described in Get Data and Get Realtime Updates.","sidebar":"firebase"},"firebase/firestore/transactions-and-batched-writes":{"id":"firebase/firestore/transactions-and-batched-writes","title":"Firestore - Transactions and batched writes","description":"Cloud Firestore supports atomic operations for reading and writing data. In a set of atomic operations, either all of the operations succeed, or none of them are applied. There are two types of atomic operations in Cloud Firestore:","sidebar":"firebase"},"firebase/index":{"id":"firebase/index","title":"Firebase","description":"The Firebase platform forms one of the biggest","sidebar":"firebase"},"firebase/invites/add-the-extension":{"id":"firebase/invites/add-the-extension","title":"Invites - Add the extension","description":"DEPRECATED"},"firebase/invites/dynamic-links":{"id":"firebase/invites/dynamic-links","title":"Invites - Dynamic Links","description":"DEPRECATED"},"firebase/invites/initialise":{"id":"firebase/invites/initialise","title":"Invites - Initialise","description":"DEPRECATED"},"firebase/invites/introduction":{"id":"firebase/invites/introduction","title":"Invites - Introduction","description":"DEPRECATED"},"firebase/invites/invitations":{"id":"firebase/invites/invitations","title":"Invites - Invitations","description":"DEPRECATED"},"firebase/migrating-to-v4":{"id":"firebase/migrating-to-v4","title":"Migrating to v4","description":"Version 4 brings a major update of the Firebase extensions and with it a series of changes.","sidebar":"firebase"},"firebase/migrating-to-v6":{"id":"firebase/migrating-to-v6","title":"Migrating to v6","description":"Version 6 brings a major update of the Firebase extensions and with it a series of changes.","sidebar":"firebase"},"firebase/performance/add-the-extension":{"id":"firebase/performance/add-the-extension","title":"Performance - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/performance/disable-monitoring":{"id":"firebase/performance/disable-monitoring","title":"Performance - Disable Monitoring","description":"Disable the Firebase Performance Monitoring","sidebar":"firebase"},"firebase/performance/introduction":{"id":"firebase/performance/introduction","title":"Performance - Introduction","description":"Gain insight into your app\'s performance issues","sidebar":"firebase"},"firebase/performance/traces":{"id":"firebase/performance/traces","title":"Performance - Traces","description":"Automatic Traces","sidebar":"firebase"},"firebase/remoteconfig/add-the-extensions":{"id":"firebase/remoteconfig/add-the-extensions","title":"RemoteConfig - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/remoteconfig/initialise":{"id":"firebase/remoteconfig/initialise","title":"RemoteConfig - Initialise","description":"","sidebar":"firebase"},"firebase/remoteconfig/introduction":{"id":"firebase/remoteconfig/introduction","title":"RemoteConfig - Introduction","description":"Remote Config","sidebar":"firebase"},"firebase/remoteconfig/set-initial-values":{"id":"firebase/remoteconfig/set-initial-values","title":"RemoteConfig - Set Initial Values","description":"Set Initial Values","sidebar":"firebase"},"firebase/remoteconfig/usage":{"id":"firebase/remoteconfig/usage","title":"RemoteConfig - Usage","description":"You can use Firebase Remote Config to define parameters in your app and update their values in the cloud, allowing you to modify the appearance and behavior of your app without distributing an app update. This guide shows you how to use Remote Config in your app, following these steps:","sidebar":"firebase"},"firebase/setup/configuration-files":{"id":"firebase/setup/configuration-files","title":"Setup - Configuration Files","description":"There are two ways to configure an application.","sidebar":"firebase"},"firebase/setup/create-a-firebase-project":{"id":"firebase/setup/create-a-firebase-project","title":"Setup - Create a Firebase Project","description":"It\'s time to add Firebase to your app. To do this you\'ll need a Firebase project and a Firebase configuration file for your app.","sidebar":"firebase"},"firebase/storage/add-the-extensions":{"id":"firebase/storage/add-the-extensions","title":"Storage - Add the extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"firebase"},"firebase/storage/delete-files":{"id":"firebase/storage/delete-files","title":"Storage - Delete Files","description":"Delete Files","sidebar":"firebase"},"firebase/storage/download-files":{"id":"firebase/storage/download-files","title":"Storage - Download Files","description":"Download Files","sidebar":"firebase"},"firebase/storage/file-metadata":{"id":"firebase/storage/file-metadata","title":"Storage - File Metadata","description":"File Metadata","sidebar":"firebase"},"firebase/storage/introduction":{"id":"firebase/storage/introduction","title":"Storage - Introduction","description":"Storage","sidebar":"firebase"},"firebase/storage/list-files":{"id":"firebase/storage/list-files","title":"Storage - List Files","description":"Cloud Storage for Firebase allows you to list the contents of your Cloud Storage bucket. The SDKs return both the items and the prefixes of objects under the current Cloud Storage reference.","sidebar":"firebase"},"firebase/storage/references":{"id":"firebase/storage/references","title":"Storage - References","description":"Storage Reference","sidebar":"firebase"},"firebase/storage/upload-files":{"id":"firebase/storage/upload-files","title":"Storage - Upload Files","description":"Upload Files","sidebar":"firebase"},"flurry/add-the-extension":{"id":"flurry/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"flurry"},"flurry/analytics-events":{"id":"flurry/analytics-events","title":"Analytics Events","description":"Logging events is as simple as calling the logEvent function with an event name and an object","sidebar":"flurry"},"flurry/analytics-sessions":{"id":"flurry/analytics-sessions","title":"Analytics Sessions","description":"A session represents a single use of the application, so you should start and end a","sidebar":"flurry"},"flurry/analytics-standard-events":{"id":"flurry/analytics-standard-events","title":"Analytics Standard Events","description":"Events track standardized actions that users take within your app \u2013 for example, making a purchase, adding a social comment, or clicking on an Ad. This helps you understand how users interact with your app.","sidebar":"flurry"},"flurry/changelog":{"id":"flurry/changelog","title":"changelog","description":"2023.01.18 [v7.1.0]","sidebar":"flurry"},"flurry/index":{"id":"flurry/index","title":"Flurry","description":"This extension gives you the ability to access the Access to the Flurry Analytics service from Yahoo (https://developer.yahoo.com/analytics/).","sidebar":"flurry"},"flurry/initialise-the-extension":{"id":"flurry/initialise-the-extension","title":"Initialise the Extension","description":"To use the analytics service you must pass in your Flurry keys that you created through the Flurry website and a configuration instance to set various configuration options (FlurryAnalyticsConfig).","sidebar":"flurry"},"flurry/migrating-to-v6":{"id":"flurry/migrating-to-v6","title":"Migrating to v6.0","description":"v6.0 brings the current release of Flurry (as at April 2021):","sidebar":"flurry"},"flurry/user-properties":{"id":"flurry/user-properties","title":"User Properties","description":"User Properties allow you to label your users based on preferences, behaviors or attributes unique to your app.","sidebar":"flurry"},"forcetouch/add-the-extension":{"id":"forcetouch/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"forcetouch"},"forcetouch/app-shortcuts":{"id":"forcetouch/app-shortcuts","title":"App Shortcuts","description":"Application Shortcuts","sidebar":"forcetouch"},"forcetouch/changelog":{"id":"forcetouch/changelog","title":"changelog","description":"2023.01.18 [v3.2.0]","sidebar":"forcetouch"},"forcetouch/force-touch-events":{"id":"forcetouch/force-touch-events","title":"Force Touch Events","description":"Listening for Events","sidebar":"forcetouch"},"forcetouch/index":{"id":"forcetouch/index","title":"ForceTouch","description":"The Force Touch","sidebar":"forcetouch"},"gameservices/access-point":{"id":"gameservices/access-point","title":"Access Point","description":"Access Point","sidebar":"gameservices"},"gameservices/achievements":{"id":"gameservices/achievements","title":"Achievements","description":"Achievements can be a great way to increase your users\' engagement within your game. You can implement achievements in your game to encourage players to experiment with features they might not normally use, or to approach your game with entirely different play styles. Achievements can also be a fun way for players to compare their progress with each other and engage in light-hearted competition.","sidebar":"gameservices"},"gameservices/auth-utilities":{"id":"gameservices/auth-utilities","title":"Auth Utilities","description":"AuthUtil provides static utility methods to:"},"gameservices/changelog":{"id":"gameservices/changelog","title":"changelog","description":"2023.08.17 [v8.3.0]","sidebar":"gameservices"},"gameservices/index":{"id":"gameservices/index","title":"GameServices","description":"The GameServices extension allows developers to use a single cross-platform API to interface with many different gaming platforms.","sidebar":"gameservices"},"gameservices/initialise-the-service":{"id":"gameservices/initialise-the-service","title":"Initialise the Service","description":"This step initialises the platform using your game service settings. Initialising the service performs serveral things, notably:","sidebar":"gameservices"},"gameservices/leaderboards":{"id":"gameservices/leaderboards","title":"Leaderboards","description":"Leaderboards can be a fun way to drive competition among your players, both for your most hardcore fans (who will be fighting for the top spot in a public leaderboard) and for your more casual players (who will be interested in comparing their progress to their friends\').","sidebar":"gameservices"},"gameservices/migrating-to-androidx":{"id":"gameservices/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"gameservices"},"gameservices/quests-and-events":{"id":"gameservices/quests-and-events","title":"Quests and Events","description":"Quests have been deprecated in Google Play Games. This functionality has been removed from the Play Games service so currently no services support Quests.","sidebar":"gameservices"},"gameservices/saved-games":{"id":"gameservices/saved-games","title":"Saved Games","description":"The Saved Games service gives you a convenient way to save your players\' game progression to the game","sidebar":"gameservices"},"gameservices/saved-games---conflicts":{"id":"gameservices/saved-games---conflicts","title":"Saved Games - Conflicts","description":"Detecting Conflicts","sidebar":"gameservices"},"gameservices/screen-recording":{"id":"gameservices/screen-recording","title":"Screen Recording","description":"You can use the screen recording functionality to easily add video recording to your games and let users share their videos with friends.","sidebar":"gameservices"},"gameservices/service/gamecenter/add-the-extension":{"id":"gameservices/service/gamecenter/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"gameservices"},"gameservices/service/gamecenter/setup":{"id":"gameservices/service/gamecenter/setup","title":"GameCenter","description":"Game Center is setup through your iTunes Connect account at two levels, the app level and the app version level.","sidebar":"gameservices"},"gameservices/service/gamecenter/troubleshooting":{"id":"gameservices/service/gamecenter/troubleshooting","title":"Troubleshooting","description":"","sidebar":"gameservices"},"gameservices/service/huawei/add-the-extension":{"id":"gameservices/service/huawei/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"gameservices"},"gameservices/service/huawei/setup":{"id":"gameservices/service/huawei/setup","title":"Huawei Game Services","description":"With Game Service, you will have access to a range of development capabilities. You can promote your game quickly and efficiently to Huawei\'s vast user base by having users sign in using their HUAWEI IDs. You can also use the service to quickly implement functions such as achievements, leaderboards and game addiction prevention.","sidebar":"gameservices"},"gameservices/service/huawei/troubleshooting":{"id":"gameservices/service/huawei/troubleshooting","title":"Troubleshooting","description":"","sidebar":"gameservices"},"gameservices/service/playgames/add-the-extension":{"id":"gameservices/service/playgames/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"gameservices"},"gameservices/service/playgames/setup":{"id":"gameservices/service/playgames/setup","title":"Google Play Games","description":"You must setup your application for Play Services, the following guide will help you through that.","sidebar":"gameservices"},"gameservices/service/playgames/troubleshooting":{"id":"gameservices/service/playgames/troubleshooting","title":"Troubleshooting","description":"This is a list of common errors encountered in using the Game Services and possible resolutions.","sidebar":"gameservices"},"gameservices/sign-in":{"id":"gameservices/sign-in","title":"Sign In","description":"The following code demonstrates how to initiate a player sign in. You should perform the sign in","sidebar":"gameservices"},"gameservices/troubleshooting":{"id":"gameservices/troubleshooting","title":"Troubleshooting","description":"See the following service specific documentation for a list of common errors encountered in using Game Services and possible resolutions.","sidebar":"gameservices"},"gameservices/turn-based-multiplayer---implementation":{"id":"gameservices/turn-based-multiplayer---implementation","title":"Turn Based Multiplayer - Implementation","description":"Sections:","sidebar":"gameservices"},"gameservices/turn-based-multiplayer---implementation-overview":{"id":"gameservices/turn-based-multiplayer---implementation-overview","title":"Turn Based Multiplayer - Implementation Overview","description":"Overview","sidebar":"gameservices"},"gameservices/turn-based-multiplayer---invitations":{"id":"gameservices/turn-based-multiplayer---invitations","title":"Turn Based Multiplayer - Invitations","description":"Invitations are received when the player is invited to play a multiplayer game.","sidebar":"gameservices"},"gameservices/turn-based-multiplayer---key-concepts":{"id":"gameservices/turn-based-multiplayer---key-concepts","title":"Turn Based Multiplayer - Key Concepts","description":"Starting on March 31, 2020, Google have ended support for real-time and turn-based multiplayer APIs.","sidebar":"gameservices"},"gameservices/user-interface":{"id":"gameservices/user-interface","title":"UI Elements","description":"There are several user interface elements you can use. Some of these can be accessed from other parts of the API eg:","sidebar":"gameservices"},"googleanalytics/add-the-extension":{"id":"googleanalytics/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"googleanalytics"},"googleanalytics/changelog":{"id":"googleanalytics/changelog","title":"changelog","description":"2023.01.20 [v4.2.0]","sidebar":"googleanalytics"},"googleanalytics/create-a-tracker":{"id":"googleanalytics/create-a-tracker","title":"Create a Tracker","description":"Creating and retrieving a Tracker use the same piece of code as shown below:","sidebar":"googleanalytics"},"googleanalytics/ecommerce":{"id":"googleanalytics/ecommerce","title":"Ecommerce","description":"Warning: Ecommerce SDK is deprecated. You still can use this functionality however it is suggested to use Enhanced Ecommerce.","sidebar":"googleanalytics"},"googleanalytics/enhanced-ecommerce":{"id":"googleanalytics/enhanced-ecommerce","title":"Enhanced Ecommerce","description":"Enhanced ecommerce enables the measurement of user interactions with products across the user\'s shopping experience, which include product impressions, product clicks, viewing product details, adding a product to a shopping cart, initiating the checkout process, transactions, and refunds.","sidebar":"googleanalytics"},"googleanalytics/index":{"id":"googleanalytics/index","title":"GoogleAnalytics","description":"GoogleAnalytics is an AIR Native Extension to enable the use of Google Analytics in your application to measure user activity.","sidebar":"googleanalytics"},"googleanalytics/install-referrer":{"id":"googleanalytics/install-referrer","title":"Install Referrer","description":"You can use the install referrer to see which campaigns, websites,","sidebar":"googleanalytics"},"googleanalytics/migrating-to-androidx":{"id":"googleanalytics/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"googleanalytics"},"googleanalytics/notes":{"id":"googleanalytics/notes","title":"Notes","description":"Dashboard","sidebar":"googleanalytics"},"googleanalytics/sending-hits-and-events":{"id":"googleanalytics/sending-hits-and-events","title":"Sending Hits and Events","description":"Sending a Screen View Hit","sidebar":"googleanalytics"},"googleanalytics/tracking-ids":{"id":"googleanalytics/tracking-ids","title":"Tracking IDs","description":"Now that Google are encouraging mobile to use Firebase the process of creating tracking ids for use only with Google Analytics in mobile applications is slightly confusing.","sidebar":"googleanalytics"},"googleidentity/add-the-extension":{"id":"googleidentity/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"googleidentity"},"googleidentity/android-certificate":{"id":"googleidentity/android-certificate","title":"Android Certificate","description":"This is where most people will run into issues getting this extension to work and signing in users.","sidebar":"googleidentity"},"googleidentity/authenticate-with-a-backend-server":{"id":"googleidentity/authenticate-with-a-backend-server","title":"Authenticate with a backend server","description":"If you use Google Sign-In with an app or site that communicates with a backend server, you might need to identify the currently signed-in user on the server. To do so securely, after a user successfully signs in, send the user\'s ID token to your server using HTTPS. Then, on the server, verify the integrity of the ID token and use the user information contained in the token to establish a session or create a new account.","sidebar":"googleidentity"},"googleidentity/changelog":{"id":"googleidentity/changelog","title":"changelog","description":"2023.07.05 [v5.5.0]","sidebar":"googleidentity"},"googleidentity/disconnect":{"id":"googleidentity/disconnect","title":"Disconnect","description":"Google\'s developer policies also require you to","sidebar":"googleidentity"},"googleidentity/enabling-server-side-access":{"id":"googleidentity/enabling-server-side-access","title":"Enabling Server-Side Access","description":"With the Sign-In procedure, your app authenticates the user on the client side only; in that case, you can access the Google APIs only while the user is actively using your app. If you want your servers to be able to make Google API calls on behalf of users\u2014possibly while they are offline\u2014your server requires an access token.","sidebar":"googleidentity"},"googleidentity/google-developers-console-project":{"id":"googleidentity/google-developers-console-project","title":"Google Developers Console project","description":"Firstly before setting up any console projects make sure you check if your Android application","sidebar":"googleidentity"},"googleidentity/google-identity-options":{"id":"googleidentity/google-identity-options","title":"Google Identity Options","description":"This shows you where to gather the information required for the Google Identity options you will use to initialise the extension.","sidebar":"googleidentity"},"googleidentity/index":{"id":"googleidentity/index","title":"GoogleIdentity","description":"The Google Identity extension","sidebar":"googleidentity"},"googleidentity/migrating-from-version-1":{"id":"googleidentity/migrating-from-version-1","title":"Migrating from version 1","description":"Version 2 brings the latest Google Identity Sign In SDK and with it some changes to the API.","sidebar":"googleidentity"},"googleidentity/migrating-to-androidx":{"id":"googleidentity/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"googleidentity"},"googleidentity/setup":{"id":"googleidentity/setup","title":"Setup","description":"Setup the extension","sidebar":"googleidentity"},"googleidentity/signing-in":{"id":"googleidentity/signing-in","title":"Signing In","description":"Signing in and out is a simple process of adding a series of listeners and then calling the","sidebar":"googleidentity"},"googleidentity/troubleshooting":{"id":"googleidentity/troubleshooting","title":"Troubleshooting","description":"Common Issues","sidebar":"googleidentity"},"googleidentity/user-information":{"id":"googleidentity/user-information","title":"User Information","description":"When your user is successfully signed in you will receive their information as part","sidebar":"googleidentity"},"googletagmanager/add-the-extension":{"id":"googletagmanager/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"googletagmanager"},"googletagmanager/changelog":{"id":"googletagmanager/changelog","title":"changelog","description":"2023.09.08 [v5.0.2]","sidebar":"googletagmanager"},"googletagmanager/google-tag-manager-setup":{"id":"googletagmanager/google-tag-manager-setup","title":"Google Tag Manager Setup","description":"Prerequisites","sidebar":"googletagmanager"},"googletagmanager/index":{"id":"googletagmanager/index","title":"GoogleTagManager","description":"The Google Tag Manager extension gives you the ability to use the Google Tag Manager analytics in your AIR application.","sidebar":"googletagmanager"},"googletagmanager/legacy/containers":{"id":"googletagmanager/legacy/containers","title":"Containers","description":"This documentation is for the legacy SDK and is no longer supported.","sidebar":"googletagmanager"},"googletagmanager/legacy/datalayer":{"id":"googletagmanager/legacy/datalayer","title":"DataLayer","description":"This documentation is for the legacy SDK and is no longer supported.","sidebar":"googletagmanager"},"googletagmanager/log-events":{"id":"googletagmanager/log-events","title":"Log events and variables","description":"Tag Manager uses events, parameters, and user properties logged by the Google Analytics for Firebase SDK to trigger and build tags you\'ve configured in Google Tag Manager.","sidebar":"googletagmanager"},"gyroscope/add-the-extension":{"id":"gyroscope/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"gyroscope"},"gyroscope/changelog":{"id":"gyroscope/changelog","title":"changelog","description":"2023.01.20 [v3.2.0]","sidebar":"gyroscope"},"gyroscope/index":{"id":"gyroscope/index","title":"Gyroscope","description":"The Gyroscope","sidebar":"gyroscope"},"gyroscope/sensor-updates":{"id":"gyroscope/sensor-updates","title":"Sensor Updates","description":"Listening for Sensor Updates","sidebar":"gyroscope"},"health/add-the-extension":{"id":"health/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"health"},"health/add-the-plugin":{"id":"health/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment."},"health/authorisation":{"id":"health/authorisation","title":"Authorisation","description":"Request Authorisation","sidebar":"health"},"health/changelog":{"id":"health/changelog","title":"changelog","description":"2023.10.13 [v1.5.0]","sidebar":"health"},"health/check-for-updates":{"id":"health/check-for-updates","title":"Availablility & Updates","description":"This is required on Android Health Connect but can be skipped if you are developing for iOS only.","sidebar":"health"},"health/index":{"id":"health/index","title":"Health","description":"The Health extension gives you access to the user\'s health data on a device, such as steps taken.","sidebar":"health"},"health/queries":{"id":"health/queries","title":"Querying Data","description":"To query data you will create a StatisticsQuery and then pass it to the execute() method. This will query the data specified and when complete call a callback function with the result.","sidebar":"health"},"health/setup":{"id":"health/setup","title":"Setup","description":"Initialise","sidebar":"health"},"idfa/add-the-extension":{"id":"idfa/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"idfa"},"idfa/changelog":{"id":"idfa/changelog","title":"changelog","description":"2023.01.18 [v5.2.0]","sidebar":"idfa"},"idfa/get-advertising-identifier":{"id":"idfa/get-advertising-identifier","title":"Get Advertising Identifier","description":"Authorisation","sidebar":"idfa"},"idfa/index":{"id":"idfa/index","title":"IDFA","description":"This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:","sidebar":"idfa"},"idfa/migrating":{"id":"idfa/migrating","title":"Migrating","description":"Version 5","sidebar":"idfa"},"idfa/migrating-to-androidx":{"id":"idfa/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"idfa"},"image/add-the-extension":{"id":"image/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"image"},"image/capturing-a-screenshot":{"id":"image/capturing-a-screenshot","title":"Capturing a Screenshot","description":"You can use this extension to capture a screenshot of your application as bitmap data and subsequently use that data as you require.","sidebar":"image"},"image/changelog":{"id":"image/changelog","title":"changelog","description":"2023.01.18 [v5.2.0]","sidebar":"image"},"image/decoding-bytearray-to-bitmapdata":{"id":"image/decoding-bytearray-to-bitmapdata","title":"Decoding ByteArray to BitmapData","description":"This process is the opposite of the encode function. It allows you to decode","sidebar":"image"},"image/encoding-bitmapdata-to-bytearray":{"id":"image/encoding-bitmapdata-to-bytearray","title":"Encoding BitmapData to ByteArray","description":"This process is the allows you to encode image data into encoded image bytes.","sidebar":"image"},"image/index":{"id":"image/index","title":"Image","description":"The Image extension","sidebar":"image"},"image/loading-bitmapdata-from-file":{"id":"image/loading-bitmapdata-from-file","title":"Loading BitmapData from File","description":"This process is the reverse of saving bitmap data, where it will load a PNG or JPG","sidebar":"image"},"image/migrating-to-androidx":{"id":"image/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"image"},"image/migrating-to-v5.2":{"id":"image/migrating-to-v5.2","title":"Migrating to v5.2","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"image"},"image/request-authorisation":{"id":"image/request-authorisation","title":"Authorisation","description":"This functionality has been deprecated and will be removed in an upcoming release.","sidebar":"image"},"image/saving-bitmapdata-to-file":{"id":"image/saving-bitmapdata-to-file","title":"Saving BitmapData to File","description":"Encoding bitmap data to a file can be a slow process when using AS3 operations.","sidebar":"image"},"image/saving-bitmapdata-to-the-camera-roll":{"id":"image/saving-bitmapdata-to-the-camera-roll","title":"Saving BitmapData to the Camera Roll","description":"This functionality has been deprecated and will be removed in an upcoming release.","sidebar":"image"},"image/transformations":{"id":"image/transformations","title":"Transformations","description":"You can apply transformations to BitmapData by using the transformAsync function to return BitmapData or the transformAndSaveAsync function to save to a file.","sidebar":"image"},"inappbilling/add-the-extension":{"id":"inappbilling/add-the-extension","title":"Add the Extension","description":"Here we will show you how to add the extension to your development environment and make the necessary changes to your application descriptor to correctly support the extension.","sidebar":"inappbilling"},"inappbilling/amazon/add-the-extension":{"id":"inappbilling/amazon/add-the-extension","title":"Amazon In-App Purchasing","description":"Amazon In-App Purchasing (IAP) API allows your app to present, process, and fulfill purchases of digital content and subscriptions within your Android app through the Amazon Appstore.","sidebar":"inappbilling"},"inappbilling/amazon/amazon-in-app-purchasing":{"id":"inappbilling/amazon/amazon-in-app-purchasing","title":"Setup Amazon IAP","description":"Add Your Application to the Developer Console","sidebar":"inappbilling"},"inappbilling/amazon/testing":{"id":"inappbilling/amazon/testing","title":"Testing Amazon IAP","description":"Amazon In-App Purchasing","sidebar":"inappbilling"},"inappbilling/apple/apple-in-app-purchases":{"id":"inappbilling/apple/apple-in-app-purchases","title":"Apple In-App Purchases","description":"Creating Your Products","sidebar":"inappbilling"},"inappbilling/apple/server-side-verification":{"id":"inappbilling/apple/server-side-verification","title":"Server Side Verification","description":"Server Side Verification","sidebar":"inappbilling"},"inappbilling/apple/testing":{"id":"inappbilling/apple/testing","title":"Testing Apple In-App Purchases","description":"iOS Subscriptions","sidebar":"inappbilling"},"inappbilling/apple/troubleshooting":{"id":"inappbilling/apple/troubleshooting","title":"Troubleshooting","description":"Common problems","sidebar":"inappbilling"},"inappbilling/application-receipt":{"id":"inappbilling/application-receipt","title":"Application Receipt","description":"The concepts here are relevant only to iOS, iPadOS and macOS using Apple\'s In-App Purchasing","sidebar":"inappbilling"},"inappbilling/billing-service":{"id":"inappbilling/billing-service","title":"Setup Billing Service","description":"Billing Service","sidebar":"inappbilling"},"inappbilling/change-a-purchase":{"id":"inappbilling/change-a-purchase","title":"Change a Purchase","description":"You can offer users different subscription tiers, such as a base tier and a premium tier in some billing services (such as Google Play Billing).","sidebar":"inappbilling"},"inappbilling/changelog":{"id":"inappbilling/changelog","title":"changelog","description":"2023.10.13 [v15.2.1]","sidebar":"inappbilling"},"inappbilling/consuming-purchases":{"id":"inappbilling/consuming-purchases","title":"Consuming Purchases","description":"Once an item is purchased, it is considered to be \\"owned\\".","sidebar":"inappbilling"},"inappbilling/get-purchases":{"id":"inappbilling/get-purchases","title":"Get Purchases","description":"On services where you can directly query the service for user purchases you can call the getPurchases() function to retrieve them directly from the service.","sidebar":"inappbilling"},"inappbilling/google/google-play-inapp-billing":{"id":"inappbilling/google/google-play-inapp-billing","title":"Google Play InApp Billing","description":"Add Your Application to the Developer Console","sidebar":"inappbilling"},"inappbilling/google/testing":{"id":"inappbilling/google/testing","title":"Testing Google Play Billing","description":"In order to test Google Play Billing you simply need to add an apk to a test channel and sign in to a device using a user who has signed up for this channel."},"inappbilling/huawei/add-the-extension":{"id":"inappbilling/huawei/add-the-extension","title":"Huawei AppGallery In-App Purchases","description":"Huawei AppGallery is Huawei official Android Application store.","sidebar":"inappbilling"},"inappbilling/huawei/huawei-appgallery":{"id":"inappbilling/huawei/huawei-appgallery","title":"Huawei AppGallery","description":"The following outlines the steps required to enable AppGallery in app purchases in your application.","sidebar":"inappbilling"},"inappbilling/huawei/testing":{"id":"inappbilling/huawei/testing","title":"Testing Huawei AppGallery","description":"Huawei AppGallery In-App Purchases","sidebar":"inappbilling"},"inappbilling/in-app-updates":{"id":"inappbilling/in-app-updates","title":"In App Updates","description":"In-App Updates is a method for your application to check with the store as to whether there is a newer version of your application available. Although some users enable background updates when their device is connected to an unmetered connection, other users may need to be reminded to update.","sidebar":"inappbilling"},"inappbilling/index":{"id":"inappbilling/index","title":"InAppBilling","description":"The In-App Billing","sidebar":"inappbilling"},"inappbilling/introductory-prices":{"id":"inappbilling/introductory-prices","title":"Introductory Prices","description":"Offer introductory pricing for auto-renewable subscriptions to eligible users.","sidebar":"inappbilling"},"inappbilling/make-a-purchase":{"id":"inappbilling/make-a-purchase","title":"Make a Purchase","description":"Finally we reach the most important process in this extension, making a purchase.","sidebar":"inappbilling"},"inappbilling/migration":{"id":"inappbilling/migration","title":"Migration (v12 and below)","description":"Version 12.0","sidebar":"inappbilling"},"inappbilling/migration-v14":{"id":"inappbilling/migration-v14","title":"Migration v14","description":"Version 14.0","sidebar":"inappbilling"},"inappbilling/migration-v15":{"id":"inappbilling/migration-v15","title":"Migration v15","description":"Version 15.0"},"inappbilling/overview":{"id":"inappbilling/overview","title":"Overview","description":"Implementing in-app billing / purchases can be a daunting task. There are several steps that you must go through.","sidebar":"inappbilling"},"inappbilling/pending-purchases":{"id":"inappbilling/pending-purchases","title":"Pending Purchases","description":"Interupted / Pending / Acknowledging Purchases","sidebar":"inappbilling"},"inappbilling/products":{"id":"inappbilling/products","title":"Products","description":"At the core of the InAppBilling functionality is a list of products.","sidebar":"inappbilling"},"inappbilling/promotions":{"id":"inappbilling/promotions","title":"Promotions","description":"With iOS 11, users can browse in-app purchases directly on the App Store and start a purchase even before downloading your app.","sidebar":"inappbilling"},"inappbilling/restore-purchases":{"id":"inappbilling/restore-purchases","title":"Restore Purchases","description":"Restoring purchases is a process that you should allow for user\'s who have either changed devices","sidebar":"inappbilling"},"inappbilling/samsung/add-the-extension":{"id":"inappbilling/samsung/add-the-extension","title":"Samsung In-App Purchasing","description":"Samsung In-App Purchase (IAP) is a payment service that makes it possible to sell a variety of items in applications for Samsung Galaxy Store and internally manages communication with supporting IAP services in the Samsung ecosystem, such as Samsung Account, Samsung Checkout, and Samsung Rewards.","sidebar":"inappbilling"},"inappbilling/samsung/samsung-in-app-purchases":{"id":"inappbilling/samsung/samsung-in-app-purchases","title":"Setup Samsung Galaxy Store","description":"Samsung devices use a variant of Android. Some may include both Google Play and the Samsung Galaxy Store.","sidebar":"inappbilling"},"inappbilling/samsung/testing":{"id":"inappbilling/samsung/testing","title":"Samsung Galaxy Store - Testing","description":"Users","sidebar":"inappbilling"},"inappbilling/subscription-offers":{"id":"inappbilling/subscription-offers","title":"Subscription Offers","description":"A subscription represents a set of benefits users can access during a specified time period. For example, a subscription might entitle a user to access a music streaming service.","sidebar":"inappbilling"},"inappbilling/testing":{"id":"inappbilling/testing","title":"Testing","description":"Test each part of your code to verify that you\u2019ve implemented it correctly.","sidebar":"inappbilling"},"inappbilling/user-data":{"id":"inappbilling/user-data","title":"User Data","description":"Some services attach some information to the user that can be retrieved and may be necessary to validate receipts.","sidebar":"inappbilling"},"index":{"id":"index","title":"Native Extensions","description":"Get started quickly and easily with distriqt\'s native extensions and focus on building great games and apps.","sidebar":"someSidebar"},"ironsource/add-the-extension":{"id":"ironsource/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"ironsource"},"ironsource/banner-ads":{"id":"ironsource/banner-ads","title":"Banner Ads","description":"A banner ad is a rectangular ad that is typically displayed on the top or bottom of the screen and remains in place for the entire user session. Banner ads can be static or dynamic.","sidebar":"ironsource"},"ironsource/changelog":{"id":"ironsource/changelog","title":"changelog","description":"2023.11.07 [v2.18.1]","sidebar":"ironsource"},"ironsource/errors":{"id":"ironsource/errors","title":"Errors","description":"ironSource provides an error code mechanism to help you understand errors you may run into during integration or live production. Extract the error data from the Event object as follows:","sidebar":"ironsource"},"ironsource/index":{"id":"ironsource/index","title":"IronSource","description":"This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:","sidebar":"ironsource"},"ironsource/initialisation":{"id":"ironsource/initialisation","title":"Initialisation","description":"Before starting to use the Iron Source SDK you must call init() with your Iron Source application key and specify the ad unit types you will be using in your application.","sidebar":"ironsource"},"ironsource/interstitials":{"id":"ironsource/interstitials","title":"Interstitials","description":"An interstitial ad is a full-screen static, video or interactive (playable) ad unit that offers users the option to exit and skip. They engage users with rich content at natural pauses in the app\u2019s flow, ensuring minimum disruption to user experience while maximizing user engagement and revenue.","sidebar":"ironsource"},"ironsource/mediation/adcolony/adcolony":{"id":"ironsource/mediation/adcolony/adcolony","title":"Mediation - AdColony","description":"This guide shows how to add mediation through AdColony to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/admob/admob":{"id":"ironsource/mediation/admob/admob","title":"Mediation - AdMob","description":"This guide shows how to add mediation through AdMob to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/amazon/amazon":{"id":"ironsource/mediation/amazon/amazon","title":"Mediation - Amazon","description":"As of September 30, 2021 Amazon deprecated Amazon Mobile Ads Network.","sidebar":"ironsource"},"ironsource/mediation/applovin/applovin":{"id":"ironsource/mediation/applovin/applovin","title":"Mediation - AppLovin","description":"This guide shows how to add mediation through AppLovin to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/chartboost/chartboost":{"id":"ironsource/mediation/chartboost/chartboost","title":"Mediation - Chartboost","description":"This guide shows how to add mediation through Chartboost to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/digitalturbine/digitalturbine":{"id":"ironsource/mediation/digitalturbine/digitalturbine","title":"Mediation - Digital Turbine (Fyber)","description":"This guide shows how to add mediation through Digital Turbine (Fyber) to your IronSource integration."},"ironsource/mediation/facebook-audience/facebook-audience":{"id":"ironsource/mediation/facebook-audience/facebook-audience","title":"Mediation - Facebook Audience","description":"This guide shows how to add mediation through Facebook Audience to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/tapjoy/tapjoy":{"id":"ironsource/mediation/tapjoy/tapjoy","title":"Mediation - Tapjoy","description":"This guide shows how to add mediation through Tapjoy to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/unityads/unityads":{"id":"ironsource/mediation/unityads/unityads","title":"Mediation - UnityAds","description":"This guide shows how to add mediation through UnityAds to your IronSource integration.","sidebar":"ironsource"},"ironsource/mediation/vungle/vungle":{"id":"ironsource/mediation/vungle/vungle","title":"Mediation - Vungle","description":"This guide shows how to add mediation through Vungle to your IronSource integration.","sidebar":"ironsource"},"ironsource/migrating-to-androidx":{"id":"ironsource/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"ironsource"},"ironsource/offerwall":{"id":"ironsource/offerwall","title":"Offerwall","description":"The offerwall is an in-app advertising unit that app developers use to monetize their apps. It acts like a mini-store in an app, listing multiple \u201coffers\u201d that users can complete in exchange for receiving an in-app reward. For example, users can receive extra in-app coins if they choose to register a username, get to level 25 on a game, make an in-app purchase, and more on the offerwall.","sidebar":"ironsource"},"ironsource/rewarded-video":{"id":"ironsource/rewarded-video","title":"Rewarded Video","description":"Rewarded videos are opt-in ad units that encourage users to watch a video in order to receive in-app rewards.","sidebar":"ironsource"},"isallmediators/changelog":{"id":"isallmediators/changelog","title":"changelog","description":"2022.10.04 [v1.1.0]"},"jobscheduler/add-the-extension":{"id":"jobscheduler/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"jobscheduler"},"jobscheduler/application-termination":{"id":"jobscheduler/application-termination","title":"Application Termination","description":"Schedule Termination","sidebar":"jobscheduler"},"jobscheduler/changelog":{"id":"jobscheduler/changelog","title":"changelog","description":"2023.02.01 [v1.1.0]","sidebar":"jobscheduler"},"jobscheduler/index":{"id":"jobscheduler/index","title":"Job Scheduler","description":"The JobScheduler extension","sidebar":"jobscheduler"},"localauth/add-the-extension":{"id":"localauth/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"localauth"},"localauth/biometric-authentication":{"id":"localauth/biometric-authentication","title":"Biometric Authentication","description":"Checking for support","sidebar":"localauth"},"localauth/changelog":{"id":"localauth/changelog","title":"changelog","description":"2023.01.23 [v3.1.0]","sidebar":"localauth"},"localauth/index":{"id":"localauth/index","title":"LocalAuth","description":"The LocalAuth is an","sidebar":"localauth"},"localauth/migrating-to-androidx":{"id":"localauth/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X"},"localauth/request-authorisation":{"id":"localauth/request-authorisation","title":"Authorisation","description":"Usage Description","sidebar":"localauth"},"location/add-the-extension":{"id":"location/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"location"},"location/changelog":{"id":"location/changelog","title":"changelog","description":"2023.07.05 [v5.0.0]","sidebar":"location"},"location/device-location-settings":{"id":"location/device-location-settings","title":"Device Location Settings","description":"Device settings are separate from authorisation. While your application may be authorised to access the user\'s location they may have disabled their devices GPS or WiFi making receiving location updates difficult or impossible.","sidebar":"location"},"location/geocoding":{"id":"location/geocoding","title":"Geocoding","description":"Geocoding is the process of transforming a street address or other description of a location into a (latitude, longitude) coordinate. Reverse geocoding is the process of transforming a (latitude, longitude) coordinate into a (partial) address. The amount of detail in a reverse geocoded location description may vary, for example one might contain the full street address of the closest building, while another might contain only a city name and postal code.","sidebar":"location"},"location/geofences":{"id":"location/geofences","title":"Geofences","description":"Authorisation","sidebar":"location"},"location/index":{"id":"location/index","title":"Location","description":"The Location extension provides","sidebar":"location"},"location/initialise-the-extension":{"id":"location/initialise-the-extension","title":"Initialise the Extension","description":"Supported","sidebar":"location"},"location/ios-location-simulation":{"id":"location/ios-location-simulation","title":"iOS Location Simulation","description":"iOS Location Simulation","sidebar":"location"},"location/location-monitoring":{"id":"location/location-monitoring","title":"Location Monitoring","description":"Start Location Monitoring","sidebar":"location"},"location/location-utils---distance":{"id":"location/location-utils---distance","title":"Location Utils - Distance","description":"Calculating distance","sidebar":"location"},"location/migrating-to-androidx":{"id":"location/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"location"},"location/migrating-to-v4.5":{"id":"location/migrating-to-v4.5","title":"Migrating to v4.5","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"location"},"location/request-authorisation":{"id":"location/request-authorisation","title":"Request Authorisation","description":"When you are going to be accessing the user\'s location you must check that your","sidebar":"location"},"mediaplayer/add-the-extension":{"id":"mediaplayer/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"mediaplayer"},"mediaplayer/audio-player":{"id":"mediaplayer/audio-player","title":"Audio Player","description":"The Audio Player can be used to play back audio files using the native audio player.","sidebar":"mediaplayer"},"mediaplayer/audio-player---background-audio":{"id":"mediaplayer/audio-player---background-audio","title":"Audio Player - Background Audio","description":"The Audio Player can be used to play back audio files using the native audio player in the background. This allows you to introduce background audio playback, and remote control center display of audio media information.","sidebar":"mediaplayer"},"mediaplayer/changelog":{"id":"mediaplayer/changelog","title":"changelog","description":"2023.10.19 [v4.8.0]","sidebar":"mediaplayer"},"mediaplayer/index":{"id":"mediaplayer/index","title":"MediaPlayer","description":"The MediaPlayer","sidebar":"mediaplayer"},"mediaplayer/media-player---control-playback":{"id":"mediaplayer/media-player---control-playback","title":"Media Player - Control Playback","description":"Controlling playback","sidebar":"mediaplayer"},"mediaplayer/media-player---create":{"id":"mediaplayer/media-player---create","title":"Media Player - Create","description":"Media Player View","sidebar":"mediaplayer"},"mediaplayer/media-player---loading-media":{"id":"mediaplayer/media-player---loading-media","title":"Media Player - Loading Media","description":"Once you have created a MediaPlayerView instance then you will need to load your media into the player. In the following code player is assumed to be the MediaPlayerView instance you created:","sidebar":"mediaplayer"},"mediaplayer/media-player---playback-events":{"id":"mediaplayer/media-player---playback-events","title":"Media Player - Playback Events","description":"There are 3 main types of events associated with the media player: status, progress and errors.","sidebar":"mediaplayer"},"mediaplayer/migrating-from-version-1":{"id":"mediaplayer/migrating-from-version-1","title":"Migrating from version 1","description":"Version 2 completely changes the way media players are created and displayed. Migration is simple as laid out below.","sidebar":"mediaplayer"},"mediaplayer/migrating-to-androidx":{"id":"mediaplayer/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"mediaplayer"},"mediaplayer/remote-command-center":{"id":"mediaplayer/remote-command-center","title":"Remote Command Center","description":"The Remote Command Center represents a common interface to access areas of the operating system that display information about the currently playing media and access to the playback controls.","sidebar":"mediaplayer"},"mediaplayer/sound-pool":{"id":"mediaplayer/sound-pool","title":"Sound Pool","description":"A SoundPool is a collection of samples that can be loaded into memory. It allows you to play short sound effects and samples. The sounds are loaded into memory for low-latency playback.","sidebar":"mediaplayer"},"mediaplayer/system-control":{"id":"mediaplayer/system-control","title":"System Control","description":"The system control interface allows your application to dispatch system wide events that other applications can respond to. These events are the default system control events for media and may control the active media player (most player respond to these events however it does depend on the application implementation).","sidebar":"mediaplayer"},"memory/add-the-extension":{"id":"memory/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"memory"},"memory/changelog":{"id":"memory/changelog","title":"changelog","description":"2023.09.22 [v4.2.2]","sidebar":"memory"},"memory/index":{"id":"memory/index","title":"Memory","description":"Memory is an AIR Native Extension to receive the low memory notifications on iOS which indicate when","sidebar":"memory"},"memory/usage":{"id":"memory/usage","title":"Usage","description":"Low Memory Warning","sidebar":"memory"},"message/add-the-extension":{"id":"message/add-the-extension","title":"Add the Extension","description":"First step is always to add the extension to your development environment.","sidebar":"message"},"message/changelog":{"id":"message/changelog","title":"changelog","description":"2021.04.27 [v7.0.027]","sidebar":"message"},"message/email":{"id":"message/email","title":"Email","description":"Sending an Email","sidebar":"message"},"message/index":{"id":"message/index","title":"Message","description":"The Message extension has been deprecated.","sidebar":"message"},"message/migrating-to-androidx":{"id":"message/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"message"},"message/sms":{"id":"message/sms","title":"SMS","description":"Sending an SMS with UI","sidebar":"message"},"nativemaps/add-the-extension":{"id":"nativemaps/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"nativemaps"},"nativemaps/apple-maps":{"id":"nativemaps/apple-maps","title":"Apple Maps","description":"Nothing particular is required to setup your application for Apple Maps on iOS.","sidebar":"nativemaps"},"nativemaps/changelog":{"id":"nativemaps/changelog","title":"changelog","description":"2023.01.26 [v5.2.0]","sidebar":"nativemaps"},"nativemaps/controlling-the-view":{"id":"nativemaps/controlling-the-view","title":"Controlling the View","description":"Changing Map Options","sidebar":"nativemaps"},"nativemaps/create-a-map":{"id":"nativemaps/create-a-map","title":"Create a Map","description":"Preparing the view on Android","sidebar":"nativemaps"},"nativemaps/google-maps":{"id":"nativemaps/google-maps","title":"Google Maps","description":"Add Your Application to the Developer Console","sidebar":"nativemaps"},"nativemaps/index":{"id":"nativemaps/index","title":"NativeMaps","description":"The Native Maps allows you to display native iOS Apple maps and Android Google maps with interactivity and overlays in your applications.","sidebar":"nativemaps"},"nativemaps/initialise-the-extension":{"id":"nativemaps/initialise-the-extension","title":"Initialise the Extension","description":"Supported","sidebar":"nativemaps"},"nativemaps/migrating-to-androidx":{"id":"nativemaps/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"nativemaps"},"nativemaps/migrating-to-v5.2":{"id":"nativemaps/migrating-to-v5.2","title":"Migrating to v5.2","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"nativemaps"},"nativemaps/overlays":{"id":"nativemaps/overlays","title":"Overlays","description":"Overlays are visual additions to the map. These include:","sidebar":"nativemaps"},"nativemaps/overlays---markers":{"id":"nativemaps/overlays---markers","title":"Overlays - Markers","description":"Markers are pins located at a single location. They can be used to identify places of interest.","sidebar":"nativemaps"},"nativemaps/overlays---polygons":{"id":"nativemaps/overlays---polygons","title":"Overlays - Polygons","description":"Polygons are an extension of a polyline allowing you to fill the area contained within the line, so they can be used to draw shapes on the map.","sidebar":"nativemaps"},"nativemaps/overlays---polylines":{"id":"nativemaps/overlays---polylines","title":"Overlays - Polylines","description":"Polylines are a series of points that trace out a line. They can be used to outline areas or to indicate paths.","sidebar":"nativemaps"},"nativemaps/request-authorisation":{"id":"nativemaps/request-authorisation","title":"Request Authorisation","description":"Displaying maps does not require any particular authorisation / permission from the user.","sidebar":"nativemaps"},"nativemaps/touch-events":{"id":"nativemaps/touch-events","title":"Touch Events","description":"There are several events that will be dispatched by the map to indicate the user is interacting with the map.","sidebar":"nativemaps"},"nativemaps/upgrade-new-version":{"id":"nativemaps/upgrade-new-version","title":"upgrade-new-version","description":"The latest version (vX.X.X) of our NativeMaps extension has been updated"},"nativetext/add-the-extension":{"id":"nativetext/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"nativetext"},"nativetext/changelog":{"id":"nativetext/changelog","title":"changelog","description":"2023.01.26 [v0.2.0]","sidebar":"nativetext"},"nativetext/index":{"id":"nativetext/index","title":"Native Text","description":"This extension was built by distriqt //","sidebar":"nativetext"},"nativetext/keyboard-input":{"id":"nativetext/keyboard-input","title":"Keyboard Input","description":"This extension provides the ability to show a text field input that displays directly above the keyboard over your application content and is presented with the keyboard. This gives you a simple way for your users to input some text for your application to use.","sidebar":"nativetext"},"nativewebview/add-the-extension":{"id":"nativewebview/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"nativewebview"},"nativewebview/browser-view":{"id":"nativewebview/browser-view","title":"Browser View","description":"The browser view is the simplest method of displaying a full page website in your application.","sidebar":"nativewebview"},"nativewebview/changelog":{"id":"nativewebview/changelog","title":"changelog","description":"2023.10.10 [v7.1.0]","sidebar":"nativewebview"},"nativewebview/communication":{"id":"nativewebview/communication","title":"Communication","description":"One of the important aspects of this extension is the ability to communicate from your Actionscript","sidebar":"nativewebview"},"nativewebview/create-a-webview":{"id":"nativewebview/create-a-webview","title":"Create a WebView","description":"Once you have initialised the extension, creating a web view is simply a matter of calling the createWebView() function with your parameters.","sidebar":"nativewebview"},"nativewebview/index":{"id":"nativewebview/index","title":"NativeWebView","description":"The NativeWebView extension is designed to be a replacement version of the StageWebView, but much more useful.","sidebar":"nativewebview"},"nativewebview/initialise-the-extension":{"id":"nativewebview/initialise-the-extension","title":"Initialise the Extension","description":"Supported","sidebar":"nativewebview"},"nativewebview/loading-packaged-files":{"id":"nativewebview/loading-packaged-files","title":"Loading Packaged Files","description":"Loading Packaged Files","sidebar":"nativewebview"},"nativewebview/location-changes":{"id":"nativewebview/location-changes","title":"Location Changes","description":"Location Change Events","sidebar":"nativewebview"},"nativewebview/migrating-to-androidx":{"id":"nativewebview/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"nativewebview"},"nativewebview/migrating-to-v5":{"id":"nativewebview/migrating-to-v5","title":"Migrating to v5","description":"Version 5","sidebar":"nativewebview"},"nativewebview/migrating-to-v5.4":{"id":"nativewebview/migrating-to-v5.4","title":"Migrating to v5.4","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"nativewebview"},"nativewebview/position-size-visibility":{"id":"nativewebview/position-size-visibility","title":"Position Size Visibility","description":"Resizing","sidebar":"nativewebview"},"nativewebview/removing-the-webview":{"id":"nativewebview/removing-the-webview","title":"Removing the WebView","description":"In order to remove the web view from your application you call the dispose function on the WebView.","sidebar":"nativewebview"},"nativewebview/screenshot":{"id":"nativewebview/screenshot","title":"Screenshot","description":"Capturing a Screenshot","sidebar":"nativewebview"},"nativewebview/webview-information":{"id":"nativewebview/webview-information","title":"WebView Information","description":"You can get information about the current state and contents of the web view through a range of methods.","sidebar":"nativewebview"},"networkinfo/add-the-extension":{"id":"networkinfo/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"networkinfo"},"networkinfo/changelog":{"id":"networkinfo/changelog","title":"changelog","description":"2023.01.19 [v4.1.0]","sidebar":"networkinfo"},"networkinfo/index":{"id":"networkinfo/index","title":"NetworkInfo","description":"The NetworkInfo","sidebar":"networkinfo"},"networkinfo/network-change-monitoring":{"id":"networkinfo/network-change-monitoring","title":"Network Change Monitoring","description":"To monitor network changes you add a listener for the NetworkInfoEvent.CHANGE","sidebar":"networkinfo"},"networkinfo/telephony":{"id":"networkinfo/telephony","title":"Telephony","description":"Provides access to information about the telephony services on the user\'s device.","sidebar":"networkinfo"},"nfc/add-the-extension":{"id":"nfc/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"nfc"},"nfc/add-the-plugin":{"id":"nfc/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"nfc"},"nfc/changelog":{"id":"nfc/changelog","title":"changelog","description":"2023.07.06 [v5.3.0]","sidebar":"nfc"},"nfc/dispatch-mode":{"id":"nfc/dispatch-mode","title":"Dispatch Mode","description":"Dispatch mode relies on the system dispatching data about the tags and responding to these events. Additionally you can use this method to register your application to launch when specific tags are detected by the system.","sidebar":"nfc"},"nfc/index":{"id":"nfc/index","title":"NFC","description":"The NFC extension gives you the ability to use the Near Field Communication (NFC) hardware to scan for NFC Tags and read the record data contained in the tags.","sidebar":"nfc"},"nfc/reader-mode":{"id":"nfc/reader-mode","title":"Reader Mode","description":"Reader mode can be used to active scan for tags and read them multiple times. This is useful in the cases where the data changes on the tag so you may need to re-read it at a later point.","sidebar":"nfc"},"nfc/scanning":{"id":"nfc/scanning","title":"Scanning","description":"Tags","sidebar":"nfc"},"nfc/unity":{"id":"nfc/unity","title":"Unity","description":"Contents"},"notifications/add-the-extension":{"id":"notifications/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"notifications"},"notifications/add-the-extension---windows":{"id":"notifications/add-the-extension---windows","title":"Add the Extension - Windows","description":"There are several additional things to consider on Windows:","sidebar":"notifications"},"notifications/cancel-notifications":{"id":"notifications/cancel-notifications","title":"Cancel Notifications","description":"Once a notification has been created you may wish to cancel it, especially in the case of","sidebar":"notifications"},"notifications/changelog":{"id":"notifications/changelog","title":"changelog","description":"2023.09.22 [v6.6.1]","sidebar":"notifications"},"notifications/delay-and-repeat-interval":{"id":"notifications/delay-and-repeat-interval","title":"Delay and Repeat Interval","description":"It is possible to schedule a notification to be delivered at a later date and also to apply","sidebar":"notifications"},"notifications/displaying-notifications":{"id":"notifications/displaying-notifications","title":"Displaying Notifications","description":"This extension allows access to native local notifications, as opposed to push notifications.","sidebar":"notifications"},"notifications/emojis":{"id":"notifications/emojis","title":"Emojis","description":"You can use emojis that are part of Unicode in your notifications wherever the extended unicode character sets are supported, which includes modern Android and iOS releases.","sidebar":"notifications"},"notifications/index":{"id":"notifications/index","title":"Notifications","description":"The Notifications extension enables the use of Local Notifications","sidebar":"notifications"},"notifications/migrating-to-6.3":{"id":"notifications/migrating-to-6.3","title":"Migrating to v6.3","description":"Android 31","sidebar":"notifications"},"notifications/migrating-to-6.4":{"id":"notifications/migrating-to-6.4","title":"Migrating to v6.4","description":"Android 13 (API 33) Permissions","sidebar":"notifications"},"notifications/migrating-to-6.5":{"id":"notifications/migrating-to-6.5","title":"Migrating to v6.5","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"notifications"},"notifications/migrating-to-androidx":{"id":"notifications/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"notifications"},"notifications/notification-icons":{"id":"notifications/notification-icons","title":"Notification Icons","description":"Notification icons refer to the image displayed in the notification center alongside the title, message and any other content associated with the notification.","sidebar":"notifications"},"notifications/notification-scenarios":{"id":"notifications/notification-scenarios","title":"Notification Scenarios","description":"Foreground, background - Notification Scenarios"},"notifications/notification-types":{"id":"notifications/notification-types","title":"Notification Types","description":"Icons","sidebar":"notifications"},"notifications/receiving-notifications":{"id":"notifications/receiving-notifications","title":"Receiving notifications","description":"There are several events that can be dispatched by a notification.","sidebar":"notifications"},"notifications/register-for-notifications":{"id":"notifications/register-for-notifications","title":"Register for notifications","description":"Now that you have authorisation to access notifications you can register your user\'s device.","sidebar":"notifications"},"notifications/request-authorisation":{"id":"notifications/request-authorisation","title":"Request Authorisation","description":"After setting up your service you should check whether the device has given your application authorisation to register and display notifications.","sidebar":"notifications"},"notifications/set-badge-number":{"id":"notifications/set-badge-number","title":"Set Badge Number","description":"You can set the badge number using this extension. The badge number is the small number","sidebar":"notifications"},"notifications/setup-your-service":{"id":"notifications/setup-your-service","title":"Setup your Service","description":"When you are setting up your Service there are a few additional options you can set to use some of the","sidebar":"notifications"},"notifications/sounds":{"id":"notifications/sounds","title":"Sounds","description":"The following documentation describes how to get custom sounds to play when your notification arrives.","sidebar":"notifications"},"ocr/add-the-extension":{"id":"ocr/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"ocr"},"ocr/changelog":{"id":"ocr/changelog","title":"changelog","description":"2023.01.29 [v4.1.0]","sidebar":"ocr"},"ocr/index":{"id":"ocr/index","title":"OCR","description":"The OCR extension gives you the ability to perform optical character recognition (https://en.wikipedia.org/wiki/Opticalcharacterrecognition) on an image.","sidebar":"ocr"},"ocr/migrating-to-androidx":{"id":"ocr/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"ocr"},"ocr/recognising-text":{"id":"ocr/recognising-text","title":"Recognising Text","description":"Recognising text is as simple as calling the recognise function with the BitmapData you wish to scan.","sidebar":"ocr"},"ocr/tips-for-improving-ocr-results":{"id":"ocr/tips-for-improving-ocr-results","title":"Tips for Improving OCR Results","description":"Tesseract is a library for performing optical character recognition, but it\'s important to know","sidebar":"ocr"},"ocr/training-data":{"id":"ocr/training-data","title":"Training Data","description":"You will need to provide a trained data file for a language. Trained data files can be found in the Tesseract Tessdata Repository.","sidebar":"ocr"},"packagemanager/add-the-extension":{"id":"packagemanager/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"packagemanager"},"packagemanager/changelog":{"id":"packagemanager/changelog","title":"changelog","description":"2023.07.20 [v3.4.0]","sidebar":"packagemanager"},"packagemanager/index":{"id":"packagemanager/index","title":"PackageManager","description":"The PackageManager extension gives access to certain features of the Android package manager.","sidebar":"packagemanager"},"packagemanager/installed-application-info":{"id":"packagemanager/installed-application-info","title":"Installed Application Info","description":"Permissions","sidebar":"packagemanager"},"packagemanager/installing-apps":{"id":"packagemanager/installing-apps","title":"Installing Apps","description":"Android only","sidebar":"packagemanager"},"packagemanager/migrating-to-androidx":{"id":"packagemanager/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"packagemanager"},"packagemanager/package-events":{"id":"packagemanager/package-events","title":"Package Events","description":"Package Removed","sidebar":"packagemanager"},"pdfreader/add-the-extension":{"id":"pdfreader/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"pdfreader"},"pdfreader/changelog":{"id":"pdfreader/changelog","title":"changelog","description":"2023.01.30 [v5.2.0]","sidebar":"pdfreader"},"pdfreader/create-a-pdf-view":{"id":"pdfreader/create-a-pdf-view","title":"Create a PDF View","description":"A PDF View represents a viewer that loads and displays a specified PDF.","sidebar":"pdfreader"},"pdfreader/index":{"id":"pdfreader/index","title":"PDFReader","description":"The PDFReader extension","sidebar":"pdfreader"},"pdfreader/migrating-to-androidx":{"id":"pdfreader/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"pdfreader"},"pdfreader/pages":{"id":"pdfreader/pages","title":"Pages","description":"You can get information about the pages in the current document:","sidebar":"pdfreader"},"permissions/add-the-extension":{"id":"permissions/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"permissions"},"permissions/changelog":{"id":"permissions/changelog","title":"changelog","description":"2023.02.01 [v3.4.1]","sidebar":"permissions"},"permissions/file-folder-access":{"id":"permissions/file-folder-access","title":"File and Folder Access","description":"Android has placed additional permissions on files outside of your application sandbox and now requires you to request user access to these directories (eg the camera storage on the sdcard: /sdcard/DCIM ).","sidebar":"permissions"},"permissions/index":{"id":"permissions/index","title":"Permissions","description":"The Permissions extension","sidebar":"permissions"},"permissions/migrating-to-androidx":{"id":"permissions/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"permissions"},"permissions/migrating-to-v3.4":{"id":"permissions/migrating-to-v3.4","title":"Migrating to v3.4","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"permissions"},"permissions/requesting-access":{"id":"permissions/requesting-access","title":"Requesting Access","description":"When you are going to be accessing a \'dangerous\' permission you must check that","sidebar":"permissions"},"permissions/set-permissions":{"id":"permissions/set-permissions","title":"Set Permissions","description":"You must inform the extension which permissions you wish to request.","sidebar":"permissions"},"permissions/system-settings":{"id":"permissions/system-settings","title":"System Settings","description":"Some permissions are controlled through the system settings dialogs and cannot be requested through the normal permission request process.","sidebar":"permissions"},"pushnotifications/add-the-extension":{"id":"pushnotifications/add-the-extension","title":"Add the Extension","description":"Here we will show you how to add the extension to your development environment and make the necessary changes to your application descriptor to correctly support the extension.","sidebar":"pushnotifications"},"pushnotifications/apple/add-the-extension":{"id":"pushnotifications/apple/add-the-extension","title":"Apple Push Notification Service","description":"Apple Push Notification Service (APNS) is the push notification system for use on iOS with iPhones, iPads and other such iOS devices.","sidebar":"pushnotifications"},"pushnotifications/apple/apple-push-notification-service":{"id":"pushnotifications/apple/apple-push-notification-service","title":"Setup","description":"Apple Push Notification Service (APNS) is the push notification system for use on","sidebar":"pushnotifications"},"pushnotifications/apple/ios-apns-message":{"id":"pushnotifications/apple/ios-apns-message","title":"iOS APNS Message","description":"There are many ways to send notifications to your devices.","sidebar":"pushnotifications"},"pushnotifications/apple/ios-apns-payload":{"id":"pushnotifications/apple/ios-apns-payload","title":"iOS APNS Payload","description":"The iOS payload is relatively simple. Using the payload you can set:","sidebar":"pushnotifications"},"pushnotifications/azure/azure-notifications":{"id":"pushnotifications/azure/azure-notifications","title":"Azure Notifications","description":"The Azure implementation is currently unmaintained, if you require an update to this service please contact our support and we will look into it for you.","sidebar":"pushnotifications"},"pushnotifications/azure/setup-your-service":{"id":"pushnotifications/azure/setup-your-service","title":"Setup your Service - Azure","description":"The following shows how to configure the Service for usage with your Azure Notification Hub.","sidebar":"pushnotifications"},"pushnotifications/changelog":{"id":"pushnotifications/changelog","title":"changelog","description":"2023.10.24 [v14.0.0]","sidebar":"pushnotifications"},"pushnotifications/firebase/add-the-extension":{"id":"pushnotifications/firebase/add-the-extension","title":"Firebase Cloud Messaging","description":"Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably send messages at no cost.","sidebar":"pushnotifications"},"pushnotifications/firebase/fcm-gcm-payload":{"id":"pushnotifications/firebase/fcm-gcm-payload","title":"FCM-GCM Payload","description":"As Android notifications have many more features there are more fields available in","sidebar":"pushnotifications"},"pushnotifications/firebase/firebase-cloud-message":{"id":"pushnotifications/firebase/firebase-cloud-message","title":"Firebase Cloud Message","description":"Sending a message with Firebase is very similar (if not exactly the same) as GCM apart from the endpoint.","sidebar":"pushnotifications"},"pushnotifications/firebase/firebase-cloud-messaging":{"id":"pushnotifications/firebase/firebase-cloud-messaging","title":"Setup","description":"You should firstly setup a Firebase project for your application. See the documentation to Create a Firebase Project.","sidebar":"pushnotifications"},"pushnotifications/firebase/firebase-inapp-messaging":{"id":"pushnotifications/firebase/firebase-inapp-messaging","title":"Firebase InApp Messaging","description":"Firebase In-App Messaging helps you engage your app\'s active users by sending them targeted, contextual messages that encourage them to use key app features. For example, you could send an in-app message to get users to subscribe, watch a video, complete a level, or buy an item. You can customize messages as cards, banners, modals, or images, and set up triggers so that they appear exactly when they\'d benefit your users most."},"pushnotifications/gcm/google-cloud-message":{"id":"pushnotifications/gcm/google-cloud-message","title":"Google Cloud Message","description":"There are many ways to send notifications to your devices."},"pushnotifications/gcm/google-cloud-messaging":{"id":"pushnotifications/gcm/google-cloud-messaging","title":"Google Cloud Messaging","description":"Google has deprecated GCM and it is no longer supported and is advising you use Firebase Cloud Messaging in place of GCM."},"pushnotifications/handling-startup-notifications":{"id":"pushnotifications/handling-startup-notifications","title":"Handling startup notifications","description":"With any of notification events they may be stored and dispatched when your application starts up.","sidebar":"pushnotifications"},"pushnotifications/icons":{"id":"pushnotifications/icons","title":"Icons","description":"Notification icons refer to the image displayed in the notification center alongside the title, message and any other content associated with the notification.","sidebar":"pushnotifications"},"pushnotifications/inapp-messaging":{"id":"pushnotifications/inapp-messaging","title":"InApp Messaging","description":"In-App Messaging helps you engage your app\'s active users by sending them targeted, contextual messages that encourage them to use key app features.","sidebar":"pushnotifications"},"pushnotifications/index":{"id":"pushnotifications/index","title":"PushNotifications","description":"The Push Notifications extension allows you to receive and process push notifications using push notification services.","sidebar":"pushnotifications"},"pushnotifications/migrating-to-androidx":{"id":"pushnotifications/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"pushnotifications"},"pushnotifications/migrating-to-v10.1":{"id":"pushnotifications/migrating-to-v10.1","title":"Migrating to v10.1","description":"v10.1 brings the latest Firebase SDK which requires some changes to your application. Other services remain unchanged at this point.","sidebar":"pushnotifications"},"pushnotifications/migrating-to-v10.2":{"id":"pushnotifications/migrating-to-v10.2","title":"Migrating to v10.2","description":"v10.2 brings the latest release of OneSignal:","sidebar":"pushnotifications"},"pushnotifications/migrating-to-v11.2":{"id":"pushnotifications/migrating-to-v11.2","title":"Migrating to v11.2","description":"v11.2 brings the latest release of OneSignal:","sidebar":"pushnotifications"},"pushnotifications/migrating-to-v11.3":{"id":"pushnotifications/migrating-to-v11.3","title":"Migrating to v11.3","description":"v11.3 brings an updated process for requesting permissions on Android.","sidebar":"pushnotifications"},"pushnotifications/migrating-to-v13.0":{"id":"pushnotifications/migrating-to-v13.0","title":"Migrating to v13.0","description":"v13.0 separates out some firebase dependencies in order that other services can be used in preference.","sidebar":"pushnotifications"},"pushnotifications/notification-scenarios":{"id":"pushnotifications/notification-scenarios","title":"Notification Scenarios","description":"Foreground, background - Notification Scenarios","sidebar":"pushnotifications"},"pushnotifications/onesignal/add-the-extension":{"id":"pushnotifications/onesignal/add-the-extension","title":"OneSignal","description":"OneSignal is a high volume and reliable push notification service for websites and mobile applications. They support all major native and mobile platforms by providing dedicated SDKs for each platform, a RESTful server API, and an online dashboard for marketers to design and send push notifications.","sidebar":"pushnotifications"},"pushnotifications/onesignal/amazon":{"id":"pushnotifications/onesignal/amazon","title":"Amazon SDK Setup","description":"If you wish to use Amazon device messaging in OneSignal you will need to do some additional changes to your installation."},"pushnotifications/onesignal/huawei":{"id":"pushnotifications/onesignal/huawei","title":"Huawei SDK Setup","description":"If you wish to use Huawei Push services (via Huawei Mobile Services (HMS)) you will need to do some additional changes to your installation.","sidebar":"pushnotifications"},"pushnotifications/onesignal/migrating-to-v7.5":{"id":"pushnotifications/onesignal/migrating-to-v7.5","title":"OneSignal - Migrating to v7.5","description":"Migrating"},"pushnotifications/onesignal/onesignal":{"id":"pushnotifications/onesignal/onesignal","title":"Setup","description":"OneSignal provides a simple interface to push notifications, letting content creators focus on quality user engagement instead of complex implementation.","sidebar":"pushnotifications"},"pushnotifications/onesignal/quick-start":{"id":"pushnotifications/onesignal/quick-start","title":"OneSignal - Quick Start","description":"- Setup OneSignal Account"},"pushnotifications/onesignal/setup-your-service":{"id":"pushnotifications/onesignal/setup-your-service","title":"Setup your Service - OneSignal","description":"OneSignal does most of the initialisation of your application from the server so you should","sidebar":"pushnotifications"},"pushnotifications/onesignal/signing":{"id":"pushnotifications/onesignal/signing","title":"OneSignal - Signing","description":"This is no longer required from AIR 30+"},"pushnotifications/pushy/pushy":{"id":"pushnotifications/pushy/pushy","title":"Pushy","description":"The pushy implementation is currently unmaintained, if you require an update to this service please contact our support and we will look into it for you.","sidebar":"pushnotifications"},"pushnotifications/pushy/pushy-message":{"id":"pushnotifications/pushy/pushy-message","title":"Pushy Message","description":"To send a message to a device registered with Pushy you can use the Pushy REST API from your backend","sidebar":"pushnotifications"},"pushnotifications/pushy/pushy-payload":{"id":"pushnotifications/pushy/pushy-payload","title":"Pushy Payload","description":"The payload for a pushy notification has two distinct sections for iOS and Android.","sidebar":"pushnotifications"},"pushnotifications/receiving-notifications":{"id":"pushnotifications/receiving-notifications","title":"Receiving notifications","description":"There are several events that can be dispatched by a notification.","sidebar":"pushnotifications"},"pushnotifications/register-for-notifications":{"id":"pushnotifications/register-for-notifications","title":"Register for notifications","description":"Now that you have authorisation to access push notifications you can register your user\'s device.","sidebar":"pushnotifications"},"pushnotifications/request-authorisation":{"id":"pushnotifications/request-authorisation","title":"Request Authorisation","description":"After setting up your service you should check whether the device has given your application authorisation to register and display notifications.","sidebar":"pushnotifications"},"pushnotifications/set-badge-number":{"id":"pushnotifications/set-badge-number","title":"Set Badge Number","description":"You can set the badge number using this extension. The badge number is the small number","sidebar":"pushnotifications"},"pushnotifications/setup-your-service":{"id":"pushnotifications/setup-your-service","title":"Setup your Service","description":"Core Initialisation","sidebar":"pushnotifications"},"pushnotifications/sounds":{"id":"pushnotifications/sounds","title":"Sounds","description":"The following documentation describes how to get custom sounds to play when your notification arrives.","sidebar":"pushnotifications"},"pushnotifications/tags":{"id":"pushnotifications/tags","title":"Tags","description":"Tags are used by some services to assign variables to a user. This can then be used by the service to selective send notifications or to substitute variables in a notification to provide highly customised interactions with your users.","sidebar":"pushnotifications"},"pushnotifications/topics":{"id":"pushnotifications/topics","title":"Topics","description":"Some services support subscribing to \\"topics\\".","sidebar":"pushnotifications"},"pushnotifications/user-consent":{"id":"pushnotifications/user-consent","title":"User Consent","description":"Currently only available for the OneSignal service implementation. Other services you will have to implement manually.","sidebar":"pushnotifications"},"pushnotifications/windows/add-the-extension":{"id":"pushnotifications/windows/add-the-extension","title":"Windows Push Notification Services","description":"The Windows Push Notification Services (WNS) enable third-party developers to send toast, tile, badge, and raw updates from their own cloud service. This provides a mechanism to deliver new updates to your users in a power-efficient and dependable way.","sidebar":"pushnotifications"},"pushnotifications/windows/windows-notification-service":{"id":"pushnotifications/windows/windows-notification-service","title":"Setup WNS","description":"- AppxManifest additions","sidebar":"pushnotifications"},"pushnotifications/windows/windows-wns-message":{"id":"pushnotifications/windows/windows-wns-message","title":"Windows WNS Message","description":"In order to send a message to WNS you will need the information you noted from the service setup:","sidebar":"pushnotifications"},"pushnotifications/windows/windows-wns-payload":{"id":"pushnotifications/windows/windows-wns-payload","title":"Windows WNS Payload","description":"The payload for the WNS notificaiton contains a Windows Toast XML structure.","sidebar":"pushnotifications"},"reactivex/changelog":{"id":"reactivex/changelog","title":"changelog","description":""},"restartapp/add-the-extension":{"id":"restartapp/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"restartapp"},"restartapp/changelog":{"id":"restartapp/changelog","title":"changelog","description":"2023.02.01 [v3.1.0]","sidebar":"restartapp"},"restartapp/index":{"id":"restartapp/index","title":"Restart App","description":"This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:","sidebar":"restartapp"},"restartapp/restart-application":{"id":"restartapp/restart-application","title":"Restart Application","description":"Restarting the application is simply a matter of calling the restartApplication() method:","sidebar":"restartapp"},"rootchecker/add-the-extension":{"id":"rootchecker/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"rootchecker"},"rootchecker/changelog":{"id":"rootchecker/changelog","title":"changelog","description":"2023.02.01 [v1.1.0]","sidebar":"rootchecker"},"rootchecker/index":{"id":"rootchecker/index","title":"Root Checker","description":"The RootChecker extension","sidebar":"rootchecker"},"rootchecker/root-check":{"id":"rootchecker/root-check","title":"Root Check","description":"To check whether the device has been \\"rooted\\" or jail broken you check the isRooted flag.","sidebar":"rootchecker"},"scanner/add-the-extension":{"id":"scanner/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"scanner"},"scanner/changelog":{"id":"scanner/changelog","title":"changelog","description":"2023.01.25 [v5.1.0]","sidebar":"scanner"},"scanner/index":{"id":"scanner/index","title":"Scanner","description":"The Scanner extension allows you to display an interface using the camera to scan for codes such as QR Codes, bar codes and other such encoded information. It supports many popular symbologies (types of bar codes) including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.","sidebar":"scanner"},"scanner/migrating-to-androidx":{"id":"scanner/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"scanner"},"scanner/migrating-to-v5.1":{"id":"scanner/migrating-to-v5.1","title":"Migrating to v5.1","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"scanner"},"scanner/migrating-to-version-5":{"id":"scanner/migrating-to-version-5","title":"Migrating to version 5","description":"Version 5 brings several new features including:","sidebar":"scanner"},"scanner/requesting-access":{"id":"scanner/requesting-access","title":"Requesting Access","description":"If you are going to be using one of the camera methods then you need to ensure you have","sidebar":"scanner"},"scanner/scanning":{"id":"scanner/scanning","title":"Scanning","description":"Once you have setup your application and gained permission to access the camera, then there are three approaches you can take to scan, 2 that utilise the camera directly and a third option to scan a provided image.","sidebar":"scanner"},"scanner/scanning-bitmap-data":{"id":"scanner/scanning-bitmap-data","title":"Scanning Bitmap Data","description":"This method of scanning doesn\'t utilise the camera directly, instead you can use other methods to acquire image data and use the extension to scan the image for any symbols directly.","sidebar":"scanner"},"sensormanager/add-the-extension":{"id":"sensormanager/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"sensormanager"},"sensormanager/changelog":{"id":"sensormanager/changelog","title":"changelog","description":"2023.02.01 [v1.1.0]","sidebar":"sensormanager"},"sensormanager/index":{"id":"sensormanager/index","title":"SensorManager","description":"The SensorManager extension gives you the ability to retrieve data from the device sensors.","sidebar":"sensormanager"},"sensormanager/proximity":{"id":"sensormanager/proximity","title":"Proximity","description":"The proximity sensor is a sensor that lets you determine how close the face of a device is to an object (known as the proximity sensor). Most commonly this is used to detect if the user is holding the device to their face (eg during a phone call) so that the device can deactivate the screen and controls.","sidebar":"sensormanager"},"share/add-the-extension":{"id":"share/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"share"},"share/add-the-plugin":{"id":"share/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"share"},"share/android-events":{"id":"share/android-events","title":"Android Events","description":"A small note about events on Android.","sidebar":"share"},"share/appextension---introduction":{"id":"share/appextension---introduction","title":"AppExtension - Introduction","description":"Introduction","sidebar":"share"},"share/appextension---setup":{"id":"share/appextension---setup","title":"AppExtension - Setup","description":"App Extension basics","sidebar":"share"},"share/appextension---share-extension":{"id":"share/appextension---share-extension","title":"AppExtension - Share Extension","description":"Share Extension Functionality","sidebar":"share"},"share/changelog":{"id":"share/changelog","title":"changelog","description":"2023.07.06 [v7.6.0]","sidebar":"share"},"share/email":{"id":"share/email","title":"Email","description":"Support","sidebar":"share"},"share/index":{"id":"share/index","title":"Share","description":"The Share extension gives you access to the default share menu to send files and information to other applications. You can use one simple line of AS3 / C# to display the built-in native share dialogs allowing your user to share files and content with other applications.","sidebar":"share"},"share/launch-applications":{"id":"share/launch-applications","title":"Launch Applications","description":"This function allows your application to start another application on the device.","sidebar":"share"},"share/migrating-from-message":{"id":"share/migrating-from-message","title":"Migrating from Message","description":"From version 5.0, we have added all of the Message ANE functionality to this ANE and will eventually be deprecating the Message ANE in favour of this Share ANE.","sidebar":"share"},"share/migrating-to-androidx":{"id":"share/migrating-to-androidx","title":"Migrating to AndroidX","description":"Android X","sidebar":"share"},"share/migrating-to-v7.4":{"id":"share/migrating-to-v7.4","title":"Migrating to v7.4","description":"This version brings an updated process for requesting permissions on Android.","sidebar":"share"},"share/positioning":{"id":"share/positioning","title":"Positioning","description":"In general the share dialog is presented as a slide up dialog presenting the available sharing options.","sidebar":"share"},"share/share-files":{"id":"share/share-files","title":"Share Files","description":"There are two operations regarding files exposed by this ANE, referred to as sharing a file (shareFile) and opening a file (showOpenIn).","sidebar":"share"},"share/simple-share":{"id":"share/simple-share","title":"Simple Share","description":"Displaying an action to share text, image data or/and URL is simply a process of calling share() with data you wish to share.","sidebar":"share"},"share/sms":{"id":"share/sms","title":"SMS","description":"SMS Supported","sidebar":"share"},"share/unity":{"id":"share/unity","title":"Unity","description":"Contents"},"singular/add-the-extension":{"id":"singular/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"singular"},"singular/advanced-options":{"id":"singular/advanced-options","title":"Advanced Options","description":"Creating Short Referrer Links","sidebar":"singular"},"singular/changelog":{"id":"singular/changelog","title":"changelog","description":"2023.10.30 [v12.1.105]","sidebar":"singular"},"singular/index":{"id":"singular/index","title":"Singular","description":"The Singular extension gives you access to the Singular SDK for anayltics.","sidebar":"singular"},"singular/initialise":{"id":"singular/initialise","title":"Initialise","description":"Creating a Configuration Object","sidebar":"singular"},"singular/tracking-events":{"id":"singular/tracking-events","title":"Tracking Events and Revenue","description":"Singular can collect data about in-app events to help analyze the performance of your campaigns and measure KPIs. For example, your organization may want to collect data about user logins, registrations, tutorial completions, or leveling up in a gaming app.","sidebar":"singular"},"speech/add-the-extension":{"id":"speech/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"speech"},"speech/authorisation":{"id":"speech/authorisation","title":"Authorisation","description":"In order to use the speech recognition functionality you must first request certain permissions from the user.","sidebar":"speech"},"speech/changelog":{"id":"speech/changelog","title":"changelog","description":"2023.10.19 [v2.0.1]","sidebar":"speech"},"speech/index":{"id":"speech/index","title":"Speech","description":"The Speech extension","sidebar":"speech"},"speech/recognition":{"id":"speech/recognition","title":"Speech Recognition","description":"All speech recognition functionality is handled through the SpeechRecogniser interface which can be accessed through the recogniser property on the main extension: Speech.instance.recogniser.","sidebar":"speech"},"speech/texttospeech":{"id":"speech/texttospeech","title":"Text to Speech","description":"All text-to-speech functionality is handled through the TextToSpeech interface which can be accessed through the tts property on the main extension: Speech.instance.tts.","sidebar":"speech"},"square libs/changelog":{"id":"square libs/changelog","title":"changelog","description":"2023.03.27 [v4.2.0]"},"squarelibs/changelog":{"id":"squarelibs/changelog","title":"changelog","description":"2022.05.04 [v4.1.0]"},"styles":{"id":"styles","title":"styles","description":"You can write content using GitHub-flavored Markdown syntax."},"systemgestures/add-the-extension":{"id":"systemgestures/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"systemgestures"},"systemgestures/changelog":{"id":"systemgestures/changelog","title":"changelog","description":"2023.01.27 [v2.2.0]","sidebar":"systemgestures"},"systemgestures/defer-system-gestures":{"id":"systemgestures/defer-system-gestures","title":"Defer System Gestures","description":"On iOS 11 Apple has introduced a range of system gestures to interact with the OS without having to use the physical home button, such as to display Control Center.","sidebar":"systemgestures"},"systemgestures/home-indicator":{"id":"systemgestures/home-indicator","title":"Home Indicator","description":"On certain iOS devices there is a visual home indicator for returning to the home screen. This appears as a white bar towards the bottom of the screen.","sidebar":"systemgestures"},"systemgestures/index":{"id":"systemgestures/index","title":"SystemGestures","description":"This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:","sidebar":"systemgestures"},"systemgestures/native-gesture-events":{"id":"systemgestures/native-gesture-events","title":"Native Gesture Events","description":"General Gestures","sidebar":"systemgestures"},"tutorials/android-adaptive-icons":{"id":"tutorials/android-adaptive-icons","title":"Android Adaptive Icons","description":"Android 8.0 (API level 26) introduces adaptive launcher icons, which can display a variety of shapes across different device models. For example, an adaptive launcher icon can display a circular shape on one OEM device, and display a squircle on another device. Each device OEM provides a mask, which the system then uses to render all adaptive icons with the same shape. Adaptive launcher icons are also used in shortcuts, the Settings app, sharing dialogs, and the overview screen.","sidebar":"tutorials"},"tutorials/android-device-debugging":{"id":"tutorials/android-device-debugging","title":"Android Device Debugging","description":"Android","sidebar":"tutorials"},"tutorials/android-resources":{"id":"tutorials/android-resources","title":"Android Resources","description":"With Android additional files and static content are defined as resources, this includes images, layouts, strings, configuration, icons and more.","sidebar":"tutorials"},"tutorials/android-splash-screen":{"id":"tutorials/android-splash-screen","title":"Android Splash Screen","description":"Android doesn\'t have a built in method of displaying an image at launch like iOS does however there are some techniques we can use to achieve a similar goal.","sidebar":"tutorials"},"tutorials/device-logs":{"id":"tutorials/device-logs","title":"Device Logs","description":"Getting access to the device logs often yields additional information when attempting to isolate an issue with an ANE. We may sometimes ask for you to provide these logs in order for us to debug an issue or isolate a problem.","sidebar":"tutorials"},"tutorials/getting-started":{"id":"tutorials/getting-started","title":"Adding an Extension","description":"These tutorials will cover adding a Native Extension for Adobe AIR to your application.","sidebar":"tutorials"},"tutorials/getting-started-animate":{"id":"tutorials/getting-started-animate","title":"Getting Started - Animate","description":"This tutorial will guide you the process of adding an ANE to your AIR application project in Adobe Animate.","sidebar":"tutorials"},"tutorials/getting-started-flashbuilder4.5":{"id":"tutorials/getting-started-flashbuilder4.5","title":"Getting Started - Flash Builder 4.5","description":"An AIR Native Extension (ANE) is a single file with the extension ane. This file contains all of the native and actionscript libraries that are implemented by this extension. You don\u2019t need access to a separate SWC file or to the source code to be able to use the ANE.","sidebar":"tutorials"},"tutorials/getting-started-flashbuilder4.7":{"id":"tutorials/getting-started-flashbuilder4.7","title":"Getting Started - Flash Builder 4.6/4.7","description":"Add the Extension","sidebar":"tutorials"},"tutorials/getting-started-flashdevelop":{"id":"tutorials/getting-started-flashdevelop","title":"Getting Started - Flash Develop","description":"This tutorial will guide you the process of adding an ANE to your AIR application project in FlashDevelop.","sidebar":"tutorials"},"tutorials/getting-started-intellij":{"id":"tutorials/getting-started-intellij","title":"Getting Started - IntelliJ","description":"This tutorial will guide you the process of adding an ANE to your AIR application project in IntelliJ IDEA.","sidebar":"tutorials"},"tutorials/index":{"id":"tutorials/index","title":"Tutorials","description":"This site contains a range of tutorials for using native extensions in your applications.","sidebar":"tutorials"},"tutorials/ios-icons-assets-car":{"id":"tutorials/ios-icons-assets-car","title":"Icons, Launch Storyboards and the Assets Catalog","description":"From iOS 11 Apple now requires a new process of adding icons to your application, you can no longer simply package them as you have done with previous versions of iOS and AIR. Instead you need to create an asset catalog (Assets.car file) and package in the root directory of your application.","sidebar":"tutorials"},"tutorials/ios-launchscreens":{"id":"tutorials/ios-launchscreens","title":"Launchscreen","description":"From iOS 13 Apple now requires a new process of adding launch / splash screens to your application, you can no longer simply package the \\"default.png\\" images in your application you have done with previous versions of iOS and AIR.","sidebar":"tutorials"},"tutorials/ios-sdk-custom":{"id":"tutorials/ios-sdk-custom","title":"iOS SDK","description":"In the particular case of developing for iOS it is quite often a requirement that you have access to the iOS SDK to access the most recent features of the SDK.","sidebar":"tutorials"},"tutorials/ios-sdk-versions":{"id":"tutorials/ios-sdk-versions","title":"iOS SDK Versions","description":"This document contains notes on integration with AIR of various versions of the iOS platform.","sidebar":"tutorials"},"tutorials/windows-appx-packaging":{"id":"tutorials/windows-appx-packaging","title":"Windows Store Packaging","description":"The Desktop App Converter can be used to turn your AIR application into an appx installer for the Windows Store. This is an important process to be able to convert your AIR app into a UWP application.","sidebar":"tutorials"},"tutorials/windows-appx-packaging-method1":{"id":"tutorials/windows-appx-packaging-method1","title":"Windows Store Packaging - Method 1","description":"This method gives the most versatility in editing the final package you create, giving you the ability to make changes to the AppxManifest. Additionally it simplifies testing as you only need to install a single test certificate on your machine.","sidebar":"tutorials"},"tutorials/windows-appx-packaging-method2":{"id":"tutorials/windows-appx-packaging-method2","title":"Windows Store Packaging - Method 2","description":"Create appx from your AIR executable","sidebar":"tutorials"},"tutorials/windows-appx-packaging-method3":{"id":"tutorials/windows-appx-packaging-method3","title":"Windows Store Packaging - Method 3","description":"Using an Installer for your AIR application","sidebar":"tutorials"},"unityads/add-the-extension":{"id":"unityads/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"unityads"},"unityads/changelog":{"id":"unityads/changelog","title":"changelog","description":"2023.09.11 [v4.8.0]","sidebar":"unityads"},"unityads/index":{"id":"unityads/index","title":"UnityAds","description":"The UnityAds extension gives you access to Unity Ads in your AIR application.","sidebar":"unityads"},"unityads/initialise":{"id":"unityads/initialise","title":"Initialising the SDK","description":"To initialize the SDK, you must reference your Project\u2019s Game ID for the appropriate platform. You can locate the ID on the Monetization dashboard by selecting CURRENT PROJECT > Project Settings from the secondary navigation menu.","sidebar":"unityads"},"unityads/interstitials":{"id":"unityads/interstitials","title":"Interstitials","description":"You must initialise the SDK before attempting to load and display ads.","sidebar":"unityads"},"vibration/add-the-extension":{"id":"vibration/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"vibration"},"vibration/add-the-plugin":{"id":"vibration/add-the-plugin","title":"Add the Plugin","description":"First step is always to add the plugin to your development environment.","sidebar":"vibration"},"vibration/changelog":{"id":"vibration/changelog","title":"changelog","description":"2023.01.25 [v5.2.0]","sidebar":"vibration"},"vibration/feedback-generators":{"id":"vibration/feedback-generators","title":"Feedback Generators","description":"Haptic feedback provides a tactile response, such as a tap, that draws attention and reinforces both actions and events. While many system-provided interface elements (for example, pickers, switches, and sliders) automatically provide haptic feedback, you can use feedback generators to add your own feedback to custom views and controls.","sidebar":"vibration"},"vibration/haptic-engine":{"id":"vibration/haptic-engine","title":"Haptic Engine","description":"Compose and play haptic patterns to customize your app\u2019s feedback.","sidebar":"vibration"},"vibration/index":{"id":"vibration/index","title":"Vibration","description":"The Vibration extension provides access to a device\'s native vibration capabilities.","sidebar":"vibration"},"vibration/unity":{"id":"vibration/unity","title":"Unity","description":"Contents"},"vibration/vibrate":{"id":"vibration/vibrate","title":"Vibrate","description":"To make the device vibrate is a simple matter of calling the vibrate function.","sidebar":"vibration"},"volume/add-the-extension":{"id":"volume/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"volume"},"volume/changelog":{"id":"volume/changelog","title":"changelog","description":"2023.01.25 [v3.2.0]","sidebar":"volume"},"volume/index":{"id":"volume/index","title":"Volume","description":"The Volume extension","sidebar":"volume"},"volume/silent-switch":{"id":"volume/silent-switch","title":"Silent Switch","description":"Currently this is only available for the iOS silent switch. It does not work with the","sidebar":"volume"},"volume/streams":{"id":"volume/streams","title":"Streams","description":"Android","sidebar":"volume"},"volume/volume-control":{"id":"volume/volume-control","title":"Volume Control","description":"Retrieving and setting the volume","sidebar":"volume"},"webp/add-the-extension":{"id":"webp/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"webp"},"webp/changelog":{"id":"webp/changelog","title":"changelog","description":"2023.02.01 [v4.1.0]","sidebar":"webp"},"webp/index":{"id":"webp/index","title":"WebP","description":"The WebP extension","sidebar":"webp"},"webp/load-a-webp-file":{"id":"webp/load-a-webp-file","title":"Load a WebP File","description":"If you have access to a WebP file you can use the loadWebPBitmapData function","sidebar":"webp"},"webp/parse-webp-data":{"id":"webp/parse-webp-data","title":"Parse WebP Data","description":"If you load data from a URL or other data source you can use the parseWebP","sidebar":"webp"},"webp/webploader":{"id":"webp/webploader","title":"WebPLoader","description":"Asynchronous Loading using the WebPLoader","sidebar":"webp"},"windowsstore/add-the-extension":{"id":"windowsstore/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"windowsstore"},"windowsstore/changelog":{"id":"windowsstore/changelog","title":"changelog","description":"2023.02.01 [v1.4.0]","sidebar":"windowsstore"},"windowsstore/consumables":{"id":"windowsstore/consumables","title":"Consumables","description":"Consumable products can be consumed by the user and purchased again.","sidebar":"windowsstore"},"windowsstore/index":{"id":"windowsstore/index","title":"WindowsStore","description":"The WindowsStore extension","sidebar":"windowsstore"},"windowsstore/initialise-the-extension":{"id":"windowsstore/initialise-the-extension","title":"Initialise the Extension","description":"You should perform this once in your application by calling the setup() method. This initialises the extension and internally sets up the native extension implementation.","sidebar":"windowsstore"},"windowsstore/make-purchase":{"id":"windowsstore/make-purchase","title":"Make Purchase","description":"In order to purchase a product you will construct a PurchaseRequest object and pass it to the makePurchase function.","sidebar":"windowsstore"},"windowsstore/products":{"id":"windowsstore/products","title":"Products","description":"Query product information","sidebar":"windowsstore"},"windowsstore/purchases":{"id":"windowsstore/purchases","title":"Purchases","description":"Get Purchases","sidebar":"windowsstore"},"windowsstore/windows-desktop-app-converter":{"id":"windowsstore/windows-desktop-app-converter","title":"Windows-Desktop App Converter","description":"The Desktop App Converter can be used to turn your AIR application into an appex installer for the Windows Store. This is an important process to be able to convert your AIR app into a UWP application.","sidebar":"windowsstore"},"windowsstore/windows-developer-account":{"id":"windowsstore/windows-developer-account","title":"Windows-Developer Account","description":"The first step is to sign up for a Windows Developer account. You must have an account","sidebar":"windowsstore"},"windowsstore/windows-overview":{"id":"windowsstore/windows-overview","title":"Windows-Overview","description":"Getting your AIR application to run on the Windows Store requires you to go through","sidebar":"windowsstore"},"ziputils/add-the-extension":{"id":"ziputils/add-the-extension","title":"Add the Extension","description":"The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).","sidebar":"ziputils"},"ziputils/changelog":{"id":"ziputils/changelog","title":"changelog","description":"2023.01.27 [v3.1.0]","sidebar":"ziputils"},"ziputils/index":{"id":"ziputils/index","title":"ZipUtils","description":"The ZipUtils extension","sidebar":"ziputils"},"ziputils/unzipping-a-file":{"id":"ziputils/unzipping-a-file","title":"Unzipping a file","description":"To unzip a file call the unzip function. This will unzip the specified zip file","sidebar":"ziputils"},"ziputils/zipping":{"id":"ziputils/zipping","title":"Zipping","description":"To compress an entire directory into a zip file you use the zip() function.","sidebar":"ziputils"}}}')}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.394ca64f.js b/assets/js/runtime~main.ccf4ba71.js similarity index 99% rename from assets/js/runtime~main.394ca64f.js rename to assets/js/runtime~main.ccf4ba71.js index 53f162e66be..127824ccabe 100644 --- a/assets/js/runtime~main.394ca64f.js +++ b/assets/js/runtime~main.ccf4ba71.js @@ -1 +1 @@ -!function(){"use strict";var e,c,d,f,b,a={},t={};function n(e){var c=t[e];if(void 0!==c)return c.exports;var d=t[e]={exports:{}};return a[e].call(d.exports,d,d.exports,n),d.exports}n.m=a,e=[],n.O=function(c,d,f,b){if(!d){var a=1/0;for(i=0;i=b)&&Object.keys(n.O).every((function(e){return n.O[e](d[r])}))?d.splice(r--,1):(t=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[d,f,b]},n.n=function(e){var c=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(c,{a:c}),c},d=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},n.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var b=Object.create(null);n.r(b);var a={};c=c||[null,d({}),d([]),d(d)];for(var t=2&f&&e;"object"==typeof t&&!~c.indexOf(t);t=d(t))Object.getOwnPropertyNames(t).forEach((function(c){a[c]=function(){return e[c]}}));return a.default=function(){return e},n.d(b,a),b},n.d=function(e,c){for(var d in c)n.o(c,d)&&!n.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:c[d]})},n.f={},n.e=function(e){return Promise.all(Object.keys(n.f).reduce((function(c,d){return n.f[d](e,c),c}),[]))},n.u=function(e){return"assets/js/"+({162:"13e3485d",195:"cb3277ce",440:"bb778a53",632:"3649c6e5",808:"6f4cc41c",820:"68637bd9",840:"bb7a524b",983:"a1b5ebbc",995:"243e72d0",1057:"ff61ba43",1181:"794bdbe1",1522:"743a4eda",1545:"c5c8c8ef",1557:"ddbbbc81",1642:"76e4ba13",1679:"8f64645b",1869:"a44a17a7",1890:"185176c3",2039:"72e33197",2044:"faa207b7",2082:"3ff77dc6",2085:"56026b06",2246:"7537a64e",2309:"2cc315c3",2447:"e9c16141",2492:"1f309900",2514:"b0386327",2657:"6217abc0",2951:"3524c5f4",3082:"4ab280a7",3084:"7087d0c3",3122:"7c148484",3174:"33b5d490",3421:"922937a2",3433:"5b77a007",3523:"bcd8dacd",3640:"e5ff2770",3814:"0e2a33af",3837:"13e8f167",3925:"44773ce0",4018:"8e160d92",4027:"d84ee27c",4030:"37ddad66",4309:"705de539",4319:"68a83471",4391:"770ebbdf",4483:"bd6c7714",4676:"09693916",4734:"3baded6d",4845:"2762efe5",4893:"7c9af93f",5020:"68c32018",5104:"6f879726",5218:"c453f0e4",5256:"6b356f46",5276:"e8767721",5326:"7b64eba0",5347:"bd01da59",5548:"a69d3c33",5701:"97e02059",5723:"c5f713a3",5844:"0563c9d5",5877:"24a18380",5912:"2f19675a",6008:"f0a6555f",6133:"c0258d9a",6302:"bfe05aa5",6337:"c270329b",6358:"98b86d9d",6645:"ad714920",6657:"a1dfeec9",6729:"d253f400",6886:"14786350",6981:"4161038c",7216:"13476308",7544:"e63cab04",7732:"17c09b7c",7752:"60a734f8",7860:"3aa2f437",8081:"759b040c",8155:"df4148ce",8346:"fc4fbc82",8393:"4e8ceca4",8420:"336e2d10",8652:"ed44cee0",8697:"d28c071c",8699:"988b121f",8862:"bcac2d32",9139:"b5429f5c",9192:"1b47644e",9246:"0b9486e1",9251:"ba71f315",9253:"689bb653",9564:"66f2530f",9569:"ce6c3cc7",9636:"7ff944dd",9711:"d21a5299",9943:"ec1c65d9",10061:"5a2fa176",10077:"ccc9a6ae",10194:"6196e3e3",10199:"b49f544b",10212:"be55fd82",10288:"16e30885",10377:"6508b81f",10480:"aa212d2b",10488:"389c677e",10735:"b0aef227",10741:"a958a1fe",10773:"71adf2b1",10777:"3dbac566",10827:"63c71228",10960:"61a58a31",11041:"ff28909e",11107:"3da7c7af",11110:"6ebc4cba",11152:"9cd6e596",11220:"f0f92231",11249:"891aa492",11367:"58b71341",11505:"311bd2e5",11519:"75afe063",11634:"74a562c5",11650:"7ff9befe",11695:"ef7a268d",11696:"1fe15ca1",11833:"6db7791b",11858:"46e74a12",11988:"f9c59cec",12471:"b05903c6",12493:"93ddc768",12537:"0ed266fd",12539:"d944851e",12615:"0f5e5ca9",12691:"cdc8bb25",13178:"6cd5e3a2",13195:"2da7ffca",13211:"ae13eaec",13267:"c4930dbf",13334:"3ad6345f",13358:"bc92a7eb",13399:"b34a828c",13430:"647b836a",13548:"414dceb8",13571:"9de038fa",13703:"cd8681d0",13854:"30bd281c",13924:"ec58503a",14016:"691b4103",14080:"d554986d",14089:"ee30c4f9",14133:"930794af",14489:"814cc783",14493:"bdeb18d1",14518:"f82bf1a9",14582:"4bd0cf30",14642:"a92f2c1a",14645:"5539d89b",14678:"c0b7d35c",14730:"c5af1cfc",14917:"c352947e",14945:"f0c91146",14966:"113776ae",15002:"b056655e",15095:"53806931",15118:"a9bd30ef",15140:"8feaef3a",15289:"bd986f80",15364:"6b8da0f5",15542:"fa6d02c0",15595:"0b695c4c",15615:"546f9a01",15659:"293f897f",15674:"b1dd4c98",15729:"ef804dd5",15736:"f16842bc",15899:"8dfee272",15999:"bc553fd8",16080:"5e8955e2",16322:"825092a9",16378:"9352df78",16486:"a6282008",16613:"d5f4b9d1",16634:"a844fb09",16754:"4f47e7ff",16756:"c5b16d1f",16799:"46c9c1c9",16818:"aaa05763",17036:"b4cf7eb5",17135:"782a8136",17190:"f71d0279",17295:"60173ad8",17533:"5e051bf3",17545:"700f0253",17642:"59c3e71f",17694:"61db54ba",17738:"bab9f44d",17867:"a45fb5ce",18166:"16d03713",18291:"d4dbcd1c",18582:"78c7ae31",18591:"b5e83296",18750:"9f9d8d40",18859:"a82ee963",19048:"8aae2b08",19067:"fcfe1329",19116:"560c8c12",19117:"0cca7499",19308:"d91d5370",19374:"c5fec417",19380:"50229c5b",19626:"2631fa1d",19679:"f401bfc3",19704:"bcd8f52b",19731:"dd042142",19801:"0ed8251c",19879:"ae36b559",20044:"7a35d080",20062:"e090d8ec",20228:"36e4096d",20260:"33d8e434",20305:"9de99998",20562:"9c0b8d44",20611:"b04e19b4",20630:"698128b2",20683:"d6267b43",20701:"9615a67c",20751:"deaabb1b",20827:"5894833a",20977:"94149987",20999:"41b24fb6",21143:"954f6ca2",21155:"15780a71",21182:"a0a3786c",21199:"223dd6d0",21636:"f8b95006",21691:"7002472e",21725:"aacc87f2",21763:"d5e5f94d",21776:"337d9695",21962:"75bdd353",22070:"24cfd963",22083:"d3c558c0",22255:"d832a8ac",22350:"3da3a6d6",22529:"36daa823",22554:"afdd1fc6",22673:"3387b713",22771:"eb9a84fa",22800:"8e5feab1",22835:"fb671fd4",23097:"1267535a",23120:"be3cd489",23121:"9f8a86a1",23122:"4c7d3a3a",23221:"939a6763",23275:"a5437f03",23332:"334d840b",23372:"32908617",23422:"4f806ca3",23486:"8c541c4b",23522:"81ccd52a",23650:"12780c04",23685:"42cc23aa",23719:"449e4b0b",23770:"004cf658",23982:"369e0402",24155:"bf2bc35c",24428:"90d854df",24538:"022f887e",24595:"03f20467",24637:"955424a3",24782:"6566fc75",24813:"bf7338c5",24850:"cc579207",24877:"44f81e6d",24886:"a6aa9e1f",24949:"17890afa",25444:"89c378d1",25572:"10699eac",25586:"4660316f",25613:"b6d51dc3",26050:"04bfa6bb",26108:"ccfbddc7",26168:"9d36a906",26214:"1ee46a20",26241:"2700ec3c",26258:"0ebe73eb",26302:"4826d74f",26328:"9d2a5046",26351:"a2ed449e",26397:"76d9cc66",26407:"a54a8d17",26457:"076ee303",26647:"7cd5c344",26651:"48bf28e1",26958:"66024f8e",27015:"d317b305",27168:"21cde90b",27272:"c35068d2",27284:"a6b1e8f8",27329:"75d624f4",27378:"4e571b33",27628:"35fa06c0",27703:"68155fb2",27723:"ad2edd7e",27745:"82a67ce7",27787:"8b00c4b0",27802:"29071212",27864:"2f6e266f",27878:"56673e51",27918:"17896441",27939:"f241cd81",28085:"5be4f51b",28103:"0abffcbf",28171:"2f8d21d9",28261:"29aa1ed4",28323:"2f322c00",28336:"9c6fee4d",28370:"246a7b8b",28414:"7d694b3a",28527:"c2fdb40c",28681:"cf76520a",28793:"ef3dde2a",28837:"f4d5a234",28993:"f42bcbd0",29092:"b3eec62e",29285:"05459498",29506:"03677e6b",29514:"1be78505",29555:"9d1c6e84",29583:"d30fc371",29630:"49cc842f",29657:"8d7eb0a9",29723:"290da131",29757:"6eeb9991",29796:"27dfa723",29820:"e072863c",30280:"106c104b",30325:"8caeb3b9",30340:"cdd3f1f6",30368:"2b7573de",30495:"386aa01b",30555:"6aa8e49e",30572:"cd671aaf",30578:"f84a6e3d",30672:"d6b80958",30738:"88d80bd2",30743:"b3f3a0dd",30747:"8b800d35",30782:"e0e5cf54",30954:"34e6a6da",31002:"2999b41c",31091:"134bb968",31110:"e56832f8",31213:"3978a105",31330:"728415ec",31574:"9f024f64",31595:"afa4c90b",31604:"b00c33b0",31642:"75222a8a",31952:"0eb9886d",31968:"eafdc628",32035:"0651460a",32351:"72c63364",32361:"bb2fcf03",32562:"3c24c133",32620:"456e6daf",32646:"e30582b2",32718:"841d3558",32734:"55cf730b",32771:"23808f4f",32829:"8257120c",32856:"11ce2a18",32894:"4b60f83c",32928:"d743a660",32952:"081694b1",33548:"01cb8778",33567:"89e61cb7",33609:"14f03e77",33620:"8fe15bf0",33789:"d4c80b47",33881:"6ba27067",33922:"a90ce6d1",33950:"9694a7fb",34151:"d8d794e7",34173:"4edc808e",34203:"083e9c39",34238:"80551706",34249:"b2125466",34274:"4bbbca70",34287:"706ef0f8",34465:"0a4ab38e",34523:"93217873",34842:"754c8a51",34929:"5baeeec9",34952:"c941472e",35120:"cf17176c",35211:"1f2b5bee",35298:"113e98af",35565:"aa913c04",35616:"3fb6235c",35647:"d72a3e67",35886:"7f320937",35936:"ef8205f2",35973:"3f977937",36021:"038896b4",36077:"ba36f8fe",36099:"ad65305a",36180:"c01205be",36186:"4f8081aa",36377:"710acf16",36529:"290901e5",36569:"99231e2c",36757:"6c1cfff2",36779:"98a54395",36836:"fea1970e",36861:"3a66a8a7",36975:"ce23889d",36996:"2ab3c725",37104:"6b6a2525",37163:"475e419a",37255:"15658e7c",37338:"eb0eeb72",37631:"d1d6cc97",37883:"8fb395ee",37952:"f92a140f",38181:"3b0faa55",38189:"0b90df17",38371:"b8053e79",38788:"b29eae3f",38811:"02e9015f",38891:"185baa7b",38993:"268b4470",39093:"2a00a656",39190:"e99d4187",39212:"727aa2eb",39300:"c4a8d8d0",39343:"424f41d9",39399:"0cd24d44",39468:"047da02a",39553:"a68f12d5",39773:"f9442607",39977:"8537e111",40003:"71753d0f",40028:"e9c01433",40116:"d1e17e98",40193:"12a75feb",40265:"cf2b6063",40504:"d064531f",40601:"bdf736ae",40659:"feb1b108",40948:"e32ba394",40951:"f311171d",40967:"19e5c8a8",40993:"ee505f00",41331:"c2f6c957",41344:"fea316db",41403:"7851fb52",41750:"226f60b4",41771:"9af0ca03",41784:"24584499",41933:"7984f828",42013:"38f15e71",42115:"07102b8e",42134:"f3edbbcb",42203:"d635135b",42214:"a2f86c00",42314:"0d4ee96f",42495:"c7a4a619",42506:"cb838682",42553:"1b71fe77",42609:"b2b7991b",42677:"ec62adee",42791:"126a8b5f",42815:"a70a1ced",42919:"15747b1c",42960:"efb761db",42978:"9f698d42",43055:"ffb17bf3",43085:"9bbe3ea4",43267:"2ce4181b",43361:"7e04375a",43763:"7b531316",43837:"7b239f86",43930:"fe18b0a2",44032:"f2bdb430",44049:"609f11c2",44235:"4bcd5de8",44247:"ae652fc3",44258:"333eac1e",44308:"5a955209",44401:"7352eb09",44426:"a433c715",44509:"394e3983",44561:"3d4c5a33",44973:"4dbe51d0",44984:"84f16505",45020:"95740546",45049:"3ac517d3",45314:"e6dc52c7",45443:"70de807c",45709:"e56ba3b9",45728:"dc04fbfa",45906:"08b05c06",45992:"aa8793a0",46076:"65f8b24f",46103:"ccc49370",46200:"7ef80d56",46360:"f6fa4812",46408:"7a50e73a",46609:"5aa2a2dd",46628:"353ce9a8",46687:"76cf8a26",46708:"1580ff85",46744:"e48737d3",46797:"e7700274",46852:"20e259dc",46869:"78514b8e",47049:"6e0506f8",47133:"f51e1b21",47324:"23886185",47404:"5042ad53",47487:"4d1b1010",47567:"2b29dd21",47658:"5c710130",47713:"34e3dd60",47734:"67bf6aac",47740:"85d5bf12",47756:"8363baa0",47953:"28deffdb",48354:"21eeeee3",48429:"76218420",48610:"6875c492",48647:"15bc9537",48700:"db0b0b1a",48882:"ca19bb68",48921:"931eabd9",49030:"00d1ff15",49038:"6a408c5d",49152:"f627fb49",49292:"11086fcd",49437:"47c7ed99",49468:"7a6fc91d",49498:"de073077",49525:"a093bc53",49786:"3e86e93e",49813:"cc2f0d6d",49862:"d1cfc991",50134:"69230ca8",50278:"c292771c",50286:"b05a33c1",50496:"423c478b",50509:"364dd23f",50601:"1e4d9f52",51070:"19aaac20",51139:"8f756a99",51153:"5a75deb7",51246:"7dd48c44",51297:"15abf55c",51563:"e9e7a7fb",51609:"54f2bbcb",51665:"2f3a8764",51725:"585adcae",51815:"1d38dda1",51823:"1a1701af",52016:"5f734fc1",52179:"fec6cfed",52206:"bc07d076",52237:"8ea06fba",52246:"1ec1185b",52351:"0162e4da",52466:"ddc2f4c9",52535:"814f3328",52830:"46e20526",52979:"23567c65",53046:"b10962eb",53047:"49c79f05",53105:"1145e4f0",53204:"a73568da",53506:"8eab39fc",53608:"9e4087bc",53696:"bd432d5c",53722:"0da2a44b",53803:"e1582300",53838:"dd5b994c",53918:"1e03b626",53954:"6e850a7c",54052:"dbca731e",54062:"13eaac75",54258:"8eb1973d",54336:"492ec0bb",54410:"ae48dd95",54438:"945bfa8e",54608:"be64f9ac",54619:"9b35e778",54653:"a9df174c",54655:"e3a29cd8",54776:"6c2c07fe",54793:"2cb54609",54923:"424cf570",55022:"4c0f683b",55037:"08c33249",55162:"f2373e87",55221:"703ac657",55573:"d6cb3553",55632:"78741edc",55755:"9284b101",55886:"7814f0dd",55956:"34ba9ce3",56033:"11fed186",56201:"397f4d9f",56327:"73bdcda8",56446:"048def50",56590:"b5f41b49",56663:"730c5bdc",56752:"c983d4c5",56846:"688b5046",56943:"4668fbc0",57009:"cde7713e",57089:"3b135a5b",57097:"f580bb09",57119:"3cf6e84c",57132:"5f415b73",57144:"df0c10c5",57234:"7e6638f3",57420:"63252ce3",57424:"b9bd11d0",57768:"59aadd5d",57819:"b8675e15",57874:"ceab8ebe",57891:"a4188783",57993:"78034abc",58193:"3b7bfe10",58261:"c9d22c22",58388:"8ed84b56",58416:"df79deea",58536:"5448c11f",58556:"b4882416",58694:"b9cff843",58751:"0920d624",59164:"f17d57ad",59243:"03bf85c5",59258:"c1a663eb",59433:"121001c3",59461:"a58da96b",59617:"e0198fbd",59619:"c0479ea5",59632:"7eee089a",59681:"8e6bd4cf",59703:"309b5dd8",59753:"ea91d5de",59776:"764ec849",59801:"a876c6eb",59935:"b1d98cc5",59957:"08970ca3",59982:"82e544f6",60231:"66745971",60297:"a68c282f",60305:"28742e33",60321:"c503b8d4",60331:"0048074e",60344:"6e0e5835",60384:"f76339d3",60523:"189163f2",60625:"198439c7",61038:"b5a748e5",61189:"de10cfa5",61365:"7feff5a7",61385:"015395c7",61523:"cccaaeb4",61554:"598b665a",62170:"bf7af2df",62505:"5c68c9cb",62725:"afdc79c2",62809:"64784e75",62837:"fa26ab2a",62944:"f3bfcfa1",63016:"1954df72",63100:"6940c6bf",63193:"0de391be",63214:"bf3de6bf",63388:"218908a4",63442:"26774934",63526:"ee4e4c1b",63600:"81b09ebd",63650:"7e4a82be",63676:"0fcfd01a",63686:"ce4e8735",63694:"33352a6c",63891:"40e34aff",64013:"01a85c17",64092:"4a64cd65",64195:"c4f5d8e4",64604:"78cb4a6f",64818:"3562d692",64837:"b3acedeb",64862:"d60e45e7",64867:"970be792",65020:"44947d78",65031:"60f75da7",65098:"ae2ac924",65153:"e696d855",65207:"0d57c9ce",65360:"c1dcfb2c",65376:"d961eb32",65762:"e36f356b",65776:"2b6cddfb",65819:"6123a303",65870:"7f5d4536",65925:"fd678dfe",66067:"47d00ea8",66191:"42a50931",66211:"08aa19df",66250:"cfdd00ee",66409:"aaf8a98b",66647:"6dc88009",66690:"2fae0427",66701:"89306545",66708:"4163f64d",66755:"af8d5674",67066:"90367a0c",67397:"20261b12",67405:"df0f0c82",67417:"abc8672b",67496:"176f50f8",67537:"0531f00a",67669:"1487a05a",67733:"d1c5891f",67770:"5b2ef1ec",67808:"da428f39",68076:"755f5727",68338:"c63a7218",68359:"ffb195dd",68397:"9cee7270",68557:"818fdb6e",68593:"963c5fcf",68957:"3f3e88c2",69104:"b5cf34bf",69689:"535392e8",69723:"4772c639",69772:"2bd1f1d5",69831:"8a6b4ce0",69897:"93d07a7d",69900:"654ea584",69964:"4f6224ab",70068:"176bd847",70078:"b0f0f9ea",70092:"938eb3c6",70221:"31698e81",70240:"10340a96",70270:"b1b6c66e",70322:"34a86810",70382:"49e160a6",70399:"78fb21bf",70466:"032fffd4",70515:"475925f8",70565:"d1970e70",70584:"2cc02388",70629:"99e171da",70652:"b96bd5f6",70656:"1c903048",70935:"61f46007",71041:"bb8fde8f",71162:"e865228c",71163:"2e1c406d",71231:"83742778",71262:"ceea3000",71483:"b02af4c8",71506:"5bd12569",71517:"09adad8b",71548:"f95d5bde",71596:"6fdb1a49",71607:"5bd0d80b",71714:"522dacfe",71814:"475645e4",71941:"d6d41f50",72033:"8da4a059",72156:"a05f09a9",72184:"235df48b",72199:"731875aa",72357:"1f96a859",72454:"5abe1b36",72471:"83ca98b0",72599:"5cd631d0",72764:"6c206af9",72834:"c0bbd0f3",72912:"211ebb99",73101:"21bcd05b",73118:"2ab612bd",73243:"ef7257b6",73288:"5db54a95",73434:"dc581294",73599:"4f04b67c",73652:"ab305317",73748:"62fc691b",73784:"628983af",73974:"58393540",74035:"8bba30fc",74103:"43e5660b",74110:"dd77d920",74208:"2a8278fe",74221:"26343730",74292:"463da95e",74371:"10fdc2f9",74375:"806c76ec",74428:"162d8ecd",74471:"26bbd135",74475:"d0b4cb1e",74517:"dbe6681e",74677:"d5e881dd",74754:"a0426457",74803:"12b8b985",74963:"e5a0cf87",75032:"b5dcc675",75052:"6700f823",75211:"139f368a",75356:"e1ad0931",75395:"95d06a9b",75477:"5e3dccae",75662:"d09e494b",75704:"34400016",75832:"01a9caec",75850:"4c35dc9e",75876:"127e01c6",75901:"8cb14d65",75916:"0b4c2a3d",75919:"6f05ef64",75963:"fa1821d1",75989:"074b8b0e",76207:"07a1d2e3",76498:"d5e5dad6",76514:"d7f3ddf3",76556:"56a68826",76669:"4e27de2d",76710:"3a0edde8",77016:"8001fdfd",77023:"e2fea577",77121:"15e6962c",77124:"dd2c1da5",77275:"c03c0f30",77353:"ebb9a700",77399:"a3563d94",77518:"2a39cc94",77537:"da0c1bd2",77610:"7e1f6989",77646:"5eb4dd36",77687:"34f95092",77823:"f08decd8",77864:"e905c64d",78198:"348ded7e",78286:"0c54e96d",78363:"4e038d8f",78375:"bfe7c903",78411:"2bd5b017",78562:"fe86874a",78614:"333c39f9",78683:"ec7f210a",78741:"fea6709f",78752:"34691405",78960:"f5e2dcd8",79200:"b083706f",79218:"ba50eb08",79282:"1b772fee",79304:"27373d57",79334:"d8554be0",79361:"be569c1a",79449:"14699dc2",79532:"e742a412",79540:"92d53f96",79625:"03c703dc",79782:"e43161e1",79791:"94135bc2",79933:"db269785",80053:"935f2afb",80172:"4ca247e6",80248:"cddb17bc",80317:"209924ca",80365:"c5aef96c",80436:"094b740a",80707:"b53f8486",80849:"12cc19cd",80887:"c35401ff",80942:"8279fca9",81080:"666a30a7",81285:"f34633ac",81298:"aa989111",81311:"bdf60ba9",81381:"80ea1cbc",81396:"1f431ca4",81437:"db0d3a29",81488:"f4c8b930",81501:"0e939daa",81523:"45d4ac63",81622:"beebc224",81707:"b34d016c",81751:"26715d4b",81802:"d8cd04d5",81886:"f942256b",82e3:"4fc3fce9",82003:"69a4838e",82034:"66256a02",82099:"fa53b2d2",82193:"28c1dcfd",82202:"1f591373",82227:"4f17a092",82326:"566c074c",82334:"1b6b2998",82366:"13b17f0f",82585:"e07be7a4",82604:"82d2094f",82633:"14d680d7",82709:"7cbafffe",82719:"522a8ef5",82897:"bd0616a1",83143:"d33a7fad",83161:"63ce3fd8",83196:"f886b690",83237:"fa11df80",83339:"b6754ca6",83570:"fa88d0b5",83696:"8295bdc8",84572:"ad5d5e29",84606:"414fbbed",84624:"42360cb6",84645:"813ecff9",84747:"0c90eee7",84790:"39196521",84792:"37d7ddc4",84949:"3c28b082",85011:"28732498",85102:"ab3f1a59",85391:"f6987bec",85473:"562ab9d8",85520:"62189c81",85691:"7f0cec17",85730:"d92f7595",85855:"4271cf9d",85869:"e6d1c85e",85890:"85d18f05",85966:"5b807afa",85986:"2debe240",86166:"e6c3444c",86181:"b7bd095a",86205:"7191627f",86219:"379f680a",86372:"6779d527",86720:"49427799",86745:"a956189c",86900:"dbd2f45f",86902:"ba4d23df",86925:"272bf7e1",86974:"40f67231",86985:"9de6c7ef",86997:"1cef52b7",87025:"9c165e1c",87272:"6dea9a1f",87288:"c3a20b5a",87420:"27490d87",87455:"e6efe6e5",87530:"645345c3",87550:"a8d8c1a6",87715:"35ed18d0",87761:"da1b6a63",87929:"af7c3599",88032:"221b8e6c",88054:"5c8ded2f",88107:"3232de46",88133:"820ba869",88201:"9fae688c",88306:"d3e71041",88601:"5db0fd99",88607:"dbdee242",88780:"2ff8124e",88814:"581892d0",88862:"2f318257",88903:"19ccee6b",88965:"f3a3bd10",89042:"229e8a6e",89147:"43fce030",89169:"b939b657",89254:"87f5d21a",89256:"f938c89f",89402:"2734a4e0",89588:"18c44d39",89602:"39dc6d1a",89721:"8ce6e6cd",89800:"aa0e0aae",89814:"676097be",89868:"fecbd6ba",89914:"e258573b",90186:"5d691fd7",90338:"7a51b8fb",90486:"d8d16c0d",90505:"37bf5da1",90545:"ce1357bd",90620:"990edd72",90627:"8ffdb1e5",90659:"8bf4c1f7",90801:"3e5bddb1",90901:"cff47a33",91e3:"b87b9466",91096:"66728c19",91101:"a07880c5",91342:"36bb77cc",91456:"05749ca5",91495:"553308b3",91569:"6da3178c",91636:"99bb8163",91733:"49d4e942",91735:"e915e8da",91776:"543b3fa4",91884:"7075d21a",91895:"01227159",91925:"0ddc651b",92014:"f3cd6f51",92240:"fe34a19d",92279:"6d35ea4e",92282:"440dde57",92395:"fc478f65",92609:"282dba02",92621:"ff91dad4",92646:"d663c1f9",92711:"ea9b195f",92857:"5c45b561",93089:"4b80bdac",93208:"886e6dbc",93297:"738641d7",93322:"525fb3e3",93405:"f3d5df32",93530:"81c35fd5",93626:"9664cf5c",93704:"e8cbe84c",93746:"35ddadc8",93824:"fb92caa1",93911:"f1e3cbd1",93990:"8e36650c",94077:"6c66ac4e",94098:"e3117358",94311:"c8c91710",94400:"90b9c8cf",94464:"b278ebdd",94467:"7f55e260",94513:"8dc7efcf",94813:"89636eb2",94830:"ed270ff2",94893:"936f0bab",94939:"d2a8f56d",95026:"25eaf694",95208:"edfa7f68",95403:"58daa6e0",95418:"2cf7b784",95434:"46777dfd",95463:"a55e208b",95670:"e8bf9c2e",95680:"116b6263",95829:"48106cfb",96042:"33a02dc5",96053:"5b85d5ef",96206:"74e84e95",96266:"6bd0373a",96332:"661d3779",96401:"2d730d1b",96523:"8c91223b",96529:"dac05b1b",96542:"15b73062",96545:"3ae1a1e9",96750:"b69071b2",96765:"221feab1",96794:"02076714",96969:"ed67b2f4",97059:"226c5800",97073:"58e68a6e",97239:"c4c94879",97252:"b674b8f7",97278:"195336ce",97303:"bd523454",97463:"3b068242",97605:"f6f6ae32",97635:"93dc7020",97839:"0e7e5a98",97920:"1a4e3797",97933:"7f53b192",98192:"01d1e1e0",98318:"4b49e2b7",98389:"1ed366b4",98436:"73e805ec",98466:"c9fa40a3",98477:"32312966",98515:"c74cff3e",98645:"183d564a",98696:"d3737fce",98874:"53b60fdb",98991:"4efdb10a",99060:"c070cc9a",99097:"af13a07f",99281:"6ab80c20",99298:"7310399f",99331:"014960ae",99511:"6d34fbb5",99515:"3fa13ed7",99633:"3bed2d65",99695:"5059c1c3",99789:"a7b969c5",99802:"073a06f9",99913:"c2df71fd",99922:"825b40fd"}[e]||e)+"."+{162:"f19c9dd7",195:"264b33ac",440:"1aeedbd8",632:"41da1f7e",808:"9910c205",820:"30f66942",840:"cc7be4aa",983:"1ebb250e",995:"ce7a1dd5",1057:"eaa2a205",1181:"7d7e12f0",1522:"eb6d4da7",1545:"af4c36c0",1557:"ca508c34",1642:"56d64e0c",1679:"f0c85fc4",1869:"65bac75d",1890:"184aa732",2039:"1e6d6f83",2044:"7a577eca",2082:"66a1856a",2085:"dfdc45f5",2246:"853a7f25",2309:"1ee128f1",2447:"8e7feb87",2492:"6d404e77",2514:"798e1bdd",2657:"c061471e",2951:"aac25b72",3082:"64090626",3084:"89051a76",3122:"7407647b",3174:"18d0edba",3421:"988d1790",3433:"ab005c35",3523:"f432400f",3640:"ac5d828d",3814:"737d0238",3837:"ade8aea5",3925:"dac9a081",4018:"162fb094",4027:"307f4f2f",4030:"fe21dfa5",4309:"378b13f0",4319:"15d2d0d7",4391:"83e667ff",4483:"de45a183",4676:"e00b7156",4734:"8296a92c",4845:"759111c5",4893:"9c3910f8",4972:"94ed9b16",5020:"51bc2414",5104:"14e957e9",5218:"b54b8083",5256:"fa538316",5276:"bfb261d3",5326:"4a706aa9",5347:"00961541",5548:"8afbdc27",5701:"5571b30d",5723:"7eb1473f",5844:"f473d0ba",5877:"f509bf43",5912:"3b1fe37a",6008:"f3385d26",6133:"06374b71",6302:"6c53917a",6337:"f76aeade",6358:"99d89a92",6645:"bff55c49",6657:"7647cda2",6729:"70cfc394",6886:"769c8f33",6981:"d9c835fb",7216:"eb0ed6c4",7544:"63cdbbd9",7732:"d3003033",7752:"005f6d63",7860:"e62f74e9",8081:"bd29efc5",8155:"076a3c1c",8346:"e7851ecf",8393:"06350c07",8420:"ce3ef3ef",8652:"26f3dfd2",8697:"0300389d",8699:"61e969b8",8862:"5fe508ea",9139:"7be5b963",9192:"f249beb2",9246:"ad440027",9251:"edd0c08c",9253:"714ff862",9564:"859dddc7",9569:"9e7dc961",9636:"0e97dd37",9711:"d069fb83",9943:"bff8dee4",10061:"7fc948b6",10077:"eadff08f",10194:"924e144b",10199:"1f78ce47",10212:"09d8aaed",10288:"d910d88b",10377:"b10e78ce",10480:"ad9549d1",10488:"6198f624",10735:"db8eaa80",10741:"cd96ac3e",10773:"280d0aa8",10777:"3111efbf",10827:"c155af87",10960:"72b5d842",11041:"c598aa5e",11107:"3a01c2a6",11110:"77ed64c2",11152:"1c2db289",11220:"2bc0dc19",11249:"01decae4",11367:"bd355b7c",11505:"7f20a0ba",11519:"e2a7a33e",11634:"f9c8d070",11650:"d21d9ff7",11695:"bf4c3949",11696:"ac7ea067",11833:"2653e770",11858:"fd1c0acb",11988:"f1ad0345",12471:"0fe6d072",12493:"e491aa28",12537:"b3de8fc0",12539:"67f784bd",12615:"c71aa6c9",12691:"8952b465",13178:"c63b1962",13195:"c5affa01",13211:"d7994645",13267:"3940dc27",13334:"15681ef2",13358:"28180c86",13399:"e63b3566",13430:"f7f9c660",13548:"8731749d",13571:"c5a98cbf",13703:"b097dea9",13854:"361520fe",13924:"46482de1",14016:"e2aab49a",14080:"be4de34b",14089:"1473e5f3",14133:"75b44a4b",14489:"6b8d94c7",14493:"d4129bf7",14518:"b76aa1b6",14582:"10de9281",14642:"a8447a05",14645:"7eacb4a6",14678:"449b9fd4",14730:"2a984e8b",14917:"400fe1ef",14945:"7c20851f",14966:"dabc3cbc",15002:"ab8c313e",15095:"4e3cc9fc",15118:"037ef89a",15140:"30ffa213",15289:"da956039",15364:"78e76106",15542:"7097a10e",15595:"ffd4fc4d",15615:"d1ee3203",15659:"dcad8575",15674:"44732021",15729:"e867aa51",15736:"f43081e5",15899:"4bd2b47f",15999:"7c4d2d57",16080:"6709c0dc",16322:"23f13ccc",16378:"b570f7ec",16486:"56533730",16613:"d9bd468e",16634:"08700a44",16754:"a7afb422",16756:"148f817e",16799:"9abc6b69",16818:"f1a82d5e",17036:"2e6b10fb",17135:"fd98f40a",17190:"a4b7356c",17295:"f9549530",17533:"a892528b",17545:"36b4d373",17642:"ae553c35",17694:"de913d2b",17738:"54ce774c",17867:"134f8e71",18166:"f4274c93",18291:"b4402c13",18582:"ee631c0d",18591:"2d79f471",18750:"8ab76738",18859:"0d0a6f27",18894:"720fe000",19048:"35ad9bd3",19067:"c170428c",19116:"cafd3b34",19117:"5a97d681",19308:"987de577",19374:"0f656105",19380:"4122aea1",19626:"edbb8c15",19679:"c955eb4d",19704:"a29a6a7d",19731:"fdb50dd4",19801:"97b87886",19879:"d9f63909",20044:"67528b24",20062:"ea2b5439",20228:"93f19136",20260:"6f3a6724",20305:"0ea27c23",20562:"861e5c07",20611:"5d6aa368",20630:"94f307cf",20683:"79a9a66d",20701:"f57d0b80",20751:"2f069671",20827:"ae0e1189",20977:"36dd15db",20999:"19baf6e2",21143:"6bb55ecb",21155:"1efce90e",21182:"1b2d698a",21199:"07252061",21636:"72523d6e",21691:"139c4623",21725:"14086c9b",21763:"32b6bce7",21776:"2d2901a7",21962:"5d6b5f81",22070:"ace22bec",22083:"dce94d26",22255:"3ed8d493",22350:"d478ef01",22529:"3c6f7f3c",22554:"56645e89",22673:"1111b369",22771:"d7e8a502",22800:"192b2608",22835:"9a851f43",23097:"193ab891",23120:"469d630c",23121:"f6908900",23122:"d85e5759",23221:"867595eb",23275:"a65735c2",23332:"ae6f1e65",23372:"5876b0df",23422:"25f06fe4",23486:"ed66310c",23522:"0439ba51",23650:"2f569f41",23685:"e811ef91",23719:"662f711c",23770:"f583467b",23982:"58204e19",24155:"353600f9",24428:"1c4b578c",24538:"24a9c49a",24595:"79fedf55",24637:"2b4e0d2d",24782:"d126882e",24813:"6d392eca",24850:"694ff0dc",24877:"1c706ddb",24886:"8ae79a34",24949:"7f3f96cf",25444:"9d1dcad4",25572:"de9d09c5",25586:"7bc386ef",25613:"f11a793e",26050:"9d0957ae",26108:"940b6889",26168:"5ad90ea7",26214:"2b4005e5",26241:"732c1738",26258:"a624105f",26302:"71a40812",26328:"fb4edb7e",26351:"cd9c3321",26397:"2cb00f39",26407:"e0d7ec73",26457:"ac2fe568",26647:"df3b9026",26651:"06c72e0d",26958:"51ca300c",27015:"f111e688",27168:"1a40c740",27272:"153c9a16",27284:"1a5b3a0a",27329:"99f5ca06",27378:"a0e82cb0",27628:"825e06e3",27703:"091588c4",27723:"e57dc3da",27745:"d76b9627",27787:"da367911",27802:"6155b1c7",27864:"ffaf5024",27878:"a07421b8",27918:"2e8b459f",27939:"7a303999",28085:"d7326d0b",28103:"252208f4",28171:"1db744c7",28261:"f7d5e510",28323:"0f683be5",28336:"5d28cb64",28370:"2a212b26",28414:"159d03e1",28527:"df95bfd8",28681:"3528e102",28793:"cb0f5ec6",28837:"1b82fdf8",28993:"4edc14ac",29092:"f5fa07e5",29285:"608e8959",29506:"03661d2c",29514:"dd0434ed",29555:"0e536735",29583:"23d2890b",29630:"876dacfe",29657:"b19798fc",29723:"bcab7941",29757:"840e9960",29796:"f23e8986",29820:"d15fb394",30280:"7bcd8c18",30325:"b73cc895",30340:"4e0cc3e1",30368:"ba381844",30495:"4950757d",30555:"b3be1371",30572:"163b4c31",30578:"7499e69e",30672:"8dc10e33",30738:"dfcbb355",30743:"b4b7245b",30747:"aaea598b",30782:"ed951bf4",30954:"8e489f6e",31002:"ea32e307",31036:"02cbdd68",31091:"117e15d5",31110:"ddc92820",31213:"c91c21a4",31330:"1dcc5d07",31574:"5325ba5d",31595:"1ada05b1",31604:"bbcb6fee",31642:"8ba69c0a",31952:"e2082121",31968:"52910b3c",32035:"2f015ba7",32351:"2670866c",32361:"5828da9c",32562:"de078b67",32620:"4c5f4344",32646:"93e07a49",32718:"80025ce8",32734:"40f2ce5f",32771:"08f35c08",32829:"97f9ac68",32856:"9c2c2358",32894:"31c8528e",32928:"b1bc1522",32952:"bd6958d9",33548:"9791e9bf",33567:"7c0a7899",33609:"1cc336b3",33620:"d81950bb",33789:"9211da95",33881:"7b5ac3e7",33922:"54edfc7b",33950:"106ecbdd",34151:"bdbefac9",34173:"f41ecb75",34203:"a9ca823e",34238:"28be8d78",34249:"8008690e",34274:"ade64241",34287:"700a47df",34465:"c041ed50",34523:"a783a0f5",34842:"d25462b4",34929:"ab75feac",34952:"15c8aab9",35120:"c667d89c",35211:"8d50a113",35298:"8b7aa6e4",35565:"ecf5646a",35616:"926f96d6",35647:"74c783e6",35886:"74b37ff0",35936:"6c52b225",35973:"b35e1b6a",36021:"7f737534",36077:"798a69ca",36099:"236a080c",36180:"db06450a",36186:"a14ae5ba",36377:"8caa9c1b",36529:"16233633",36569:"5ee5e069",36757:"5c39eba4",36779:"8f8b0de0",36836:"4cd801b6",36861:"311981a7",36975:"4079e582",36996:"edd1aecb",37104:"d8b01467",37163:"b250c687",37255:"cf32676f",37338:"04ea6019",37631:"63aa697a",37883:"66192b05",37952:"579a277a",38181:"1a90259d",38189:"54875155",38371:"f7a8bc33",38788:"9b14d356",38811:"831cf10a",38891:"71dcf907",38993:"8735fa46",39093:"5aa16908",39190:"8bb536b3",39212:"55baa0d1",39300:"b9b6d1a0",39343:"f871156a",39399:"564b82a1",39468:"93511063",39553:"a9c9f811",39773:"3d4968e6",39977:"63bf0f9e",40003:"db4b6c63",40028:"d2f2be02",40116:"e04a8cac",40193:"5fd8aa32",40265:"7828b026",40504:"2980c50d",40601:"dca60534",40659:"5b095ff8",40948:"616207b0",40951:"46cc611e",40967:"91f3d8ac",40993:"fc4a9969",41331:"fbc4f97a",41344:"bccdea11",41403:"ecd6b879",41750:"4eaae860",41771:"d12639e8",41784:"d6fbd1db",41933:"a9b03064",42013:"45867001",42115:"be5c41eb",42134:"80c00187",42203:"ac8d673e",42214:"76d30402",42314:"61e4fe67",42495:"c9b79ad5",42506:"cf75e2ff",42553:"867ac4a9",42609:"752c1848",42677:"473c42a6",42791:"6a6a3671",42815:"ad8d2ff6",42919:"624e5fe3",42960:"72e9fa23",42978:"6e301124",43055:"5c1838ec",43085:"6103307d",43267:"38c31208",43361:"8716d463",43763:"fb0a166e",43837:"22b7cbad",43930:"51e2c64f",44032:"6097f065",44049:"3caa29b8",44235:"5e9dc497",44247:"cdc74ca5",44258:"f1ca2e0c",44308:"2377a57a",44401:"88225e94",44426:"53e7433a",44509:"b58c8d76",44561:"388e60b8",44973:"ec6d2c37",44984:"b582b306",45020:"18bf88b4",45049:"f3beac4c",45314:"92705574",45443:"b5456089",45709:"dd24bf4b",45728:"c8160e1f",45906:"b34e2b81",45992:"deaf1d11",46048:"81079b48",46076:"4c78fe8b",46103:"f5b60dac",46200:"cbdafad1",46360:"bbfd9091",46408:"1a7efa9a",46609:"fb323bc9",46628:"b47c466e",46687:"5b4d170e",46708:"1fb4d78c",46744:"9b0c65a8",46797:"ae2ee5ff",46852:"2559f0d3",46869:"1de3e423",46945:"70ad4e4d",47049:"67364de8",47133:"96c06608",47324:"3c907066",47404:"05baf8ad",47487:"7b351da1",47567:"9828a0d1",47658:"e7aa0954",47713:"869ba4ea",47734:"a05252e1",47740:"bc6cf802",47756:"3be0bd8b",47953:"20141070",48354:"466d19e2",48429:"f2170e10",48610:"cdcf9bd8",48647:"2822b3b5",48700:"e2b6bbe3",48882:"8db7fc36",48921:"a917eac1",49030:"c850cc6a",49038:"750650ef",49152:"9890e3f9",49292:"e5a80513",49437:"bc0fbfcb",49468:"2ead9785",49498:"f56960ce",49525:"79ff1717",49786:"0d253a19",49813:"2bbc85ac",49862:"41099c3c",50134:"d9102772",50278:"58fb96c6",50286:"76c8d6fa",50496:"ac63fb88",50509:"6cfa2310",50601:"13974574",51070:"20e9d786",51139:"b06199d1",51153:"4ef282ad",51246:"9bb28164",51297:"3f8c3441",51563:"cdd03259",51609:"74499353",51665:"7a8a8c33",51725:"2df087be",51815:"fe20f492",51823:"2b369e75",52016:"cbc6efb9",52179:"406d75c4",52206:"816da6c5",52237:"44bba918",52246:"15c07dd2",52351:"ac32a61d",52466:"87237cfe",52535:"072d69aa",52830:"ae61d8f8",52979:"76b2e727",53046:"bb05dd95",53047:"8a6cf1a7",53105:"863e05ac",53204:"ab6731da",53506:"c0f209f5",53608:"ed64357a",53696:"79a01761",53722:"646fbf8a",53803:"9a275c06",53838:"9f8923cc",53918:"4eb61f3b",53954:"5a9e27c0",54052:"cfab1023",54062:"8192abff",54258:"73527f0b",54336:"25930eb9",54410:"e8bf0afa",54438:"4bc0b921",54608:"19d53eec",54619:"dd650c31",54653:"fb74baa2",54655:"c1e1f348",54776:"205ea854",54793:"41fb43d1",54923:"0552654d",55022:"6085e8d9",55037:"62b5bd29",55162:"1a42adca",55221:"352b0062",55573:"fb32649d",55632:"e8169c2a",55755:"2b379720",55886:"4b6babd6",55956:"2ccff26d",56033:"cb31da25",56201:"91ae2d25",56327:"9178acb8",56446:"fa5017da",56590:"6d64bc22",56663:"35f825c0",56752:"3ef2045d",56846:"3cee2715",56943:"4a010041",57009:"e2f5e48a",57089:"82035c43",57097:"dd6f10aa",57119:"d6d55018",57132:"f873d4c4",57144:"24ce2d9b",57234:"f3f380b7",57420:"6bc4e7af",57424:"64f36937",57768:"3b0cbd3f",57819:"b98dd03b",57874:"fe93cb7d",57891:"b51a95a0",57993:"9a856d4f",58193:"3718d94a",58261:"919d4803",58388:"919c0ad6",58416:"85e9bae4",58536:"4e4ffd09",58556:"d92e82e0",58694:"c374d774",58751:"7ef1370c",59164:"69fa01e6",59243:"e9eb4396",59258:"f3750ba9",59433:"8d926128",59461:"d6225260",59617:"3f1b7063",59619:"42c899d4",59632:"dcbd218d",59681:"bfa0764e",59703:"3086dbb9",59753:"b558d2c1",59776:"f68bc966",59801:"588eea01",59935:"6c6e7f71",59957:"d22dab3b",59982:"1211f851",60231:"32e533aa",60297:"e02eac1c",60305:"93e65a98",60321:"fd401dff",60331:"f66ad8e4",60344:"bca7f1f8",60384:"7c1f5f3a",60523:"d292ae18",60625:"271aaaf2",61038:"213571c0",61189:"ca3affdf",61365:"b4c52c42",61385:"9cb26ebc",61523:"bb7ede40",61554:"7891f7ea",62170:"c99e0a68",62505:"14d83885",62725:"02acf96b",62809:"e3aa878d",62837:"c1d4abc5",62944:"efb772f1",63016:"2f4a6fd3",63100:"8cf7989f",63193:"fea39589",63214:"390a0935",63388:"2f0f6123",63442:"f11cf20e",63526:"ba6a2db0",63600:"4c0241f7",63650:"cb485153",63676:"85e9b86c",63686:"b5989604",63694:"f9da93c0",63891:"9ab5eaf4",64013:"c72a1fdd",64092:"59853f27",64195:"73a1e872",64604:"010a274c",64818:"69cb7052",64837:"e823cb3b",64862:"951c8cf6",64867:"05a9e0cf",65020:"f72d935e",65031:"7d6c5e73",65098:"b80437c0",65153:"d3e4fb7b",65207:"ea9544e9",65360:"1d4c94d5",65376:"c41c486d",65762:"5e5a04e5",65776:"45910a21",65819:"b638008a",65870:"c662f287",65925:"8c50f06e",66067:"a6693dc1",66191:"9dc80463",66211:"fc858866",66250:"8a0c72a1",66409:"4721094b",66647:"c922d5ff",66690:"f2348832",66701:"0787318c",66708:"96b99f49",66755:"e012687d",67066:"c599fc47",67397:"f46d222e",67405:"373e96a6",67417:"e78db44e",67496:"f9cf67b5",67537:"ec2382ef",67669:"99a28219",67733:"f32bd6fa",67770:"35d7d5f3",67808:"7af430e0",68076:"053db970",68338:"eb261de6",68359:"3b379e60",68397:"19a59a88",68557:"62ab26f4",68593:"d5517f28",68957:"8377f69b",69104:"05d7b998",69689:"c7a0a5bc",69723:"728bf9e4",69772:"d30f5c4c",69831:"1a1e66d0",69897:"b4825953",69900:"1b9e227c",69964:"046a34f8",70068:"1d1bea04",70078:"583546a0",70092:"a78a5d75",70221:"083dac6b",70240:"cc4be49d",70270:"c3ed7aaf",70322:"23e6c0de",70382:"16535e30",70399:"ae3d3dc2",70466:"1abe2872",70515:"db6ec03a",70565:"aed1bdd8",70584:"09d5b912",70629:"870735a5",70652:"4c23d4d3",70656:"0f002979",70935:"5832e917",71041:"e4a3c236",71162:"caa7aae2",71163:"e5236bec",71231:"a11ef9de",71262:"21c8ad9d",71483:"f5df5ddd",71506:"5b9a7385",71517:"e3c5691e",71548:"afd05b82",71596:"1ee609db",71607:"c1607640",71714:"c1396844",71814:"7d5ba3b5",71941:"5fe091f1",72033:"a77474a5",72156:"f6777991",72184:"4b71fee2",72199:"f18694c8",72357:"494fa0dc",72454:"883c42e1",72471:"1f442c2d",72599:"5a559f6e",72764:"79d4cbf3",72834:"1eb113e2",72912:"034e3896",73101:"641e3e32",73118:"8b8c6884",73243:"a58b53de",73288:"da180c69",73434:"9bb33b4d",73599:"29e04e25",73652:"ccafaae3",73748:"c9684cb1",73784:"fee9e459",73974:"b93fc295",74035:"7d696710",74103:"ea3ec24e",74110:"a0c94efd",74208:"df7c1e8f",74221:"045ce587",74292:"91af8320",74371:"e6be8dff",74375:"1b765f73",74428:"9c3a20e2",74471:"5e855cf3",74475:"7e98a9e0",74517:"1be35da6",74677:"673b546f",74754:"f0d2fc8c",74803:"d0cf7ffc",74963:"274164b0",75032:"33eb3d16",75052:"e46411a7",75211:"67d49e22",75356:"7e02e9ec",75395:"566415f6",75477:"b97523ec",75662:"5f413c1b",75704:"ccc91543",75832:"d0261263",75850:"48bfc804",75876:"50bd5965",75901:"4e2f0720",75916:"eba70766",75919:"fda810e7",75963:"ddbdfe6a",75989:"c65b2026",76207:"5a4c0441",76498:"c80254a0",76514:"f4d96396",76556:"70dcf01d",76669:"5bbddee0",76710:"0e2159a1",77016:"cb89d3e0",77023:"31a1d9e0",77121:"6c3f1686",77124:"7e828bde",77275:"1981223a",77353:"9fa5ae82",77399:"f1aa9e09",77518:"edf4268d",77537:"74869200",77610:"1f49f488",77646:"810a55fd",77687:"c8a883d8",77823:"32bdb30c",77864:"195a8112",78198:"aa768773",78286:"6f07e364",78363:"099d048f",78375:"b276118c",78411:"268cb097",78562:"1f937441",78614:"4a53634e",78683:"38af36a2",78741:"6c304afe",78752:"7a6900b8",78960:"c6ae250f",79200:"6fe66561",79218:"7492323d",79282:"721b8af7",79304:"0565ad04",79334:"88c23a98",79361:"3b614906",79449:"67043f81",79532:"4582db91",79540:"46203971",79625:"8efd22ba",79782:"d109cf55",79791:"7ff1a7ef",79933:"b6dd4a44",80053:"fa576174",80172:"d67a3f86",80248:"fb4b5abc",80317:"bc5a9480",80365:"4e7798ba",80436:"d443d23d",80707:"e9166ca0",80849:"465ff347",80887:"344f3dd2",80942:"a7fd4b4e",81080:"6053b89a",81285:"02ba1e0b",81298:"4357fd9a",81311:"9aa199b9",81381:"d7adf0ae",81396:"485cbba3",81437:"08fa5c19",81488:"19989853",81501:"8100a457",81523:"928030ab",81622:"072b8511",81707:"ff49f4f3",81751:"d2f7bd04",81802:"7266371d",81886:"40d46503",82e3:"c36f2bf7",82003:"5d9843af",82034:"f23d6a1d",82099:"8a2824cb",82193:"0e18a12b",82202:"3c0b8957",82227:"a200ce4d",82326:"0c4658ed",82334:"f6fe4b01",82366:"22ccf47a",82585:"c568edeb",82604:"d469bd8b",82633:"c6477015",82709:"0a0d5f30",82719:"e8746d8b",82897:"64a1db0c",83143:"3a39f029",83161:"02635b22",83196:"0b737d08",83237:"913c6c55",83339:"8c20d9a6",83570:"5e9d83e4",83696:"ca59e747",84572:"170524c2",84606:"dff9fd8a",84624:"1993b218",84645:"28d17a30",84747:"9a91d412",84790:"8a132ce6",84792:"106a2467",84949:"b88c6944",85011:"cd647c34",85102:"5e4ebfa2",85391:"86edb779",85473:"de39892e",85520:"b93d75fe",85691:"9d9b7599",85730:"a48558fe",85855:"a89df95c",85869:"6ae63b22",85890:"5a69e5b2",85966:"64dda0ee",85986:"2890cafb",86166:"184dd6a4",86181:"33e58e25",86205:"094c56f1",86219:"22250e0f",86372:"dc46993a",86720:"41862e9e",86745:"1a5eafe5",86900:"a4b548ea",86902:"999e3db3",86925:"aec517b4",86974:"acdf6505",86985:"1263b029",86997:"c0dd6c21",87025:"3389a2cb",87272:"5bd69767",87288:"89cc97b2",87420:"42496ee4",87455:"0aa15019",87530:"65e325ae",87550:"0c0badd8",87715:"5aa20c19",87761:"2141129a",87929:"cdaf9fb9",88032:"76aee412",88054:"1eba9309",88107:"589896a7",88133:"36c2bf22",88201:"de08ac94",88306:"c2afe687",88601:"29e3986c",88607:"23c4b474",88780:"d6128200",88814:"d98137d3",88862:"85b02bbe",88903:"4d782f43",88965:"e485e92f",89042:"4e6ca00d",89147:"9289166a",89169:"d917799e",89254:"7f88cc94",89256:"e007806d",89402:"05b42e23",89588:"032020c1",89602:"491fc269",89721:"87690263",89800:"dc357da3",89814:"8ed7fc26",89868:"186db7ba",89914:"14386b3c",90186:"9e87ecac",90338:"a04cc71d",90486:"6af6f3e4",90505:"8b7a2f2c",90545:"4d9116f4",90620:"0fc95c31",90627:"e92076cb",90659:"4dd06be7",90801:"c8c13e6e",90901:"195b534a",91e3:"558bf5c3",91096:"842c1cbe",91101:"f7d7649b",91342:"6d504d8d",91456:"2fb90812",91495:"31990160",91569:"1d4686e4",91636:"3cf003a4",91733:"09cf16eb",91735:"47d3275a",91776:"358a43cd",91884:"9450a1f1",91895:"18d2959b",91925:"ffd0b711",92014:"45ab6051",92240:"4654f229",92279:"b37988ec",92282:"776a48d1",92395:"1379736d",92609:"34d04396",92621:"be17476b",92646:"f8492b2c",92711:"d6107aa0",92857:"1a84c751",93089:"474c16a9",93208:"d880ff22",93297:"7f815050",93322:"69fa218b",93405:"169a3eda",93530:"75a92296",93626:"2ea31b3f",93704:"16428304",93746:"a84ce850",93824:"5e7418a0",93911:"21e57c84",93990:"55c2784b",94077:"643f58db",94098:"8b15c9e6",94311:"5d2129ef",94400:"96f40d6e",94464:"ecfc8bfd",94467:"ff3917e7",94513:"b7076f53",94813:"9459303b",94830:"13958ceb",94893:"53c97b59",94939:"0f0dcb29",95026:"73daf737",95208:"592b5c84",95403:"7574856f",95418:"d4e2d48e",95434:"2339c637",95463:"4d766ed0",95670:"c16c1ba6",95680:"1a842c57",95829:"05e1d1bf",96042:"0dfdaab6",96053:"3dcaeb8c",96206:"21e8c421",96266:"217afb9c",96332:"71dfdbbf",96401:"9b8ff31d",96523:"20f0de27",96529:"7415fcf9",96542:"a542befc",96545:"330edc89",96750:"ef157ae8",96765:"c023231c",96794:"276c4d75",96969:"d315fd4a",97059:"8196fbdc",97073:"679e998f",97239:"e9b19c99",97252:"fdd60c48",97278:"40106419",97303:"35973930",97463:"bb6ac8de",97605:"ae9ca355",97635:"140b7912",97839:"efcfa8fb",97920:"339c81f3",97933:"9ca7a817",98192:"01f0be10",98318:"ceae3458",98389:"5670d2c0",98436:"16ee8b42",98466:"e42ccdad",98477:"52dc3dcc",98515:"e5e986f7",98645:"037144ce",98696:"e1f95067",98874:"aaf983be",98991:"9c31f420",99060:"6a549612",99097:"57dc0eb7",99281:"2d204353",99298:"1eebf09b",99331:"8840ab8e",99511:"386e7f53",99515:"4764ed1c",99633:"edca8ed6",99695:"340a4e6b",99724:"69865832",99789:"4be7a0d7",99802:"9fca0a7b",99913:"bf9e84ad",99922:"8bbf3a56"}[e]+".js"},n.miniCssF=function(e){},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=function(e,c){return Object.prototype.hasOwnProperty.call(e,c)},f={},b="nativeextensions-documentation:",n.l=function(e,c,d,a){if(f[e])f[e].push(c);else{var t,r;if(void 0!==d)for(var o=document.getElementsByTagName("script"),i=0;i=b)&&Object.keys(n.O).every((function(e){return n.O[e](d[r])}))?d.splice(r--,1):(t=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[d,f,b]},n.n=function(e){var c=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(c,{a:c}),c},d=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},n.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var b=Object.create(null);n.r(b);var a={};c=c||[null,d({}),d([]),d(d)];for(var t=2&f&&e;"object"==typeof t&&!~c.indexOf(t);t=d(t))Object.getOwnPropertyNames(t).forEach((function(c){a[c]=function(){return e[c]}}));return a.default=function(){return e},n.d(b,a),b},n.d=function(e,c){for(var d in c)n.o(c,d)&&!n.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:c[d]})},n.f={},n.e=function(e){return Promise.all(Object.keys(n.f).reduce((function(c,d){return n.f[d](e,c),c}),[]))},n.u=function(e){return"assets/js/"+({162:"13e3485d",195:"cb3277ce",440:"bb778a53",632:"3649c6e5",808:"6f4cc41c",820:"68637bd9",840:"bb7a524b",983:"a1b5ebbc",995:"243e72d0",1057:"ff61ba43",1181:"794bdbe1",1522:"743a4eda",1545:"c5c8c8ef",1557:"ddbbbc81",1642:"76e4ba13",1679:"8f64645b",1869:"a44a17a7",1890:"185176c3",2039:"72e33197",2044:"faa207b7",2082:"3ff77dc6",2085:"56026b06",2246:"7537a64e",2309:"2cc315c3",2447:"e9c16141",2492:"1f309900",2514:"b0386327",2657:"6217abc0",2951:"3524c5f4",3082:"4ab280a7",3084:"7087d0c3",3122:"7c148484",3174:"33b5d490",3421:"922937a2",3433:"5b77a007",3523:"bcd8dacd",3640:"e5ff2770",3814:"0e2a33af",3837:"13e8f167",3925:"44773ce0",4018:"8e160d92",4027:"d84ee27c",4030:"37ddad66",4309:"705de539",4319:"68a83471",4391:"770ebbdf",4483:"bd6c7714",4676:"09693916",4734:"3baded6d",4845:"2762efe5",4893:"7c9af93f",5020:"68c32018",5104:"6f879726",5218:"c453f0e4",5256:"6b356f46",5276:"e8767721",5326:"7b64eba0",5347:"bd01da59",5548:"a69d3c33",5701:"97e02059",5723:"c5f713a3",5844:"0563c9d5",5877:"24a18380",5912:"2f19675a",6008:"f0a6555f",6133:"c0258d9a",6302:"bfe05aa5",6337:"c270329b",6358:"98b86d9d",6645:"ad714920",6657:"a1dfeec9",6729:"d253f400",6886:"14786350",6981:"4161038c",7216:"13476308",7544:"e63cab04",7732:"17c09b7c",7752:"60a734f8",7860:"3aa2f437",8081:"759b040c",8155:"df4148ce",8346:"fc4fbc82",8393:"4e8ceca4",8420:"336e2d10",8652:"ed44cee0",8697:"d28c071c",8699:"988b121f",8862:"bcac2d32",9139:"b5429f5c",9192:"1b47644e",9246:"0b9486e1",9251:"ba71f315",9253:"689bb653",9564:"66f2530f",9569:"ce6c3cc7",9636:"7ff944dd",9711:"d21a5299",9943:"ec1c65d9",10061:"5a2fa176",10077:"ccc9a6ae",10194:"6196e3e3",10199:"b49f544b",10212:"be55fd82",10288:"16e30885",10377:"6508b81f",10480:"aa212d2b",10488:"389c677e",10735:"b0aef227",10741:"a958a1fe",10773:"71adf2b1",10777:"3dbac566",10827:"63c71228",10960:"61a58a31",11041:"ff28909e",11107:"3da7c7af",11110:"6ebc4cba",11152:"9cd6e596",11220:"f0f92231",11249:"891aa492",11367:"58b71341",11505:"311bd2e5",11519:"75afe063",11634:"74a562c5",11650:"7ff9befe",11695:"ef7a268d",11696:"1fe15ca1",11833:"6db7791b",11858:"46e74a12",11988:"f9c59cec",12471:"b05903c6",12493:"93ddc768",12537:"0ed266fd",12539:"d944851e",12615:"0f5e5ca9",12691:"cdc8bb25",13178:"6cd5e3a2",13195:"2da7ffca",13211:"ae13eaec",13267:"c4930dbf",13334:"3ad6345f",13358:"bc92a7eb",13399:"b34a828c",13430:"647b836a",13548:"414dceb8",13571:"9de038fa",13703:"cd8681d0",13854:"30bd281c",13924:"ec58503a",14016:"691b4103",14080:"d554986d",14089:"ee30c4f9",14133:"930794af",14489:"814cc783",14493:"bdeb18d1",14518:"f82bf1a9",14582:"4bd0cf30",14642:"a92f2c1a",14645:"5539d89b",14678:"c0b7d35c",14730:"c5af1cfc",14917:"c352947e",14945:"f0c91146",14966:"113776ae",15002:"b056655e",15095:"53806931",15118:"a9bd30ef",15140:"8feaef3a",15289:"bd986f80",15364:"6b8da0f5",15542:"fa6d02c0",15595:"0b695c4c",15615:"546f9a01",15659:"293f897f",15674:"b1dd4c98",15729:"ef804dd5",15736:"f16842bc",15899:"8dfee272",15999:"bc553fd8",16080:"5e8955e2",16322:"825092a9",16378:"9352df78",16486:"a6282008",16613:"d5f4b9d1",16634:"a844fb09",16754:"4f47e7ff",16756:"c5b16d1f",16799:"46c9c1c9",16818:"aaa05763",17036:"b4cf7eb5",17135:"782a8136",17190:"f71d0279",17295:"60173ad8",17533:"5e051bf3",17545:"700f0253",17642:"59c3e71f",17694:"61db54ba",17738:"bab9f44d",17867:"a45fb5ce",18166:"16d03713",18291:"d4dbcd1c",18582:"78c7ae31",18591:"b5e83296",18750:"9f9d8d40",18859:"a82ee963",19048:"8aae2b08",19067:"fcfe1329",19116:"560c8c12",19117:"0cca7499",19308:"d91d5370",19374:"c5fec417",19380:"50229c5b",19626:"2631fa1d",19679:"f401bfc3",19704:"bcd8f52b",19731:"dd042142",19801:"0ed8251c",19879:"ae36b559",20044:"7a35d080",20062:"e090d8ec",20228:"36e4096d",20260:"33d8e434",20305:"9de99998",20562:"9c0b8d44",20611:"b04e19b4",20630:"698128b2",20683:"d6267b43",20701:"9615a67c",20751:"deaabb1b",20827:"5894833a",20977:"94149987",20999:"41b24fb6",21143:"954f6ca2",21155:"15780a71",21182:"a0a3786c",21199:"223dd6d0",21636:"f8b95006",21691:"7002472e",21725:"aacc87f2",21763:"d5e5f94d",21776:"337d9695",21962:"75bdd353",22070:"24cfd963",22083:"d3c558c0",22255:"d832a8ac",22350:"3da3a6d6",22529:"36daa823",22554:"afdd1fc6",22673:"3387b713",22771:"eb9a84fa",22800:"8e5feab1",22835:"fb671fd4",23097:"1267535a",23120:"be3cd489",23121:"9f8a86a1",23122:"4c7d3a3a",23221:"939a6763",23275:"a5437f03",23332:"334d840b",23372:"32908617",23422:"4f806ca3",23486:"8c541c4b",23522:"81ccd52a",23650:"12780c04",23685:"42cc23aa",23719:"449e4b0b",23770:"004cf658",23982:"369e0402",24155:"bf2bc35c",24428:"90d854df",24538:"022f887e",24595:"03f20467",24637:"955424a3",24782:"6566fc75",24813:"bf7338c5",24850:"cc579207",24877:"44f81e6d",24886:"a6aa9e1f",24949:"17890afa",25444:"89c378d1",25572:"10699eac",25586:"4660316f",25613:"b6d51dc3",26050:"04bfa6bb",26108:"ccfbddc7",26168:"9d36a906",26214:"1ee46a20",26241:"2700ec3c",26258:"0ebe73eb",26302:"4826d74f",26328:"9d2a5046",26351:"a2ed449e",26397:"76d9cc66",26407:"a54a8d17",26457:"076ee303",26647:"7cd5c344",26651:"48bf28e1",26958:"66024f8e",27015:"d317b305",27168:"21cde90b",27272:"c35068d2",27284:"a6b1e8f8",27329:"75d624f4",27378:"4e571b33",27628:"35fa06c0",27703:"68155fb2",27723:"ad2edd7e",27745:"82a67ce7",27787:"8b00c4b0",27802:"29071212",27864:"2f6e266f",27878:"56673e51",27918:"17896441",27939:"f241cd81",28085:"5be4f51b",28103:"0abffcbf",28171:"2f8d21d9",28261:"29aa1ed4",28323:"2f322c00",28336:"9c6fee4d",28370:"246a7b8b",28414:"7d694b3a",28527:"c2fdb40c",28681:"cf76520a",28793:"ef3dde2a",28837:"f4d5a234",28993:"f42bcbd0",29092:"b3eec62e",29285:"05459498",29506:"03677e6b",29514:"1be78505",29555:"9d1c6e84",29583:"d30fc371",29630:"49cc842f",29657:"8d7eb0a9",29723:"290da131",29757:"6eeb9991",29796:"27dfa723",29820:"e072863c",30280:"106c104b",30325:"8caeb3b9",30340:"cdd3f1f6",30368:"2b7573de",30495:"386aa01b",30555:"6aa8e49e",30572:"cd671aaf",30578:"f84a6e3d",30672:"d6b80958",30738:"88d80bd2",30743:"b3f3a0dd",30747:"8b800d35",30782:"e0e5cf54",30954:"34e6a6da",31002:"2999b41c",31091:"134bb968",31110:"e56832f8",31213:"3978a105",31330:"728415ec",31574:"9f024f64",31595:"afa4c90b",31604:"b00c33b0",31642:"75222a8a",31952:"0eb9886d",31968:"eafdc628",32035:"0651460a",32351:"72c63364",32361:"bb2fcf03",32562:"3c24c133",32620:"456e6daf",32646:"e30582b2",32718:"841d3558",32734:"55cf730b",32771:"23808f4f",32829:"8257120c",32856:"11ce2a18",32894:"4b60f83c",32928:"d743a660",32952:"081694b1",33548:"01cb8778",33567:"89e61cb7",33609:"14f03e77",33620:"8fe15bf0",33789:"d4c80b47",33881:"6ba27067",33922:"a90ce6d1",33950:"9694a7fb",34151:"d8d794e7",34173:"4edc808e",34203:"083e9c39",34238:"80551706",34249:"b2125466",34274:"4bbbca70",34287:"706ef0f8",34465:"0a4ab38e",34523:"93217873",34842:"754c8a51",34929:"5baeeec9",34952:"c941472e",35120:"cf17176c",35211:"1f2b5bee",35298:"113e98af",35565:"aa913c04",35616:"3fb6235c",35647:"d72a3e67",35886:"7f320937",35936:"ef8205f2",35973:"3f977937",36021:"038896b4",36077:"ba36f8fe",36099:"ad65305a",36180:"c01205be",36186:"4f8081aa",36377:"710acf16",36529:"290901e5",36569:"99231e2c",36757:"6c1cfff2",36779:"98a54395",36836:"fea1970e",36861:"3a66a8a7",36975:"ce23889d",36996:"2ab3c725",37104:"6b6a2525",37163:"475e419a",37255:"15658e7c",37338:"eb0eeb72",37631:"d1d6cc97",37883:"8fb395ee",37952:"f92a140f",38181:"3b0faa55",38189:"0b90df17",38371:"b8053e79",38788:"b29eae3f",38811:"02e9015f",38891:"185baa7b",38993:"268b4470",39093:"2a00a656",39190:"e99d4187",39212:"727aa2eb",39300:"c4a8d8d0",39343:"424f41d9",39399:"0cd24d44",39468:"047da02a",39553:"a68f12d5",39773:"f9442607",39977:"8537e111",40003:"71753d0f",40028:"e9c01433",40116:"d1e17e98",40193:"12a75feb",40265:"cf2b6063",40504:"d064531f",40601:"bdf736ae",40659:"feb1b108",40948:"e32ba394",40951:"f311171d",40967:"19e5c8a8",40993:"ee505f00",41331:"c2f6c957",41344:"fea316db",41403:"7851fb52",41750:"226f60b4",41771:"9af0ca03",41784:"24584499",41933:"7984f828",42013:"38f15e71",42115:"07102b8e",42134:"f3edbbcb",42203:"d635135b",42214:"a2f86c00",42314:"0d4ee96f",42495:"c7a4a619",42506:"cb838682",42553:"1b71fe77",42609:"b2b7991b",42677:"ec62adee",42791:"126a8b5f",42815:"a70a1ced",42919:"15747b1c",42960:"efb761db",42978:"9f698d42",43055:"ffb17bf3",43085:"9bbe3ea4",43267:"2ce4181b",43361:"7e04375a",43763:"7b531316",43837:"7b239f86",43930:"fe18b0a2",44032:"f2bdb430",44049:"609f11c2",44235:"4bcd5de8",44247:"ae652fc3",44258:"333eac1e",44308:"5a955209",44401:"7352eb09",44426:"a433c715",44509:"394e3983",44561:"3d4c5a33",44973:"4dbe51d0",44984:"84f16505",45020:"95740546",45049:"3ac517d3",45314:"e6dc52c7",45443:"70de807c",45709:"e56ba3b9",45728:"dc04fbfa",45906:"08b05c06",45992:"aa8793a0",46076:"65f8b24f",46103:"ccc49370",46200:"7ef80d56",46360:"f6fa4812",46408:"7a50e73a",46609:"5aa2a2dd",46628:"353ce9a8",46687:"76cf8a26",46708:"1580ff85",46744:"e48737d3",46797:"e7700274",46852:"20e259dc",46869:"78514b8e",47049:"6e0506f8",47133:"f51e1b21",47324:"23886185",47404:"5042ad53",47487:"4d1b1010",47567:"2b29dd21",47658:"5c710130",47713:"34e3dd60",47734:"67bf6aac",47740:"85d5bf12",47756:"8363baa0",47953:"28deffdb",48354:"21eeeee3",48429:"76218420",48610:"6875c492",48647:"15bc9537",48700:"db0b0b1a",48882:"ca19bb68",48921:"931eabd9",49030:"00d1ff15",49038:"6a408c5d",49152:"f627fb49",49292:"11086fcd",49437:"47c7ed99",49468:"7a6fc91d",49498:"de073077",49525:"a093bc53",49786:"3e86e93e",49813:"cc2f0d6d",49862:"d1cfc991",50134:"69230ca8",50278:"c292771c",50286:"b05a33c1",50496:"423c478b",50509:"364dd23f",50601:"1e4d9f52",51070:"19aaac20",51139:"8f756a99",51153:"5a75deb7",51246:"7dd48c44",51297:"15abf55c",51563:"e9e7a7fb",51609:"54f2bbcb",51665:"2f3a8764",51725:"585adcae",51815:"1d38dda1",51823:"1a1701af",52016:"5f734fc1",52179:"fec6cfed",52206:"bc07d076",52237:"8ea06fba",52246:"1ec1185b",52351:"0162e4da",52466:"ddc2f4c9",52535:"814f3328",52830:"46e20526",52979:"23567c65",53046:"b10962eb",53047:"49c79f05",53105:"1145e4f0",53204:"a73568da",53506:"8eab39fc",53608:"9e4087bc",53696:"bd432d5c",53722:"0da2a44b",53803:"e1582300",53838:"dd5b994c",53918:"1e03b626",53954:"6e850a7c",54052:"dbca731e",54062:"13eaac75",54258:"8eb1973d",54336:"492ec0bb",54410:"ae48dd95",54438:"945bfa8e",54608:"be64f9ac",54619:"9b35e778",54653:"a9df174c",54655:"e3a29cd8",54776:"6c2c07fe",54793:"2cb54609",54923:"424cf570",55022:"4c0f683b",55037:"08c33249",55162:"f2373e87",55221:"703ac657",55573:"d6cb3553",55632:"78741edc",55755:"9284b101",55886:"7814f0dd",55956:"34ba9ce3",56033:"11fed186",56201:"397f4d9f",56327:"73bdcda8",56446:"048def50",56590:"b5f41b49",56663:"730c5bdc",56752:"c983d4c5",56846:"688b5046",56943:"4668fbc0",57009:"cde7713e",57089:"3b135a5b",57097:"f580bb09",57119:"3cf6e84c",57132:"5f415b73",57144:"df0c10c5",57234:"7e6638f3",57420:"63252ce3",57424:"b9bd11d0",57768:"59aadd5d",57819:"b8675e15",57874:"ceab8ebe",57891:"a4188783",57993:"78034abc",58193:"3b7bfe10",58261:"c9d22c22",58388:"8ed84b56",58416:"df79deea",58536:"5448c11f",58556:"b4882416",58694:"b9cff843",58751:"0920d624",59164:"f17d57ad",59243:"03bf85c5",59258:"c1a663eb",59433:"121001c3",59461:"a58da96b",59617:"e0198fbd",59619:"c0479ea5",59632:"7eee089a",59681:"8e6bd4cf",59703:"309b5dd8",59753:"ea91d5de",59776:"764ec849",59801:"a876c6eb",59935:"b1d98cc5",59957:"08970ca3",59982:"82e544f6",60231:"66745971",60297:"a68c282f",60305:"28742e33",60321:"c503b8d4",60331:"0048074e",60344:"6e0e5835",60384:"f76339d3",60523:"189163f2",60625:"198439c7",61038:"b5a748e5",61189:"de10cfa5",61365:"7feff5a7",61385:"015395c7",61523:"cccaaeb4",61554:"598b665a",62170:"bf7af2df",62505:"5c68c9cb",62725:"afdc79c2",62809:"64784e75",62837:"fa26ab2a",62944:"f3bfcfa1",63016:"1954df72",63100:"6940c6bf",63193:"0de391be",63214:"bf3de6bf",63388:"218908a4",63442:"26774934",63526:"ee4e4c1b",63600:"81b09ebd",63650:"7e4a82be",63676:"0fcfd01a",63686:"ce4e8735",63694:"33352a6c",63891:"40e34aff",64013:"01a85c17",64092:"4a64cd65",64195:"c4f5d8e4",64604:"78cb4a6f",64818:"3562d692",64837:"b3acedeb",64862:"d60e45e7",64867:"970be792",65020:"44947d78",65031:"60f75da7",65098:"ae2ac924",65153:"e696d855",65207:"0d57c9ce",65360:"c1dcfb2c",65376:"d961eb32",65762:"e36f356b",65776:"2b6cddfb",65819:"6123a303",65870:"7f5d4536",65925:"fd678dfe",66067:"47d00ea8",66191:"42a50931",66211:"08aa19df",66250:"cfdd00ee",66409:"aaf8a98b",66647:"6dc88009",66690:"2fae0427",66701:"89306545",66708:"4163f64d",66755:"af8d5674",67066:"90367a0c",67397:"20261b12",67405:"df0f0c82",67417:"abc8672b",67496:"176f50f8",67537:"0531f00a",67669:"1487a05a",67733:"d1c5891f",67770:"5b2ef1ec",67808:"da428f39",68076:"755f5727",68338:"c63a7218",68359:"ffb195dd",68397:"9cee7270",68557:"818fdb6e",68593:"963c5fcf",68957:"3f3e88c2",69104:"b5cf34bf",69689:"535392e8",69723:"4772c639",69772:"2bd1f1d5",69831:"8a6b4ce0",69897:"93d07a7d",69900:"654ea584",69964:"4f6224ab",70068:"176bd847",70078:"b0f0f9ea",70092:"938eb3c6",70221:"31698e81",70240:"10340a96",70270:"b1b6c66e",70322:"34a86810",70382:"49e160a6",70399:"78fb21bf",70466:"032fffd4",70515:"475925f8",70565:"d1970e70",70584:"2cc02388",70629:"99e171da",70652:"b96bd5f6",70656:"1c903048",70935:"61f46007",71041:"bb8fde8f",71162:"e865228c",71163:"2e1c406d",71231:"83742778",71262:"ceea3000",71483:"b02af4c8",71506:"5bd12569",71517:"09adad8b",71548:"f95d5bde",71596:"6fdb1a49",71607:"5bd0d80b",71714:"522dacfe",71814:"475645e4",71941:"d6d41f50",72033:"8da4a059",72156:"a05f09a9",72184:"235df48b",72199:"731875aa",72357:"1f96a859",72454:"5abe1b36",72471:"83ca98b0",72599:"5cd631d0",72764:"6c206af9",72834:"c0bbd0f3",72912:"211ebb99",73101:"21bcd05b",73118:"2ab612bd",73243:"ef7257b6",73288:"5db54a95",73434:"dc581294",73599:"4f04b67c",73652:"ab305317",73748:"62fc691b",73784:"628983af",73974:"58393540",74035:"8bba30fc",74103:"43e5660b",74110:"dd77d920",74208:"2a8278fe",74221:"26343730",74292:"463da95e",74371:"10fdc2f9",74375:"806c76ec",74428:"162d8ecd",74471:"26bbd135",74475:"d0b4cb1e",74517:"dbe6681e",74677:"d5e881dd",74754:"a0426457",74803:"12b8b985",74963:"e5a0cf87",75032:"b5dcc675",75052:"6700f823",75211:"139f368a",75356:"e1ad0931",75395:"95d06a9b",75477:"5e3dccae",75662:"d09e494b",75704:"34400016",75832:"01a9caec",75850:"4c35dc9e",75876:"127e01c6",75901:"8cb14d65",75916:"0b4c2a3d",75919:"6f05ef64",75963:"fa1821d1",75989:"074b8b0e",76207:"07a1d2e3",76498:"d5e5dad6",76514:"d7f3ddf3",76556:"56a68826",76669:"4e27de2d",76710:"3a0edde8",77016:"8001fdfd",77023:"e2fea577",77121:"15e6962c",77124:"dd2c1da5",77275:"c03c0f30",77353:"ebb9a700",77399:"a3563d94",77518:"2a39cc94",77537:"da0c1bd2",77610:"7e1f6989",77646:"5eb4dd36",77687:"34f95092",77823:"f08decd8",77864:"e905c64d",78198:"348ded7e",78286:"0c54e96d",78363:"4e038d8f",78375:"bfe7c903",78411:"2bd5b017",78562:"fe86874a",78614:"333c39f9",78683:"ec7f210a",78741:"fea6709f",78752:"34691405",78960:"f5e2dcd8",79200:"b083706f",79218:"ba50eb08",79282:"1b772fee",79304:"27373d57",79334:"d8554be0",79361:"be569c1a",79449:"14699dc2",79532:"e742a412",79540:"92d53f96",79625:"03c703dc",79782:"e43161e1",79791:"94135bc2",79933:"db269785",80053:"935f2afb",80172:"4ca247e6",80248:"cddb17bc",80317:"209924ca",80365:"c5aef96c",80436:"094b740a",80707:"b53f8486",80849:"12cc19cd",80887:"c35401ff",80942:"8279fca9",81080:"666a30a7",81285:"f34633ac",81298:"aa989111",81311:"bdf60ba9",81381:"80ea1cbc",81396:"1f431ca4",81437:"db0d3a29",81488:"f4c8b930",81501:"0e939daa",81523:"45d4ac63",81622:"beebc224",81707:"b34d016c",81751:"26715d4b",81802:"d8cd04d5",81886:"f942256b",82e3:"4fc3fce9",82003:"69a4838e",82034:"66256a02",82099:"fa53b2d2",82193:"28c1dcfd",82202:"1f591373",82227:"4f17a092",82326:"566c074c",82334:"1b6b2998",82366:"13b17f0f",82585:"e07be7a4",82604:"82d2094f",82633:"14d680d7",82709:"7cbafffe",82719:"522a8ef5",82897:"bd0616a1",83143:"d33a7fad",83161:"63ce3fd8",83196:"f886b690",83237:"fa11df80",83339:"b6754ca6",83570:"fa88d0b5",83696:"8295bdc8",84572:"ad5d5e29",84606:"414fbbed",84624:"42360cb6",84645:"813ecff9",84747:"0c90eee7",84790:"39196521",84792:"37d7ddc4",84949:"3c28b082",85011:"28732498",85102:"ab3f1a59",85391:"f6987bec",85473:"562ab9d8",85520:"62189c81",85691:"7f0cec17",85730:"d92f7595",85855:"4271cf9d",85869:"e6d1c85e",85890:"85d18f05",85966:"5b807afa",85986:"2debe240",86166:"e6c3444c",86181:"b7bd095a",86205:"7191627f",86219:"379f680a",86372:"6779d527",86720:"49427799",86745:"a956189c",86900:"dbd2f45f",86902:"ba4d23df",86925:"272bf7e1",86974:"40f67231",86985:"9de6c7ef",86997:"1cef52b7",87025:"9c165e1c",87272:"6dea9a1f",87288:"c3a20b5a",87420:"27490d87",87455:"e6efe6e5",87530:"645345c3",87550:"a8d8c1a6",87715:"35ed18d0",87761:"da1b6a63",87929:"af7c3599",88032:"221b8e6c",88054:"5c8ded2f",88107:"3232de46",88133:"820ba869",88201:"9fae688c",88306:"d3e71041",88601:"5db0fd99",88607:"dbdee242",88780:"2ff8124e",88814:"581892d0",88862:"2f318257",88903:"19ccee6b",88965:"f3a3bd10",89042:"229e8a6e",89147:"43fce030",89169:"b939b657",89254:"87f5d21a",89256:"f938c89f",89402:"2734a4e0",89588:"18c44d39",89602:"39dc6d1a",89721:"8ce6e6cd",89800:"aa0e0aae",89814:"676097be",89868:"fecbd6ba",89914:"e258573b",90186:"5d691fd7",90338:"7a51b8fb",90486:"d8d16c0d",90505:"37bf5da1",90545:"ce1357bd",90620:"990edd72",90627:"8ffdb1e5",90659:"8bf4c1f7",90801:"3e5bddb1",90901:"cff47a33",91e3:"b87b9466",91096:"66728c19",91101:"a07880c5",91342:"36bb77cc",91456:"05749ca5",91495:"553308b3",91569:"6da3178c",91636:"99bb8163",91733:"49d4e942",91735:"e915e8da",91776:"543b3fa4",91884:"7075d21a",91895:"01227159",91925:"0ddc651b",92014:"f3cd6f51",92240:"fe34a19d",92279:"6d35ea4e",92282:"440dde57",92395:"fc478f65",92609:"282dba02",92621:"ff91dad4",92646:"d663c1f9",92711:"ea9b195f",92857:"5c45b561",93089:"4b80bdac",93208:"886e6dbc",93297:"738641d7",93322:"525fb3e3",93405:"f3d5df32",93530:"81c35fd5",93626:"9664cf5c",93704:"e8cbe84c",93746:"35ddadc8",93824:"fb92caa1",93911:"f1e3cbd1",93990:"8e36650c",94077:"6c66ac4e",94098:"e3117358",94311:"c8c91710",94400:"90b9c8cf",94464:"b278ebdd",94467:"7f55e260",94513:"8dc7efcf",94813:"89636eb2",94830:"ed270ff2",94893:"936f0bab",94939:"d2a8f56d",95026:"25eaf694",95208:"edfa7f68",95403:"58daa6e0",95418:"2cf7b784",95434:"46777dfd",95463:"a55e208b",95670:"e8bf9c2e",95680:"116b6263",95829:"48106cfb",96042:"33a02dc5",96053:"5b85d5ef",96206:"74e84e95",96266:"6bd0373a",96332:"661d3779",96401:"2d730d1b",96523:"8c91223b",96529:"dac05b1b",96542:"15b73062",96545:"3ae1a1e9",96750:"b69071b2",96765:"221feab1",96794:"02076714",96969:"ed67b2f4",97059:"226c5800",97073:"58e68a6e",97239:"c4c94879",97252:"b674b8f7",97278:"195336ce",97303:"bd523454",97463:"3b068242",97605:"f6f6ae32",97635:"93dc7020",97839:"0e7e5a98",97920:"1a4e3797",97933:"7f53b192",98192:"01d1e1e0",98318:"4b49e2b7",98389:"1ed366b4",98436:"73e805ec",98466:"c9fa40a3",98477:"32312966",98515:"c74cff3e",98645:"183d564a",98696:"d3737fce",98874:"53b60fdb",98991:"4efdb10a",99060:"c070cc9a",99097:"af13a07f",99281:"6ab80c20",99298:"7310399f",99331:"014960ae",99511:"6d34fbb5",99515:"3fa13ed7",99633:"3bed2d65",99695:"5059c1c3",99789:"a7b969c5",99802:"073a06f9",99913:"c2df71fd",99922:"825b40fd"}[e]||e)+"."+{162:"f19c9dd7",195:"264b33ac",440:"1aeedbd8",632:"41da1f7e",808:"9910c205",820:"30f66942",840:"cc7be4aa",983:"1ebb250e",995:"ce7a1dd5",1057:"eaa2a205",1181:"7d7e12f0",1522:"eb6d4da7",1545:"af4c36c0",1557:"ca508c34",1642:"56d64e0c",1679:"f0c85fc4",1869:"65bac75d",1890:"184aa732",2039:"1e6d6f83",2044:"7a577eca",2082:"66a1856a",2085:"dfdc45f5",2246:"853a7f25",2309:"1ee128f1",2447:"8e7feb87",2492:"6d404e77",2514:"798e1bdd",2657:"c061471e",2951:"aac25b72",3082:"64090626",3084:"89051a76",3122:"7407647b",3174:"18d0edba",3421:"988d1790",3433:"ab005c35",3523:"f432400f",3640:"ac5d828d",3814:"737d0238",3837:"ade8aea5",3925:"dac9a081",4018:"162fb094",4027:"307f4f2f",4030:"fe21dfa5",4309:"378b13f0",4319:"15d2d0d7",4391:"83e667ff",4483:"de45a183",4676:"e00b7156",4734:"8296a92c",4845:"759111c5",4893:"9c3910f8",4972:"94ed9b16",5020:"51bc2414",5104:"14e957e9",5218:"b54b8083",5256:"fa538316",5276:"bfb261d3",5326:"4a706aa9",5347:"00961541",5548:"8afbdc27",5701:"5571b30d",5723:"7eb1473f",5844:"f473d0ba",5877:"f509bf43",5912:"3b1fe37a",6008:"f3385d26",6133:"06374b71",6302:"6c53917a",6337:"f76aeade",6358:"99d89a92",6645:"bff55c49",6657:"7647cda2",6729:"70cfc394",6886:"769c8f33",6981:"d9c835fb",7216:"eb0ed6c4",7544:"63cdbbd9",7732:"d3003033",7752:"005f6d63",7860:"e62f74e9",8081:"bd29efc5",8155:"076a3c1c",8346:"e7851ecf",8393:"06350c07",8420:"ce3ef3ef",8652:"26f3dfd2",8697:"0300389d",8699:"61e969b8",8862:"5fe508ea",9139:"7be5b963",9192:"f249beb2",9246:"ad440027",9251:"edd0c08c",9253:"714ff862",9564:"859dddc7",9569:"9e7dc961",9636:"0e97dd37",9711:"d069fb83",9943:"bff8dee4",10061:"7fc948b6",10077:"eadff08f",10194:"924e144b",10199:"1f78ce47",10212:"09d8aaed",10288:"d910d88b",10377:"b10e78ce",10480:"ad9549d1",10488:"6198f624",10735:"db8eaa80",10741:"cd96ac3e",10773:"280d0aa8",10777:"3111efbf",10827:"c155af87",10960:"72b5d842",11041:"c598aa5e",11107:"3a01c2a6",11110:"77ed64c2",11152:"1c2db289",11220:"2bc0dc19",11249:"01decae4",11367:"bd355b7c",11505:"7f20a0ba",11519:"e2a7a33e",11634:"f9c8d070",11650:"d21d9ff7",11695:"bf4c3949",11696:"ac7ea067",11833:"2653e770",11858:"fd1c0acb",11988:"f1ad0345",12471:"0fe6d072",12493:"e491aa28",12537:"b3de8fc0",12539:"67f784bd",12615:"c71aa6c9",12691:"8952b465",13178:"c63b1962",13195:"c5affa01",13211:"d7994645",13267:"3940dc27",13334:"15681ef2",13358:"28180c86",13399:"e63b3566",13430:"f7f9c660",13548:"8731749d",13571:"c5a98cbf",13703:"b097dea9",13854:"361520fe",13924:"46482de1",14016:"e2aab49a",14080:"be4de34b",14089:"1473e5f3",14133:"75b44a4b",14489:"6b8d94c7",14493:"d4129bf7",14518:"b76aa1b6",14582:"10de9281",14642:"a8447a05",14645:"7eacb4a6",14678:"449b9fd4",14730:"2a984e8b",14917:"400fe1ef",14945:"7c20851f",14966:"dabc3cbc",15002:"ab8c313e",15095:"4e3cc9fc",15118:"037ef89a",15140:"30ffa213",15289:"da956039",15364:"78e76106",15542:"7097a10e",15595:"ffd4fc4d",15615:"d1ee3203",15659:"dcad8575",15674:"44732021",15729:"e867aa51",15736:"f43081e5",15899:"4bd2b47f",15999:"7c4d2d57",16080:"6709c0dc",16322:"23f13ccc",16378:"b570f7ec",16486:"56533730",16613:"d9bd468e",16634:"08700a44",16754:"a7afb422",16756:"148f817e",16799:"9abc6b69",16818:"f1a82d5e",17036:"2e6b10fb",17135:"fd98f40a",17190:"a4b7356c",17295:"f9549530",17533:"a892528b",17545:"36b4d373",17642:"ae553c35",17694:"de913d2b",17738:"54ce774c",17867:"134f8e71",18166:"f4274c93",18291:"b4402c13",18582:"ee631c0d",18591:"2d79f471",18750:"8ab76738",18859:"0d0a6f27",18894:"720fe000",19048:"35ad9bd3",19067:"c170428c",19116:"cafd3b34",19117:"5a97d681",19308:"987de577",19374:"0f656105",19380:"4122aea1",19626:"edbb8c15",19679:"c955eb4d",19704:"a29a6a7d",19731:"fdb50dd4",19801:"97b87886",19879:"d9f63909",20044:"67528b24",20062:"ea2b5439",20228:"93f19136",20260:"6f3a6724",20305:"0ea27c23",20562:"861e5c07",20611:"5d6aa368",20630:"94f307cf",20683:"79a9a66d",20701:"f57d0b80",20751:"2f069671",20827:"ae0e1189",20977:"36dd15db",20999:"19baf6e2",21143:"6bb55ecb",21155:"1efce90e",21182:"1b2d698a",21199:"07252061",21636:"72523d6e",21691:"139c4623",21725:"14086c9b",21763:"32b6bce7",21776:"2d2901a7",21962:"5d6b5f81",22070:"ace22bec",22083:"dce94d26",22255:"3ed8d493",22350:"d478ef01",22529:"3c6f7f3c",22554:"56645e89",22673:"1111b369",22771:"d7e8a502",22800:"192b2608",22835:"9a851f43",23097:"193ab891",23120:"469d630c",23121:"f6908900",23122:"d85e5759",23221:"867595eb",23275:"a65735c2",23332:"ae6f1e65",23372:"5876b0df",23422:"25f06fe4",23486:"ed66310c",23522:"0439ba51",23650:"2f569f41",23685:"e811ef91",23719:"662f711c",23770:"f583467b",23982:"58204e19",24155:"353600f9",24428:"1c4b578c",24538:"24a9c49a",24595:"79fedf55",24637:"2b4e0d2d",24782:"d126882e",24813:"6d392eca",24850:"694ff0dc",24877:"1c706ddb",24886:"8ae79a34",24949:"7f3f96cf",25444:"9d1dcad4",25572:"de9d09c5",25586:"7bc386ef",25613:"f11a793e",26050:"9d0957ae",26108:"940b6889",26168:"5ad90ea7",26214:"2b4005e5",26241:"732c1738",26258:"a624105f",26302:"71a40812",26328:"fb4edb7e",26351:"cd9c3321",26397:"2cb00f39",26407:"e0d7ec73",26457:"ac2fe568",26647:"df3b9026",26651:"06c72e0d",26958:"51ca300c",27015:"f111e688",27168:"1a40c740",27272:"153c9a16",27284:"1a5b3a0a",27329:"99f5ca06",27378:"a0e82cb0",27628:"825e06e3",27703:"091588c4",27723:"e57dc3da",27745:"d76b9627",27787:"da367911",27802:"6155b1c7",27864:"ffaf5024",27878:"a07421b8",27918:"2e8b459f",27939:"7a303999",28085:"d7326d0b",28103:"252208f4",28171:"1db744c7",28261:"f7d5e510",28323:"0f683be5",28336:"5d28cb64",28370:"2a212b26",28414:"159d03e1",28527:"df95bfd8",28681:"3528e102",28793:"cb0f5ec6",28837:"1b82fdf8",28993:"4edc14ac",29092:"f5fa07e5",29285:"608e8959",29506:"03661d2c",29514:"dd0434ed",29555:"0e536735",29583:"23d2890b",29630:"876dacfe",29657:"b19798fc",29723:"bcab7941",29757:"840e9960",29796:"f23e8986",29820:"d15fb394",30280:"7bcd8c18",30325:"b73cc895",30340:"4e0cc3e1",30368:"ba381844",30495:"4950757d",30555:"b3be1371",30572:"163b4c31",30578:"7499e69e",30672:"8dc10e33",30738:"dfcbb355",30743:"b4b7245b",30747:"aaea598b",30782:"ed951bf4",30954:"8e489f6e",31002:"ea32e307",31036:"02cbdd68",31091:"117e15d5",31110:"ddc92820",31213:"c91c21a4",31330:"1dcc5d07",31574:"5325ba5d",31595:"1ada05b1",31604:"bbcb6fee",31642:"8ba69c0a",31952:"e2082121",31968:"52910b3c",32035:"2f015ba7",32351:"2670866c",32361:"5828da9c",32562:"de078b67",32620:"4c5f4344",32646:"93e07a49",32718:"80025ce8",32734:"40f2ce5f",32771:"08f35c08",32829:"97f9ac68",32856:"9c2c2358",32894:"31c8528e",32928:"b1bc1522",32952:"bd6958d9",33548:"9791e9bf",33567:"7c0a7899",33609:"1cc336b3",33620:"d81950bb",33789:"9211da95",33881:"7b5ac3e7",33922:"54edfc7b",33950:"106ecbdd",34151:"bdbefac9",34173:"f41ecb75",34203:"a9ca823e",34238:"28be8d78",34249:"8008690e",34274:"ade64241",34287:"700a47df",34465:"c041ed50",34523:"a783a0f5",34842:"d25462b4",34929:"ab75feac",34952:"15c8aab9",35120:"c667d89c",35211:"8d50a113",35298:"8b7aa6e4",35565:"ecf5646a",35616:"926f96d6",35647:"74c783e6",35886:"74b37ff0",35936:"6c52b225",35973:"b35e1b6a",36021:"7f737534",36077:"798a69ca",36099:"236a080c",36180:"db06450a",36186:"a14ae5ba",36377:"8caa9c1b",36529:"16233633",36569:"5ee5e069",36757:"5c39eba4",36779:"8f8b0de0",36836:"4cd801b6",36861:"311981a7",36975:"4079e582",36996:"edd1aecb",37104:"d8b01467",37163:"b250c687",37255:"cf32676f",37338:"04ea6019",37631:"63aa697a",37883:"66192b05",37952:"579a277a",38181:"1a90259d",38189:"54875155",38371:"f7a8bc33",38788:"9b14d356",38811:"831cf10a",38891:"71dcf907",38993:"8735fa46",39093:"5aa16908",39190:"8bb536b3",39212:"55baa0d1",39300:"b9b6d1a0",39343:"f871156a",39399:"564b82a1",39468:"93511063",39553:"a9c9f811",39773:"3d4968e6",39977:"63bf0f9e",40003:"db4b6c63",40028:"d2f2be02",40116:"e04a8cac",40193:"5fd8aa32",40265:"7828b026",40504:"2980c50d",40601:"dca60534",40659:"5b095ff8",40948:"616207b0",40951:"46cc611e",40967:"91f3d8ac",40993:"fc4a9969",41331:"fbc4f97a",41344:"bccdea11",41403:"ecd6b879",41750:"4eaae860",41771:"d12639e8",41784:"d6fbd1db",41933:"a9b03064",42013:"45867001",42115:"be5c41eb",42134:"80c00187",42203:"ac8d673e",42214:"76d30402",42314:"61e4fe67",42495:"c9b79ad5",42506:"cf75e2ff",42553:"867ac4a9",42609:"752c1848",42677:"473c42a6",42791:"6a6a3671",42815:"ad8d2ff6",42919:"624e5fe3",42960:"72e9fa23",42978:"6e301124",43055:"5c1838ec",43085:"6103307d",43267:"38c31208",43361:"8716d463",43763:"fb0a166e",43837:"22b7cbad",43930:"51e2c64f",44032:"6097f065",44049:"3caa29b8",44235:"5e9dc497",44247:"cdc74ca5",44258:"f1ca2e0c",44308:"2377a57a",44401:"88225e94",44426:"53e7433a",44509:"b58c8d76",44561:"388e60b8",44973:"ec6d2c37",44984:"b582b306",45020:"18bf88b4",45049:"f3beac4c",45314:"92705574",45443:"b5456089",45709:"dd24bf4b",45728:"c8160e1f",45906:"b34e2b81",45992:"deaf1d11",46048:"81079b48",46076:"4c78fe8b",46103:"f5b60dac",46200:"cbdafad1",46360:"bbfd9091",46408:"1a7efa9a",46609:"fb323bc9",46628:"b47c466e",46687:"5b4d170e",46708:"1fb4d78c",46744:"9b0c65a8",46797:"ae2ee5ff",46852:"2559f0d3",46869:"1de3e423",46945:"70ad4e4d",47049:"67364de8",47133:"96c06608",47324:"3c907066",47404:"05baf8ad",47487:"7b351da1",47567:"9828a0d1",47658:"e7aa0954",47713:"869ba4ea",47734:"a05252e1",47740:"bc6cf802",47756:"3be0bd8b",47953:"20141070",48354:"466d19e2",48429:"f2170e10",48610:"cdcf9bd8",48647:"2822b3b5",48700:"e2b6bbe3",48882:"8db7fc36",48921:"a917eac1",49030:"c850cc6a",49038:"750650ef",49152:"9890e3f9",49292:"e5a80513",49437:"bc0fbfcb",49468:"2ead9785",49498:"f56960ce",49525:"79ff1717",49786:"e07e59af",49813:"2bbc85ac",49862:"41099c3c",50134:"d9102772",50278:"58fb96c6",50286:"76c8d6fa",50496:"ac63fb88",50509:"6cfa2310",50601:"13974574",51070:"20e9d786",51139:"b06199d1",51153:"4ef282ad",51246:"9bb28164",51297:"3f8c3441",51563:"cdd03259",51609:"74499353",51665:"7a8a8c33",51725:"2df087be",51815:"fe20f492",51823:"2b369e75",52016:"cbc6efb9",52179:"406d75c4",52206:"816da6c5",52237:"44bba918",52246:"15c07dd2",52351:"ac32a61d",52466:"87237cfe",52535:"072d69aa",52830:"ae61d8f8",52979:"76b2e727",53046:"bb05dd95",53047:"8a6cf1a7",53105:"863e05ac",53204:"ab6731da",53506:"c0f209f5",53608:"ed64357a",53696:"79a01761",53722:"646fbf8a",53803:"9a275c06",53838:"9f8923cc",53918:"4eb61f3b",53954:"5a9e27c0",54052:"cfab1023",54062:"8192abff",54258:"73527f0b",54336:"25930eb9",54410:"e8bf0afa",54438:"4bc0b921",54608:"19d53eec",54619:"dd650c31",54653:"fb74baa2",54655:"c1e1f348",54776:"205ea854",54793:"41fb43d1",54923:"0552654d",55022:"6085e8d9",55037:"62b5bd29",55162:"1a42adca",55221:"352b0062",55573:"fb32649d",55632:"e8169c2a",55755:"2b379720",55886:"4b6babd6",55956:"2ccff26d",56033:"cb31da25",56201:"91ae2d25",56327:"9178acb8",56446:"fa5017da",56590:"6d64bc22",56663:"35f825c0",56752:"3ef2045d",56846:"3cee2715",56943:"4a010041",57009:"e2f5e48a",57089:"82035c43",57097:"dd6f10aa",57119:"d6d55018",57132:"f873d4c4",57144:"24ce2d9b",57234:"f3f380b7",57420:"6bc4e7af",57424:"64f36937",57768:"3b0cbd3f",57819:"b98dd03b",57874:"fe93cb7d",57891:"b51a95a0",57993:"9a856d4f",58193:"3718d94a",58261:"919d4803",58388:"919c0ad6",58416:"85e9bae4",58536:"4e4ffd09",58556:"d92e82e0",58694:"c374d774",58751:"7ef1370c",59164:"69fa01e6",59243:"e9eb4396",59258:"f3750ba9",59433:"8d926128",59461:"d6225260",59617:"3f1b7063",59619:"42c899d4",59632:"dcbd218d",59681:"bfa0764e",59703:"3086dbb9",59753:"b558d2c1",59776:"f68bc966",59801:"588eea01",59935:"6c6e7f71",59957:"d22dab3b",59982:"1211f851",60231:"32e533aa",60297:"e02eac1c",60305:"93e65a98",60321:"fd401dff",60331:"f66ad8e4",60344:"bca7f1f8",60384:"7c1f5f3a",60523:"d292ae18",60625:"271aaaf2",61038:"213571c0",61189:"ca3affdf",61365:"b4c52c42",61385:"9cb26ebc",61523:"bb7ede40",61554:"7891f7ea",62170:"c99e0a68",62505:"14d83885",62725:"02acf96b",62809:"e3aa878d",62837:"c1d4abc5",62944:"efb772f1",63016:"2f4a6fd3",63100:"8cf7989f",63193:"fea39589",63214:"390a0935",63388:"2f0f6123",63442:"f11cf20e",63526:"ba6a2db0",63600:"4c0241f7",63650:"cb485153",63676:"85e9b86c",63686:"b5989604",63694:"f9da93c0",63891:"9ab5eaf4",64013:"c72a1fdd",64092:"59853f27",64195:"73a1e872",64604:"010a274c",64818:"69cb7052",64837:"e823cb3b",64862:"951c8cf6",64867:"05a9e0cf",65020:"f72d935e",65031:"7d6c5e73",65098:"b80437c0",65153:"d3e4fb7b",65207:"ea9544e9",65360:"1d4c94d5",65376:"c41c486d",65762:"5e5a04e5",65776:"45910a21",65819:"b638008a",65870:"c662f287",65925:"8c50f06e",66067:"a6693dc1",66191:"9dc80463",66211:"fc858866",66250:"8a0c72a1",66409:"4721094b",66647:"c922d5ff",66690:"f2348832",66701:"0787318c",66708:"96b99f49",66755:"e012687d",67066:"c599fc47",67397:"f46d222e",67405:"373e96a6",67417:"e78db44e",67496:"f9cf67b5",67537:"ec2382ef",67669:"99a28219",67733:"f32bd6fa",67770:"35d7d5f3",67808:"7af430e0",68076:"053db970",68338:"eb261de6",68359:"3b379e60",68397:"19a59a88",68557:"62ab26f4",68593:"d5517f28",68957:"8377f69b",69104:"05d7b998",69689:"c7a0a5bc",69723:"728bf9e4",69772:"d30f5c4c",69831:"1a1e66d0",69897:"b4825953",69900:"1b9e227c",69964:"046a34f8",70068:"1d1bea04",70078:"583546a0",70092:"a78a5d75",70221:"083dac6b",70240:"cc4be49d",70270:"c3ed7aaf",70322:"23e6c0de",70382:"16535e30",70399:"ae3d3dc2",70466:"1abe2872",70515:"db6ec03a",70565:"aed1bdd8",70584:"09d5b912",70629:"870735a5",70652:"4c23d4d3",70656:"0f002979",70935:"5832e917",71041:"e4a3c236",71162:"caa7aae2",71163:"e5236bec",71231:"a11ef9de",71262:"21c8ad9d",71483:"f5df5ddd",71506:"5b9a7385",71517:"e3c5691e",71548:"afd05b82",71596:"1ee609db",71607:"c1607640",71714:"c1396844",71814:"7d5ba3b5",71941:"5fe091f1",72033:"a77474a5",72156:"f6777991",72184:"4b71fee2",72199:"f18694c8",72357:"494fa0dc",72454:"883c42e1",72471:"1f442c2d",72599:"5a559f6e",72764:"79d4cbf3",72834:"1eb113e2",72912:"034e3896",73101:"641e3e32",73118:"8b8c6884",73243:"a58b53de",73288:"da180c69",73434:"9bb33b4d",73599:"29e04e25",73652:"ccafaae3",73748:"c9684cb1",73784:"fee9e459",73974:"b93fc295",74035:"7d696710",74103:"ea3ec24e",74110:"a0c94efd",74208:"df7c1e8f",74221:"045ce587",74292:"91af8320",74371:"e6be8dff",74375:"1b765f73",74428:"9c3a20e2",74471:"5e855cf3",74475:"7e98a9e0",74517:"1be35da6",74677:"673b546f",74754:"f0d2fc8c",74803:"d0cf7ffc",74963:"274164b0",75032:"33eb3d16",75052:"e46411a7",75211:"67d49e22",75356:"7e02e9ec",75395:"566415f6",75477:"b97523ec",75662:"5f413c1b",75704:"ccc91543",75832:"d0261263",75850:"48bfc804",75876:"50bd5965",75901:"4e2f0720",75916:"eba70766",75919:"fda810e7",75963:"ddbdfe6a",75989:"c65b2026",76207:"5a4c0441",76498:"c80254a0",76514:"f4d96396",76556:"70dcf01d",76669:"5bbddee0",76710:"0e2159a1",77016:"cb89d3e0",77023:"31a1d9e0",77121:"6c3f1686",77124:"7e828bde",77275:"1981223a",77353:"9fa5ae82",77399:"f1aa9e09",77518:"edf4268d",77537:"74869200",77610:"1f49f488",77646:"810a55fd",77687:"c8a883d8",77823:"32bdb30c",77864:"195a8112",78198:"aa768773",78286:"6f07e364",78363:"099d048f",78375:"b276118c",78411:"268cb097",78562:"1f937441",78614:"4a53634e",78683:"38af36a2",78741:"6c304afe",78752:"7a6900b8",78960:"c6ae250f",79200:"6fe66561",79218:"7492323d",79282:"721b8af7",79304:"0565ad04",79334:"88c23a98",79361:"3b614906",79449:"67043f81",79532:"4582db91",79540:"46203971",79625:"8efd22ba",79782:"d109cf55",79791:"7ff1a7ef",79933:"b6dd4a44",80053:"33ddf85f",80172:"d67a3f86",80248:"fb4b5abc",80317:"bc5a9480",80365:"4e7798ba",80436:"d443d23d",80707:"e9166ca0",80849:"465ff347",80887:"344f3dd2",80942:"a7fd4b4e",81080:"6053b89a",81285:"02ba1e0b",81298:"4357fd9a",81311:"9aa199b9",81381:"d7adf0ae",81396:"485cbba3",81437:"08fa5c19",81488:"19989853",81501:"8100a457",81523:"928030ab",81622:"072b8511",81707:"ff49f4f3",81751:"d2f7bd04",81802:"7266371d",81886:"40d46503",82e3:"c36f2bf7",82003:"5d9843af",82034:"f23d6a1d",82099:"8a2824cb",82193:"0e18a12b",82202:"3c0b8957",82227:"a200ce4d",82326:"0c4658ed",82334:"f6fe4b01",82366:"22ccf47a",82585:"c568edeb",82604:"d469bd8b",82633:"c6477015",82709:"0a0d5f30",82719:"e8746d8b",82897:"64a1db0c",83143:"3a39f029",83161:"02635b22",83196:"0b737d08",83237:"913c6c55",83339:"8c20d9a6",83570:"5e9d83e4",83696:"ca59e747",84572:"170524c2",84606:"dff9fd8a",84624:"1993b218",84645:"28d17a30",84747:"9a91d412",84790:"8a132ce6",84792:"106a2467",84949:"b88c6944",85011:"cd647c34",85102:"5e4ebfa2",85391:"86edb779",85473:"de39892e",85520:"b93d75fe",85691:"9d9b7599",85730:"a48558fe",85855:"a89df95c",85869:"6ae63b22",85890:"5a69e5b2",85966:"64dda0ee",85986:"2890cafb",86166:"184dd6a4",86181:"33e58e25",86205:"094c56f1",86219:"22250e0f",86372:"dc46993a",86720:"41862e9e",86745:"1a5eafe5",86900:"a4b548ea",86902:"999e3db3",86925:"aec517b4",86974:"acdf6505",86985:"1263b029",86997:"c0dd6c21",87025:"3389a2cb",87272:"5bd69767",87288:"89cc97b2",87420:"42496ee4",87455:"0aa15019",87530:"65e325ae",87550:"0c0badd8",87715:"5aa20c19",87761:"2141129a",87929:"cdaf9fb9",88032:"76aee412",88054:"1eba9309",88107:"589896a7",88133:"36c2bf22",88201:"de08ac94",88306:"c2afe687",88601:"29e3986c",88607:"23c4b474",88780:"d6128200",88814:"d98137d3",88862:"85b02bbe",88903:"4d782f43",88965:"e485e92f",89042:"4e6ca00d",89147:"9289166a",89169:"d917799e",89254:"7f88cc94",89256:"e007806d",89402:"05b42e23",89588:"032020c1",89602:"491fc269",89721:"87690263",89800:"dc357da3",89814:"8ed7fc26",89868:"186db7ba",89914:"14386b3c",90186:"9e87ecac",90338:"a04cc71d",90486:"6af6f3e4",90505:"8b7a2f2c",90545:"4d9116f4",90620:"0fc95c31",90627:"e92076cb",90659:"4dd06be7",90801:"c8c13e6e",90901:"195b534a",91e3:"558bf5c3",91096:"842c1cbe",91101:"f7d7649b",91342:"6d504d8d",91456:"2fb90812",91495:"31990160",91569:"1d4686e4",91636:"3cf003a4",91733:"09cf16eb",91735:"47d3275a",91776:"358a43cd",91884:"9450a1f1",91895:"18d2959b",91925:"ffd0b711",92014:"45ab6051",92240:"4654f229",92279:"b37988ec",92282:"776a48d1",92395:"1379736d",92609:"34d04396",92621:"be17476b",92646:"f8492b2c",92711:"d6107aa0",92857:"1a84c751",93089:"474c16a9",93208:"d880ff22",93297:"7f815050",93322:"69fa218b",93405:"169a3eda",93530:"75a92296",93626:"2ea31b3f",93704:"16428304",93746:"a84ce850",93824:"5e7418a0",93911:"21e57c84",93990:"55c2784b",94077:"643f58db",94098:"8b15c9e6",94311:"5d2129ef",94400:"96f40d6e",94464:"ecfc8bfd",94467:"ff3917e7",94513:"b7076f53",94813:"9459303b",94830:"13958ceb",94893:"53c97b59",94939:"0f0dcb29",95026:"73daf737",95208:"592b5c84",95403:"7574856f",95418:"d4e2d48e",95434:"2339c637",95463:"4d766ed0",95670:"c16c1ba6",95680:"1a842c57",95829:"05e1d1bf",96042:"0dfdaab6",96053:"3dcaeb8c",96206:"21e8c421",96266:"217afb9c",96332:"71dfdbbf",96401:"9b8ff31d",96523:"20f0de27",96529:"7415fcf9",96542:"a542befc",96545:"330edc89",96750:"ef157ae8",96765:"c023231c",96794:"276c4d75",96969:"d315fd4a",97059:"8196fbdc",97073:"679e998f",97239:"e9b19c99",97252:"fdd60c48",97278:"40106419",97303:"35973930",97463:"bb6ac8de",97605:"ae9ca355",97635:"140b7912",97839:"efcfa8fb",97920:"339c81f3",97933:"9ca7a817",98192:"01f0be10",98318:"ceae3458",98389:"5670d2c0",98436:"16ee8b42",98466:"e42ccdad",98477:"52dc3dcc",98515:"e5e986f7",98645:"037144ce",98696:"e1f95067",98874:"aaf983be",98991:"9c31f420",99060:"6a549612",99097:"57dc0eb7",99281:"2d204353",99298:"1eebf09b",99331:"8840ab8e",99511:"386e7f53",99515:"4764ed1c",99633:"edca8ed6",99695:"340a4e6b",99724:"69865832",99789:"4be7a0d7",99802:"9fca0a7b",99913:"bf9e84ad",99922:"8bbf3a56"}[e]+".js"},n.miniCssF=function(e){},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=function(e,c){return Object.prototype.hasOwnProperty.call(e,c)},f={},b="nativeextensions-documentation:",n.l=function(e,c,d,a){if(f[e])f[e].push(c);else{var t,r;if(void 0!==d)for(var o=document.getElementsByTagName("script"),i=0;i
- + \ No newline at end of file diff --git a/docs/adverts/banner-adverts/index.html b/docs/adverts/banner-adverts/index.html index d666bb7e496..1d31a94c1a8 100644 --- a/docs/adverts/banner-adverts/index.html +++ b/docs/adverts/banner-adverts/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Banner Adverts

Banner advertisements are represented by the AdView class. You create an instance of this class using the extension and then use this instance to set properties, load and display the advert.

Creating an AdView

To create an AdView use the createAdView function. This function takes a callback function of the form function( adView:AdView ):void and will be called as soon as the AdView has been created and is ready to use.

Adverts.service.createAdView(
function( adView:AdView ):void
{
// Set properties and load ads as required
});

This will instanciate an instance of the AdView class.

Size and Ad Unit ID

You must set at least the size and ad unit id properties on your AdView to correctly setup the view before use. Without these properties the advert will not display correctly.

adView.setAdSize( AdSize.SMART_BANNER );
adView.setAdUnitId( "ca-app-pub-3940256099942544/6300978111" );

You can use any of the predefined AdSize constants to set the size of the advert.

Adaptive Banners

Adaptive banners are the next generation of responsive ads, maximizing performance by optimizing ad size for each device. Improving on smart banners, which only supported fixed heights, adaptive banners let developers specify the ad-width and use this to determine the optimal ad size.

To pick the best ad size, adaptive banners use fixed aspect ratios instead of fixed heights. This results in banner ads that occupy a more consistent portion of the screen across devices and provide opportunities for improved performance.

When working with adaptive banners, note that these will always return a constant size for a given device and width. Once you've tested your layout on a given device, you can be sure that the ad size will not change. However, the size of the banner creative may change across different devices. Consequently, it is recommended to ensure your layout can accommodate variances in ad height. In rare cases, the full adaptive size may not be filled and a standard size creative will be centered in this slot instead.

Important: You must know the width of the view that the ad will be placed in, and this should take into account the device width and any display cutouts that are applicable.

To use adaptive banners, replace any calls to setAdSize() with setAdaptiveAdSize(). This function takes two optional parameters, the width and the orientation. The simplest option is to use the defaults,and then the extension will calculate the available width based on the current orientation and use that for creation of the adaptive banner size.

Adverts.service.createAdView(
function( adView:AdView ):void
{
adView.setAdaptiveAdSize();
adView.setAdUnitId( "ca-app-pub-3940256099942544/6300978111" );

...
});

If you wish to preload an advert for a different width / orientation you can pass in the appropriate values, eg to set the :

adView.setAdaptiveAdSize( width, "portrait" );

Valid values for orientation are:

  • portrait
  • landscape
  • auto (default)

If you are specifying an orientation different from the current, then you must supply a valid width.

Loading

To load an advert into your view you use the load function and pass it an AdRequest object which will specify the details of the ad request to load. You create an AdRequest by using the AdRequestBuilder. The builder is used to correctly create the request object and easily set the availble properties on the request.

The simplest example is to just use a generic request:

adView.load( new AdRequestBuilder().build() );

You can set properties, such as adding a gender to the request, using the other methods on the builder:

var request:AdRequest = new AdRequestBuilder()
.setGender( AdRequest.GENDER_MALE )
.build();

adView.load( request );

See Targeting for more on the AdRequestBuilder targetting options.

You can listen for events that will inform you on when an advert is available or if there were any errors in loading the advert. There are two events of interest here:

  • AdViewEvent.LOADED: dispatched when an ad has finished loading;
  • AdViewEvent.ERROR: dispatched if the ad failed to load

You can use the loaded event to delay displaying the ad until you are sure an ad is available.

adView.addEventListener( AdViewEvent.LOADED, loadedHandler );
adView.addEventListener( AdViewEvent.ERROR, errorHandler );


function loadedHandler( event:AdViewEvent ):void
{
// Ad loaded and ready to be displayed
}

function errorHandler( event:AdViewEvent ):void
{
// Load error occurred. The errorCode will contain more information
trace( "Error" + event.errorCode );
}

If an error occurs you can use the errorCode on the event to determine what type of error occurred. See the troubleshooting guide to determine what happened.

Testing and Development

It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.

While in development you should either use the test ad unit ids available or specify your test device id in your ad requests. More information on this is located in the section on Test Ads

The following Ad Unit IDs can be used to AdMob test banner ads in your application:

  • Android: ca-app-pub-3940256099942544/6300978111
  • iOS: ca-app-pub-3940256099942544/2934735716

Display

When you are ready to display your advert you call show() as below.

adView.show();

You don't have to wait for a load complete event to show the ad. However if you want to ensure that something is displayed in the view then we suggest you wait for the LOADED event before showing your ad view.

You can also remove the ad from the view by calling hide(). This is the reverse of the show function and will remove the ad from view, while not unloading the ad.

adView.hide();

View Parameters

Changing the view parameters of an advert allows you to reposition the advert to suit your application.

The view params are probably best used to align the advert to a particular horizontal and vertical location in your application. For example to align the ad to the bottom left of your application:

var params:AdViewParams = new AdViewParams();
params.horizontalAlign = AdViewParams.ALIGN_LEFT;
params.verticalAlign = AdViewParams.ALIGN_BOTTOM;

adView.setViewParams( params );

You can also use the view params to position the adview at a specific location:

var params:AdViewParams = new AdViewParams();
params.x = 10;
params.y = 10;

adView.setViewParams( params );

Note: Setting an alignment in your view params will override the x,y coordinate

Retrieving the size of the advert allows you to get the pixel size of the displayed Ad.

var size:AdSize = adView.getAdSize();

trace( "pixel width: " + size.widthInPixels );
trace( "pixel height: " + size.heightInPixels );

This can be useful if you need to adjust elements of your application to fit around a banner ad.

Events

There are several events dispatched by the advert as the user interacts with it:

  • AdViewEvent.OPENED: dispatched when an ad opens an overlay that covers the screen;
  • AdViewEvent.CLOSED: dispatched when a user returns to the app, having closed the interstitial;

At the very least we suggest you should listen for the closed event to know when control returns to your application.

adView.addEventListener( AdViewEvent.OPENED, openedHandler );
adView.addEventListener( AdViewEvent.CLOSED, closedHandler );

adView.show();


function openedHandler( event:AdViewEvent ):void
{
// The has been opened and presented an overlay visible to the user
}

function closedHandler( event:AdViewEvent ):void
{
// Control has returned to your application
// you should reactivate any paused / stopped parts of your application.
}

Refresh

You can refresh the ad at any time by triggering another AdRequest load:

adView.load( new AdRequestBuilder().build() ); 

Destroy

When you are finished with an AdView instance you can cleanup any memory consumed by the ad by calling destroy():

adView.destroy();

No other methods should be called on the ad view after destroy() is called as they will have undefinted results.

- + \ No newline at end of file diff --git a/docs/adverts/changelog/index.html b/docs/adverts/changelog/index.html index 8e582eef3d1..fdb57d01051 100644 --- a/docs/adverts/changelog/index.html +++ b/docs/adverts/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.08.18 [v14.3.0]

feat(huawei): update hms sdk v13.4.62.302
feat(android,ump): update ump to v2.1.0 (resolves #509)
feat(android,admob): update admob sdk to v22.2.0

2023.07.05 [v14.1.0]

feat(android): update google admob version to v22.1.0
feat(ios): update google admob version to v10.6.0
fix(docs): add kotlin missing dependency from manual integration docs

2023.05.08 [v14.0.3]

feat(android): background thread handling (resolves #456)
feat(ios,android,admob): add function to set admob network extras (resolves #461)

2023.01.12 [v13.8.1]

feat(ios): update ios admob sdk to v9.14.0

2023.01.12 [v13.8.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): update android admob sdk v21.3.0 (resolves #427)
feat(huawei,android): update huawei ads sdk v13.4.58.301
fix(android): add UMP fail gracefully if ad identifier dependency not included (resolves #444)

2022.11.01 [v13.7.7]

fix(ios,admob): correct issue setting server side verification options on rewarded video ads (resolves #371)
feat(docs): update docs for admob move from funding choices to privacy and messaging
fix(docs,package): add appset extension dependency

2022.11.01 [v13.7.7]

fix(ios,admob): correct issue setting server side verification options on rewarded video ads (resolves #371)
feat(docs): update docs for admob move from funding choices to privacy and messaging
fix(docs,package): add appset extension dependency

2022.09.26 [v13.7.5]

 fix(android,nativeads,admob): resolve issue with native ads set to not visible reappearing after main activity resume (resolves #424)
fix(docs): remove unnecessary permissions

2022.09.16 [v13.7.4]

feat(rewarded): add information on the reward to the LOADED event for rewarded video/interstitial ads (resolves #421)

2022.08.08 [v13.7.3]

feat(docs): add documentation on removing AD_ID permission using apm (resolves #407)
fix(android,admob): correct issue with not handling nativead error dispatch (resolves #413)

2022.07.20 [v13.7.2]

fix(airpackage): correct airpackage assets overlap between admob and huawei implementations

2022.07.20 [v13.7.1]

fix(build): build with AIR 33.1.1.856 due to issue with SWC generation in 889 (resolves #409)

2022.06.24 [v13.7.0]

feat(admob): update admob android sdk v21.0.0

2022.06.23 [v13.6.0]

feat(ios,admob): update ios sdk to v9.2.0 (#371)
feat(admob): add life time value implementation (resolves #361)

2022.03.08 [v13.5.0]

Update SDK: 
- iOS v8.13.0
- Android v20.5.0

Android 31 support (resolves #365, #366, #349)
Documentation update for Android 31 and apm usage (resolves #359)
Android: Update lifecycle handling on some admob adviews
App Open Ads (resolves #257)

2021.12.23 [v13.4.1]

Update documentation and examples on manifest additions for admob (#352)

2021.11.16 [v13.4.0]

Update AdMob iOS SDK to v8.12.0
Add AdMob iOS support for inline adaptive banner sizes (resolves #322)

2021.10.05 [v13.3.32]

Updated package to correctly include admob android application id (resolves #334)

2021.09.13 [v13.3.31]

Corrected Rewarded interstitial event dispatching incorrectly (resolves #326)

2021.08.31 [v13.3.29]

Deprecated the advertising identifier to remove AdSupport / ASIdentifierManager usage (resolves #305)
Implemented Rewarded Interstitials (resolves #297)
Corrected processing of RequestConfiguration on iOS 12 (resolves #301)

Updated UMP SDK v2.0.0
Updated Admob SDK
- Android v20.2.0
- iOS v8.9.0

Added air package

2021.06.19 [v13.2.013]

Android: AdMob corrected issue with native ad templates (resolves #293)
iOS: AdMob Corrected user identifier set on rewarded video ads (resolves #292)

2021.06.14 [v13.2.009]

Corrected new AdView delegate definitions on iOS causing issues with events (resolves #290)

2021.06.09 [v13.2.006]

Removed legacy google consent sdk (resolves #287)
Updated consent sdk docs
Added isSupported flag to Consent SDK
Corrected default lib definitions (resolves #288)

2021.06.05 [v13.1.002]

Updated AdMob SDK
- Android v20.1.0

Added adaptive inline banner sizing setInlineAdaptiveAdSize and setInlineAdaptiveAdSizeWithMaxHeight (resolves #279)
iOS: Fixed crash with UMP caused by removal of consent type information (#286)

2021.05.11 [v13.0.009]

Updated AdMob SDK
- Android v20.0.0
- iOS v8.4.0

Major refactoring around AdMob restructured SDK, introducing FullScreenContentEvent and RequestConfiguration

2021.01.20 [v12.0.009]

Updated AdMob SDK
- Android v19.6.0
- iOS v7.69.0

2020.12.11 [v11.0.001]

Huawei Ads Kit addition (resolves #220)
Fix iOS AdMob issue with platformVersion (resolves #225)
Added documentation on multidex (#223)

2020.11.25 [v10.1.037]

Added support for AdMob Open Bidding (resolves #211)
Updated initialisation process
Deprecated wiki

2020.10.19 [v10.0.025]

Updated docs (resolves #202, resolves #210) and corrected App Tracking framework dependency (resolves #208)

2020.10.04 [v10.0.021]

Implemented User Messaging Platform (resolves #195)
Updated initialisation process to better handle consent

Updated AdMob SDK
- Android v19.4.0 (#194)
- iOS v7.66.0

2020.08.14 [v9.2.128]

Updated AdMob SDK
- iOS v7.62.0
Updated build and docs with new AdsIdentifier Google Play Services
Android: Corrected native ad ratings star display
iOS: Fixed white background on ios native ad template

2020.06.11 [v9.1.047]

Updated AdMob SDK
- iOS v7.60.0
Updated show/hide of banners and native ads (resolves #174)

2020.05.25 [v9.0.022]

Updated AdMob SDK
- Android v19.1.0
- iOS v7.59.0 (resolves #167)
Added Native Ad templates (resolves #164)

2020.04.30 [v8.0.051]

Updated Rewarded Video API to new version
Added Adaptive banners (resolves #152)

2020.03.23 [v7.0.031]

Android X migration (resolves #161)
Updated Admob SDK
- Android v18.3.0
- iOS v7.45.0 (pre Firebase sqlite changes)

2019.12.11 [v6.1.015]

Updated Admob SDK
- iOS v7.45.0 (pre Firebase sqlite changes)
- Android v17.1.2
Added Firebase v6.2.0 compatibility

2019.09.20 [v6.0.008]

iOS: Removed dependencies on frameworks that causes usage description errors (resolves #143)

2019.08.13 [v6.0.002]

Android 64bit update (resolves #137)
Updated minimum iOS version to 9.0

2019.03.12 [v5.5.177]

Embedded iOS bitcode

2019.02.26 [v5.5.176]

Updated minimum iOS version to 8.0

2018.12.12 [v5.4.175]

Android: Updated Google Play Services Ads to 17.1.2 (#112)

2018.11.27 [v5.4.173]

Updated to Google Play Services v16.0.5 (#105, #104, #72, #57)
Removed application keys

2018.11.01 [v5.3.171]

Added tagForUnderAgeOfConsent to AdRequest (resolves #90)
iOS: Resolved landscape smart banner full width issue (resolves #74)

2018.09.05 [v5.3.161]

Documentation update + small Android update

2018.08.08 [v5.3.159]

Added Animate example (#78)

2018.07.31 [v5.3.158]

Android: Added handling of crashes in some edge load cases (#76)

2018.07.14 [v5.3.157]

Updated loading calls to remedy ANRs (#72)

2018.07.06 [v5.3.147]

Removed available flags from Google iOS Consent SDK for windows packaging (resolves #71)

2018.06.25 [v5.3.131]

Added the Consent SDK (resolves #63)

2018.06.20 [v5.2.112]

Updated asdocs

2018.06.01 [v5.2.111]

Android: Updated to Google Play Services v15+

2018.05.18 [v5.2.109]

Updated documentation

2018.05.18 [v5.2.108]

iOS: Updated SDK to v7.31.0 (#57)
Added targeting options (resolves #61)
- child treatment (COPPA)
- non-personalised ads (GDPR)
- ad content
- keywords

2018.04.23 [v5.1.102]

Added Rewarded Video Ads (resolves #42)

2018.04.20 [v5.0.085]

Updated build and corrected isSupported check (resolves #58, #60)

2018.03.10 [v5.0.083]

Major update including complete refactor for future development
Android: Updated SDK to v11.8.0
iOS: Updated SDK to v7.28.0
- Added ability to get advert size (resolves #46)
- New method to retrieve advertising id
- Added advertising id tracking flag info (resolves #41)
- Added gender and birthday to requests (resolves #6)
- Better advert positioning (resolves #1)
- Resolved crash (resolves #44)

2017.10.26 [v4.0.019]

Corrected setTestDetails function definition (#50)

2017.07.10 [v4.0.011]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.03.15 [v4.0.010]

Removed iOS Simulator version to reduce file size
Android: Updated SDK to v10.2.0
iOS: Updated SDK to v3.14.0

2017.03.15 [v4.0.010]

Removed iOS Simulator version to reduce file size
Android: Updated SDK to v10.2.0
iOS: Updated SDK to v3.14.0

2017.01.06 [v4.0.003]

iAd Shutdown, updated SDKs, new documentation

2016.06.04

Android: Minor view parameter changes (#35)

2016.05.20

iOS: Resolved missing framework references (resolves #33, #25)

2016.05.03

Updated SDK versions (#25)

2016.03.10

2015.06.26

Android: Fix to prevent unusual crashes (resolves #21)

2015.04.23

Android: Resolved issue with AdMob test details (resolves #19)

2015.02.26

Android: Fixed banner positioning issue (resolves #15)

2015.02.24

Android: Fixed crash when initialising doubleClick (resolves #10)

2015.02.19

Added Interstitial Advert support for AdMob and iAd
Fixed Flash Builder 4.6 missing class issue
iOS: Updated Google Mobile Ads library to version 7.0.0
iOS: Fix for smart banner rendering in landscape mode when flat
iOS: Fix for iOS 8 dimension changes for position banner adverts
iOS: Fixed issue with arm64 compilation error undefined symbols (resolves #5) (notify #12)
Android: Separated Google Play Libraries into separate ANE

2015.01.31

iOS: Removed reference to the IDFA returned as the advertising identifier in the iAdOnly version to avoid review rejection (resolves #3)

2015.01.31

Added check for .debug suffix in application id

2014.12.17

iOS: Included arm64 support (resolves #2)
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.11.26

New application based key check, removing server checks

2014.10.20

iOS Update for iOS 8
- iOS: Split into two versions to satisfy Apple review for iAd (resolves #218)
- + \ No newline at end of file diff --git a/docs/adverts/consent/index.html b/docs/adverts/consent/index.html index 438e435e55f..ef40f0f77fc 100644 --- a/docs/adverts/consent/index.html +++ b/docs/adverts/consent/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Consent

caution

AdMob users must migrate to the User Messaging Platform to ensure you have access to the latest consent gathering tools. The consent sdk has been removed due to app rejections when it was included.

Huawei still utilises this consent SDK.

Under the EU User Consent Policy, you must make certain disclosures to your users in the European Economic Area (EEA) and obtain their consent to use cookies or other local storage, where legally required, and to use personal data (such as AdID) to serve ads. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR).

This consent SDK is to support publishers in meeting their duties under this policy. The Consent SDK is an open-source library that provides utility functions for collecting consent from your users.

This guide describes how to use the Consent SDK to obtain consent from users. It also describes how to forward consent to the ads SDK once you have obtained consent.

Availability

The consent sdk is only available for certain platforms. Once you have setup your platform you can check if the consent sdk is available by calling isSupported

if (Adverts.service.consent.isSupported)
{
// Consent sdk is available
}

Prior to using any other methods in the Consent SDK, you should update consent status to make sure the Consent SDK has the latest information regarding the ad technology providers you've selected in the AdMob UI. If the list of ad technology providers has changed since the user last provided consent, the consent state is set back to an unknown state.

To retrieve and update the consent status call the getConsentStatus function:

Adverts.service.consent.getConsentStatus( "publisher_id" );

The publisher id is taken from your AdMob account as shown in the AdMob Settings section.

This is an asynchronous process and will dispatch one of two possible events:

  • ConsentEvent.STATUS_UPDATED: Dispatched when the consent status has been updated
  • ConsentEvent.STATUS_ERROR: Dispatched when there was an error retrieving the consent status
Adverts.service.consent.addEventListener( ConsentEvent.STATUS_UPDATED, statusUpdatedHandler );
Adverts.service.consent.addEventListener( ConsentEvent.STATUS_ERROR, statusErrorHandler );

Adverts.service.consent.getConsentStatus( "publisher_id" );


function statusUpdatedHandler( event:ConsentEvent ):void
{
trace( "statusUpdatedHandler(): " + event.status
+ " inEea:" + event.inEeaOrUnknown );
}

private function statusErrorHandler( event:ConsentEvent ):void
{
trace( "statusErrorHandler(): " + event.error );
}

Huawei Ads Kit

Huawei's consent sdk will present a series of dialogs to request consent for your user.

You can control the content using the ConsentOptions.setDialogContent() functionality and passing an ConsentDialogContent instance:

var options:ConsentOptions = new ConsentOptions( "https://airnativeextensions.com/privacy" )
.setDialogContent(
new ConsentDialogContent()
.setContentText( "The Ads in this application are provided in collaboration with our advertising partners. To provide this service, we need to share certain information about you with these partners, including your location as well as your usage records for the news service.\n\n" +
"For more information about our partners and how your data is processed, please touch %MORE_INFO%.\n\n" +
"By touching AGREE, you indicate that you agree to share the above personal information with our partners so that they can provide you with personalized advertisements on behalf of their customers, based on interests and preferences identified or predicted through analysis of your personal information.\n\n" +
"You can withdraw your consent at any time by going to settings.\n\n" +
"If you touch SKIP, your data will not be shared with our partners and you will not receive personalized ads.")
.setTitle( "Test Title" )
.setMoreInfoText( "The Ads in HUAWEI X is provided in collaboration with our partners. You can find a full list of our partners for each country/region %MORE_INFO%.\n\n" +
" In order to provide you with personalized advertisements, we need to share the following information with our partners:\n\n" +
" •\tUser information, including advertising ID, city of residence, country, and language.\n\n" +
" •\tDevice information, including device name and model, operating system version, screen size, and network type.\n\n" +
" •\tService usage information, including news ID and records of views, clicks, dislikes, shares, and comments for news content and advertisements.\n\n" +
" With your consent, the above information will be shared with our partners so that they can provide you with personalized advertisements on behalf of their customers, based on interests and preferences identified or predicted through analysis of your personal information.\n\n" +
" You can withdraw your consent at any time by going to app settings.\n\n" +
" Without your consent, no data will be shared with our partners and you will not receive personalized ads." )
.setMediationPartnersText("You can find a full list of our partners for each country/region \n\n" )
);

Adverts.service.consent.askForConsent( options );

Once you have called askForConsent you will receive one of two events:

  • ConsentEvent.FORM_CLOSED: Dispatched when the user has selected their consent status and the form has been closed
    • event.status: Is a string containing one of the values defined in the ConsentStatus class.
  • ConsentEvent.FORM_ERROR: Dispatched when there was an error loading or displaying the form
    • event.error: Will be a description of the error that occurred.

See ConsentEvent for more information on the fields.

var options:ConsentOptions = new ConsentOptions( "https://www.your.com/privacyurl" )
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption();

Adverts.service.consent.addEventListener( ConsentEvent.FORM_CLOSED, formClosedHandler );
Adverts.service.consent.addEventListener( ConsentEvent.FORM_ERROR, formErrorHandler );

Adverts.service.consent.askForConsent( options );


function formClosedHandler( event:ConsentEvent ):void
{
trace( "formClosedHandler(): " + event.status
+ " inEea:" + event.inEeaOrUnknown
+ " adFree:" + event.userPrefersAdFree );
}

function formErrorHandler( event:ConsentEvent ):void
{
trace( "formErrorHandler(): " + event.error );
}

Huawei Ads Kit return values are slightly different, userPrefersAdFree will always be false and inEeaOrUnknown will be true if the user needs to consent and false otherwise. The consent status will have equivalent values though.

Remember to provide users with the option to change or revoke consent.

Testing

The Consent SDK has different behaviors depending on the location of the user. For example, the consent form fails to load if the user is not located in the EEA.

To enable easier testing of your app both inside and outside the EEA, the Consent SDK supports debug options that you can set prior to calling any other methods in the Consent SDK.

  1. Update the consent status by calling getConsentStatus() as described above.
I/ConsentInformation: Use ConsentInformation.getInstance(context).addTestDevice("33BE2250B43518CCDA7DE426D04EE231") to get test ads on this device.
  1. Whitelist your device to be a debug device using the advertising ID:
Adverts.service.consent.addTestDevice( "33BE2250B43518CCDA7DE426D04EE231" );
  1. Finally, call setDebugGeography to set your preferred geography for testing purposes.
Adverts.service.consent.setDebugGeography( DebugGeography.DEBUG_GEOGRAPHY_EEA );

After completing these steps, calls to update consent status will take into account your debug geography.

Once you have gathered consent you must set the appropriate information on an ad request. See the Targeting section for more information.

- + \ No newline at end of file diff --git a/docs/adverts/index.html b/docs/adverts/index.html index b5f02c43874..29a495f988d 100644 --- a/docs/adverts/index.html +++ b/docs/adverts/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Adverts

The Adverts extension gives you the ability to display adverts in your AIR application.

This extension allows you to monetise your application by displaying advertisements, including banners and interstitials.

Currently the extension supports the following advertising platforms:

  • Google AdMob: Android, iOS
  • Huawei Ads Kit: Android

iAd Shutdown

Please note the Apple iAd network has been shutdown and will no longer be supported. As of December 31, 2016, the iAd App Network is no longer available.

Any new versions will have the iAd support removed and will no longer be available through the ANE.

Features

  • Show/Hide adverts;
  • Identical cross-platform implementation;
  • Position and auto-alignment options;
  • AdMob on both iOS and Android;
  • Huawei Ads Kit on Huawei Android devices;
  • Support for:
    • Banners;
    • Interstitials;
    • Rewarded Video;
    • Native Ad Templates (AdMob only);
  • Consent through the User Messaging Platform;

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/adverts/initialise-platform/index.html b/docs/adverts/initialise-platform/index.html index dd9aea56675..b5a3a08c265 100644 --- a/docs/adverts/initialise-platform/index.html +++ b/docs/adverts/initialise-platform/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Initialise Platform

Setup the platform

You should perform this once in your application preferrably early well before any adverts will be displayed.

This is a two step process. You should initially call setup specifying you platform selection and then call initialise to initialise the platform.

Firstly select the platform:

Adverts.service.setup( AdvertPlatform.PLATFORM_ADMOB );

This simply specifies the platform the extension will use, so the correct implementation will be used for all other functionality. At this point you can use other functionality of the extension around consent and the user messaging platform, however adverts will not function.

Next call initialise():

Adverts.service.initialise();

This will initialise the actual platforms advertising SDK.

Warning: Ads may be preloaded by the underlying advertising SDK or mediation partner SDKs upon calling initialise(). If you need to obtain consent from users in the European Economic Area (EEA), set any request-specific flags (such as tagForChildDirectedTreatment or tag_for_under_age_of_consent), or otherwise take action before loading ads, ensure you do so before calling initialise().

This is the main reason there are two steps in the process to allow you to acquire consent before loading any ads.

The initialisation process is asynchronous and will take a short amount of time depending on the platform. An event is dispatched when this process is complete.

Adverts.service.addEventListener( AdvertsEvent.INITIALISED, initialisedHandler );

Adverts.service.initialise();

function initialisedHandler( event:AdvertsEvent ):void
{
// Platform is now initialised and ready to load ads
}

Open Bidding

If you are planning to use "Open Bidding Mediation" then you need to ensure you await the initialised event. Before an open bidding adapter can participate in an ad request, it must first be initialized. The initialise() method initializes open bidding adapters and dispatches the AdvertsEvent.INITIALISED event once all adapters complete initialisation (or after a 30 second timeout).

The initialised event will contain details of the available mediator adapters, including their state and latency:

Adverts.service.addEventListener( AdvertsEvent.INITIALISED, initialisedHandler );

Adverts.service.initialise();

function initialisedHandler( event:AdvertsEvent ):void
{
for each (var adapterStatus:AdapterStatus in e.adapterStatus)
{
trace( "adapter: " + adapterStatus.name + " : " + adapterStatus.state + " [" + adapterStatus.latency + "] - " + adapterStatus.description );
}
}

Checking Support

You can also check whether a platform is supported before initialising it to dynamically swap platforms, by using the isPlatformSupported function.

if (Adverts.service.isPlatformSupported( AdvertPlatform.PLATFORM_HUAWEI_ADS ))
{
Adverts.service.setup( AdvertPlatform.PLATFORM_HUAWEI_ADS );
}
else if (Adverts.service.isPlatformSupported( AdvertPlatform.PLATFORM_ADMOB ))
{
Adverts.service.setup( AdvertPlatform.PLATFORM_ADMOB );
}
else
{
trace( "No platform supported on the current device" );
}
- + \ No newline at end of file diff --git a/docs/adverts/interstitials/index.html b/docs/adverts/interstitials/index.html index 9268f7fd78e..e34f140dd77 100644 --- a/docs/adverts/interstitials/index.html +++ b/docs/adverts/interstitials/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ See the Initialise Platform section.

Support

The interstitials have their own isSupported flag as interstitials aren't available on all platform and services.

To check if interstitials are supported:

if (Adverts.service.interstitials.isSupported)
{
// Interstitials are supported
}

This allows you to create a fallback scenario if interstitials aren't supported on the current platform and device.

Creating an Interstitial

To create an InterstitialAd use the createInterstitialAd function:

var interstitial:InterstitialAd = Adverts.service.interstitials.createInterstitialAd();

This will instanciate an instance of the InterstitialAd class.

You must set the ad unit on this ad as soon as possible by using the setAdUnitId function:

interstitial.setAdUnitId( "interstitial_adUnitId" );

Without setting the ad unit id everything else regarding the interstitial will fail.

Loading

Interstitials should be preloaded in your application. This allows you to start the load at any time, and only display when your application is ready or when the advert has been loaded.

To load an advert you use the load function and pass it an AdRequest object which will specify the details of the ad request to load. You create an AdRequest by using the AdRequestBuilder. The builder is used to correctly create the request object and easily set the availble properties on the request.

The simplest example is to just use a generic request:

interstitial.load( new AdRequestBuilder().build() );

See Targeting for more on the AdRequestBuilder targetting options.

You can listen for events that will inform you on when an advert is available or if there were any errors in loading the advert. There are two events of interest here:

You can use the loaded event to delay displaying the ad until you are sure an ad is available.

interstitial.addEventListener( InterstitialAdEvent.LOADED, loadedHandler );
interstitial.addEventListener( InterstitialAdEvent.ERROR, errorHandler );


function loadedHandler( event:InterstitialAdEvent ):void
{
// interstitial loaded and ready to be displayed
}

function errorHandler( event:InterstitialAdEvent ):void
{
// Load error occurred. The errorCode will contain more information
trace( "Error" + event.errorCode );
}

If an error occurs you can use the errorCode on the event to determine what type of error occurred. See the troubleshooting guide to determine what happened.

Testing and Development

It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.

While in development you should either use the test ad unit ids available or specify your test device id in your request configuration. More information on this is located in the section on Test Ads

The following Ad Unit IDs can be used to test interstitial ads in your application:

Checking Loaded

You can check whether the advert is loaded by waiting for the InterstitialEvent.LOADED or checking the isLoaded() flag. It is useful to use the flag to confirm that the ad is loaded before attempting to display the ad:

if (interstitial.isLoaded())
{
// Show the ad
}

Display

When you are ready to display your advert you call show() as below.

interstitial.show();

When showing an advert you should save any content in your application as the advert may take the user out of your application if they follow the presented action. The InterstitialAdEvent.CLOSED event is dispatched when the user closes the advert and control returns to your application and you can then resume operation.

As noted above you should check if the advert is loaded before calling show:

if (interstitial.isLoaded())
{
interstitial.show();
}

Events

There are several events dispatched by the advert as the user interacts with it:

At the very least we suggest you should listen for the closed event to know when control returns to your application.

interstitial.addEventListener( FullScreenContentEvent.SHOW, showHandler );
interstitial.addEventListener( FullScreenContentEvent.FAILED_TO_SHOW, failedToShowHandler );
interstitial.addEventListener( FullScreenContentEvent.DISMISSED, dismissedHandler );

if (interstitial.isLoaded())
{
interstitial.show();
}


function showHandler( event:FullScreenContentEvent ):void
{
// The interstitial has been opened and is now visible to the user
}

function failedToShowHandler( event:FullScreenContentEvent ):void
{
// The ad failed to be shown
}

function dismissedHandler( event:FullScreenContentEvent ):void
{
// Control has returned to your application
// you should reactivate any paused / stopped parts of your application.
}

Refresh

Once you have displayed an interstitial a new ad needs to be loaded in order to display the interstitial again. This is a simple matter of starting a new ad request load:

interstitial.load( new AdRequestBuilder().build() );

The FullScreenContentEvent.DISMISSED event is generally a good place to trigger this load so that you ensure you always have a loaded ad available to display in your application, however you can handle this process as you see fit.

- + \ No newline at end of file diff --git a/docs/adverts/life-time-value/index.html b/docs/adverts/life-time-value/index.html index 857488e7bc0..b810defe59b 100644 --- a/docs/adverts/life-time-value/index.html +++ b/docs/adverts/life-time-value/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Life Time Value (LTV)

When an impression occurs, the extension calls the paid event handler with its associated revenue data. By implementing this event handler, you can use the data to calculate a user's life time value, or forward the data downstream to other relevant systems.

info

You must reach out to your account manager to get allowlisted for this feature.

This feature applies to:

  • Banner Ad
  • Interstitial Ad
  • Rewarded Video Ad
  • Rewarded Interstitial Ad

Each ad format dispatches a PaidEvent.PAID event. During the lifecycle of an ad event, the SDK monitors impression events and dispatches the event with an earned value.


var rewardedVideoAd : RewardedVideoAd = Adverts.service.rewardedVideoAds.createRewardedVideoAd();
rewardedVideoAd.setAdUnitId( "REWARDED_AD_UNIT_ID" );
rewardedVideoAd.load( new AdRequestBuilder().build() );


rewardedVideoAd.addEventListener( PaidEvent.PAID, paidHandler );

function paidHandler( event:PaidEvent ):void
{
// event.adValue will contain the paid event revenue information
trace( event.adValue.value + " ("+event.adValue.currencyCode+")" );
}

The event has a property adValue which is an instance of the AdValue class. It contains information about the amount, currency and precision of the revenue.

- + \ No newline at end of file diff --git a/docs/adverts/mediation/adcolony/index.html b/docs/adverts/mediation/adcolony/index.html index 5185b8334bf..af7639b7175 100644 --- a/docs/adverts/mediation/adcolony/index.html +++ b/docs/adverts/mediation/adcolony/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

AdColony

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from AdColony through Open Bidding or waterfall mediation. It covers how to add AdColony ads to an ad unit's mediation configuration, and how to integrate the AdColony SDK and adapter into an AIR app.

Step 1: Set up AdColony

Sign up or log in to your AdColony account. Add your app to the AdColony publisher dashboard by clicking the Setup New App button.

Continue following the guide on the AdMob site:

Step 2: Configure mediation settings for your AdMob ad unit

Step 3: Import the AdColony SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.AdColony

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.com.distriqt.admob.AdColony.ane # AdColony AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

No additional code required

Step 5: Test your implementation

To enable test ads on AdColony, go to your AdColony dashboard and navigate to Monetization > Apps. Select your Zone for which you would like to enable test ads under the Ad Zones section of your app. Test ads can be enabled by checking Yes to Show test ads only? under the Development section.

Optional steps

Under the Google EU User Consent Policy, you must ensure that certain disclosures are given to, and consents obtained from, users in the European Economic Area (EEA) regarding the use of device identifiers and personal data. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). When seeking consent, you must identify each ad network in your mediation chain that may collect, receive, or use personal data and provide information about each network's use. Google currently is unable to pass the user's consent choice to such networks automatically.

The section below shows you how to enable or disable personalized ads for AdColony.

The AdColony adapter provides the AdColony.instance.getAppOptions() method to customize parameters to be sent to AdColony's SDK. Two methods relevant to GDPR on these options are setPrivacyFrameworkRequired() and setPrivacyConsentString(), added in AdColony SDK 4.2.0. The following sample code demonstrates how to pass these parameters to the AdColony adapter, which are then used in AdColony’s initialization method. These options must be set before you initialize mobile ads to ensure they get forwarded properly to AdColony's SDK:

AdColony.instance.getAppOptions()
.setPrivacyFrameworkRequired( AdColonyAppOptions.GDPR, true )
.setPrivacyConsentString( AdColonyAppOptions.GDPR, "1" );

See AdColony’s GDPR implementation details for more information about what values may be provided in these methods.

Permissions

For optimal performance, AdColony recommends adding the following optional permissions to your app's manifest additions:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />

Further information

See the Google AdColony Mediation guide:

https://developers.google.com/admob/android/mediation/adcolony

- + \ No newline at end of file diff --git a/docs/adverts/mediation/applovin/index.html b/docs/adverts/mediation/applovin/index.html index 5cc11a7af11..59ea016d038 100644 --- a/docs/adverts/mediation/applovin/index.html +++ b/docs/adverts/mediation/applovin/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

AppLovin

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from AppLovin Ads via mediation. It covers how to add AppLovin to an ad unit's mediation configuration , how to set up Ad Network Optimization (ANO), and how to integrate the AppLovin SDK and adapter into an Android app.

Step 1: Set up AppLovin

Sign up or log in to your AppLovin account.

To set up your AdMob ad unit, you'll need your AppLovin SDK Key and Report Key. To find them, go to the AppLovin Dashboard and click on the Account tab. In the dropdown list under Account, select Keys to see both values.Sign up or log in to your AppLovin account.

To set up your AdMob ad unit, you'll need your AppLovin SDK Key and Report Key. To find them, go to the AppLovin Dashboard and click on the Account tab. In the dropdown list under Account, select Keys to see both values.

Select app for mediation

On the AppLovin dashboard, select Manage Apps under the Monetize section to get to your registered apps. Select the app you'd like to use with mediation from the list of available apps. If you do not see your app in the list, it is not registered. See the note below to get it registered

Register AppLovin Application

Before you can complete the AdMob mediation setup, your app needs to be registered by AppLovin. Once your app initializes the AppLovin SDK, AppLovin automatically detects and registers it. To complete this process:

  1. Follow the steps in the Import the AppLovin SDK and adapter section below. Once that's done, you will have the AppLovin SDK integrated in your app.

  2. Add the Initialize the AppLovin SDK by calling AdMobAppLovin.service.initializeSdk(); in your application.

Build and run your app, then wait thirty minutes or so. Afterwards, check the AppLovin dashboard under Monetize > Manage Apps to find your app.

Once the registration process is complete, you can remove the initializeSdk call.

Create Zone

On the AppLovin dashboard, select Zones under the Monetize section to get to your registered Zone IDs. If you have already created the required Zones for your app, skip ahead to Step2. To create a new Zone ID, click on Create Zone.

Enter the name of Zone ID, select Android as the Platform, and choose the desired Ad Type.

Configure Pricing for the Zone by selecting either Flat CPM or Optimized by AppLovin. CPMs can be configured on a per country basis for the Flat CPM option. Then, click Save.

Once the Zone is created, the Zone ID can be found under the Zone ID column.

Note: We highly recommend that you create an AppLovin Zone corresponding to each AdMob ad unit so that AdMob can more effectively Optimize ad sources in mediation. See AppLovin's best practices to assist you in configuring Zones optimally. In the meantime, you can continue without creating a Zone.

Step 2: Configure mediation settings for your AdMob ad unit

https://developers.google.com/admob/android/mediation/applovin#step_2_configure_mediation_settings_for_your_ad_unit

Step 3: Import the AppLovin SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.AppLovin

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.admob.AppLovin.ane # AppLovin AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You must set the Android and iOS AppLovin SDK keys you setup in the console. This will allow apm to automatically insert them into the correct position in your application descriptor. Call the following to step through the configuration values for this extension:
apm project config set com.distriqt.admob.AppLovin

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

No additional code required.

Step 5: Test your implementation

AppLovin recommends that test ads should be used during development if you cannot get live ads.

To enable test ads, go to the Manage Apps page by clicking on your app's name in the AppLovin dashboard and navigate to the Test Mode section. Toggle the Test Mode switch to ON.

Test Mode may take up to 30 mins to take effect. It will also automatically reset to OFF after two hours.

Forcing Mediation Network

The easiest way we have found to force a mediation network during testing is to disable automatic optimisations and set the eCPM manually.

Doing this you can give the mediation network you are wanting to test a high eCPM value ( eg $1000) and all others (including AdMob) a very low eCPM (eg $0.01).

Optional steps

Under the Google EU User Consent Policy, you must ensure that certain disclosures are given to, and consents obtained from, users in the European Economic Area (EEA) regarding the use of device identifiers and personal data. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). When seeking consent, you must identify each ad network in your mediation chain that may collect, receive, or use personal data and provide information about each network's use. Google currently is unable to pass the user's consent choice to such networks automatically.

The section below shows you how to enable or disable personalized ads for AppLovin.

In SDK version 8.0.1, AppLovin added the setHasUserContent and setIsAgeRestrictedUser methods. The following sample code shows how to pass consent information to the AppLovin SDK. It is recommended that you call these methods prior to requesting ads via the Google Mobile Ads SDK.

AdMobAppLovin.service.setHasUserConsent( true );

Additionally, if the user is known to be in an age-restricted category, you can also set the below flag to true.

AdMobAppLovin.service.setIsAgeRestrictedUser( true );

Further information

See the Google AppLovin Mediation guide:

https://developers.google.com/admob/android/mediation/applovin

- + \ No newline at end of file diff --git a/docs/adverts/mediation/changelog/index.html b/docs/adverts/mediation/changelog/index.html index d47442b2db4..9d1487aef49 100644 --- a/docs/adverts/mediation/changelog/index.html +++ b/docs/adverts/mediation/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.08.22 [v6.8.1]
fix(unity): correct airpackage dependencies - missing androidx.webkit (resolves #61)
2023.08.18 [v6.8.0]
Compatible with Adverts v14.3.0 

feat(adcolony): update adcolony sdk: android v4.8.0.2
feat(applovin): update applovin sdk: android v11.11.1.0
feat(facebook): update audience sdk: android v6.15.0
feat(ironsource): update ironsource sdk: android v7.4.0
feat(pangle): update pangle sdk: android v5.3.0.6
feat(tapjoy): update tapjoy sdk: android v13.1.2
feat(unityads): update unityads sdk: android v4.8.0
2023.06.02 [v6.7.0]
feat(android): update to support AIR background thread implementation
2023.02.24 [v6.6.2]
fix(pangle): corrected ios implementation missing dependency (resolves #56)
2023.02.24 [v6.6.1]
fix(pangle): corrected ios implementation missing dependency (resolves #56)
2023.02.17 [v6.6.1]
feat(ios): strip bitcode from dynamic frameworks that haven't been updated yet (resolves #58) 
2023.01.12 [v6.6.0]
feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(adverts): update to support Adverts v13.8.0

feat(adcolony): update sdk: android v4.8.0 ios v4.9.0
feat(applovin): update sdk: android v11.6.1 ios v11.6.1
feat(facebook): update sdk: android v6.12.0 ios v6.12.0
feat(ironsource): update sdk: android v7.2.6 ios v7.2.6
feat(pangle): update sdk: android v4.9.0.7 ios v5.0.0.3
feat(tapjoy): update sdk: android v12.11.1 ios v12.11.1
feat(unityads): update sdk: android v4.5.0 ios v4.3.0
2022.11.05 [v6.5.0]
feat(pangle): add pangle mediation network (resolves #44)
feat(docs): update pangle docs
fix(adcolony): correct dependencies of airpackage and update docs
2022.07.20 [v6.4.2]
fix(build): build with AIR 33.1.1.856 due to issue with SWC generation in 889
feat(assets): restructure assets and frameworks to include ios simulator
2022.07.08 [v6.4.1]
fix(all): correct package assets such as audience_network.dex (resolves #46)
2022.06.24 [v6.4.0]
feat(update): update compatibility with latest Adverts extension
feat(unityads): update unityads sdk: android v4.2.1, ios v4.1.0
feat(tapjoy): update tapjoy sdk: android v12.10.0, ios v12.9.1
feat(ironsource): update ironsource sdk: android v7.2.2, ios v7.2.1.2
feat(facebookaudience): update fb audience sdk: android v6.11.0, ios v6.9.0.1
feat(applovin): update applovin sdk: android v11.4.3, ios v11.3.2
feat(adcolony): update adcolony sdk: android v4.8.0, ios v4.8.0
2022.03.25 [v6.3.1]
Correct missing dynamic frameworks for Facebook Audience mediation (resolves #39)
2022.03.08 [v6.3.0]
Update mediation adapters for compatibility with Adverts v13.5.0
2021.12.07 [v6.2.3]
Update air package documentation and config descriptions
2021.11.19 [v6.2.2]
Correct issue with unity ads mediator missing adaptor aar (resolves #35)
2021.09.08 [v6.2.1]
Updated docs
2021.09.08 [v6.2.1]
Updated Facebook Audience to v6.6.0
2021.08.31 [v6.2.0]
AdColony: Added airpackage, Updated SDK android v4.5.0 ios v4.7.0
AppLovin: Added airpackage, Updated SDK android v10.3.2 ios v10.3.4
Facebook: Added airpackage, Updated SDK android v6.5.1 ios v6.5.1
IronSource: Added airpackage, Updated SDK android v7.1.8 ios v7.1.8
TapJoy: Added airpackage, Updated SDK android v12.8.1 ios v12.8.1
UnityAds: Added airpackage, Updated SDK android v3.7.5 ios v3.7.5
2021.06.23 [v6.1.0]
Facebook Audience Android update v6.5.0 (#31)
IronSource Android update v7.1.6 (#30, #29)
2021.05.24 [v6.0.0]
Updated to latest AdMob mediation adapters to bring inline with v13 of the Adverts extension
2021.04.08 [v5.4.0]
Added AdColony mediation extension
2021.04.07 [v5.3.1]
Corrected issue in tap joy platform definition (resolves #27)
Reduced number of linker options and removed iOS minimum version
2021.03.07 [v5.3.0]
Added TapJoy mediation (resolves #26)
2021.02.08 [v5.2.0]
Updated to support latest Admob mediation adapters (resolves #25)
2021.03.07 [v5.3.0]
Added TapJoy mediation (resolves #26)
2021.02.08 [v5.2.0]
Updated to support latest Admob mediation adapters (resolves #25)
2020.11.25 [v5.1.0]
Updated to support latest Adverts release
AppLovin update (resolves #20, resolves #21)
- Android v9.14.6
- iOS v6.14.8
Deprecated wiki
2020.11.04 [v5.0.1]
Corrected audience_network.dex file for Facebook Audience mediator (resolves #218)
2020.10.14 [v5.0.0]
Correcting docs
2020.10.14 [v5.0.0]
Updated to support latest Adverts release
AppLovin update (resolves #18)
- Android v9.13.4
- iOS v6.14.4
Facebook Audience update (resolves #15)
- Android v6.1.0
- iOS v6.0.0
ironSource update
- Android v7.0.2
- iOS v7.0.2
UnityAds update
- Android v3.4.8
- iOS v3.4.8
2020.06.11 [v4.2.0]
Updated to support latest Adverts release
IronSource v6.16.0 mediation adapter integration (resolves #10)
Facebook Audience update
- iOS v5.9.0
- Android v5.9.0
2020.04.09 [v4.1.0]
AppLovin update
- Android v9.11.2
- iOS v6.12.0 (resolves #9)
Minor update to versioning (nativeVersion now correctly reports the mediator sdk version)
2020.03.23 [v4.0.0]
Android X migration (resolves #7)
Facebook Audience Mediator release
- Android v5.7.1
- iOS v5.4.0
AppLovin update
- Android v9.11.2

2019.08.13 [v3.0.005]
Updated minimum iOS version to 9.0
2019.07.04 [v3.0.003]
Android 64bit support (resolves #5)
2018.09.07 [v2.2.065]
Release version + Updated documentation
2018.09.05 [v2.2.064]
Android AdMob AppLovin mediation adapter beta
- + \ No newline at end of file diff --git a/docs/adverts/mediation/facebookaudience/index.html b/docs/adverts/mediation/facebookaudience/index.html index 4cb6063ba54..093744c1c92 100644 --- a/docs/adverts/mediation/facebookaudience/index.html +++ b/docs/adverts/mediation/facebookaudience/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Facebook Audience

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Facebook Audience Network via mediation.

Step 1: Set up Facebook Audience Network

The Google documentation contains a very detailed guide as to the process to setup your properties and Facebook account to display adverts.

Make sure you follow this guide closely.

Step 2: Configure mediation settings for your AdMob ad unit

You need to add Facebook to the mediation configuration for your ad unit.

Step 3: Import the Facebook Audience Network SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.FacebookAudience

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ assets
| |____ android
| | |____ audience_network.dex
| |____ ios
| | |____ Frameworks
| | | |____ [dynamic frameworks]
|____ ane
| |____ com.distriqt.admob.FacebookAudience.ane # Facebook Audience AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

  • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/android folder to the root of your Android application package and the assets/ios folder to the root of your iOS application package. (The android folder contains the audience_network.dex file that is required on Android and the ios folder contains a Frameworks folder with the required iOS dynamic frameworks).

info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

There is no additional code required.

Step 5: Test your implementation

When testing always make sure you are adding your test device id to the request to ensuring AdMob do not block your account for policy violations:

new AdRequestBuilder()
.addTestDevice( "XXXXXXXXXXXXXXXXXX" )
.build()

See the Adverts docs for more details.

Facebook Testing

You will need to enable testing in your Facebook account, by adding your test device and enabling an test advert type to serve the device.

See the Testing Audience Network Implementation guide for detailed instructions on how to enable Facebook test ads.

Forcing Mediation Network

The easiest way we have found to force a mediation network during testing is to disable automatic optimisations and set the eCPM manually.

Doing this you can give the mediation network you are wanting to test a high eCPM value ( eg $1000) and all others (including AdMob) a very low eCPM (eg $0.01).

- + \ No newline at end of file diff --git a/docs/adverts/mediation/index.html b/docs/adverts/mediation/index.html index bc88dce3a51..f409b294a3f 100644 --- a/docs/adverts/mediation/index.html +++ b/docs/adverts/mediation/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Adverts Mediation

These extensions allow you to add mediation networks with advertising platforms using the Adverts ANE.

Mediation is a feature that lets you serve ads to your apps from multiple sources, including the AdMob Network, third-party ad networks, and AdMob campaigns. AdMob Mediation helps maximize your fill rate and increase your monetization by sending ad requests to multiple networks to ensure you find the best available network to serve ads.

This guide is your one-stop shop for integrating mediation into your AdMob app.

They are designed to work with the distriqt Adverts ANE however should work with any recent AdMob implementation.

Features:

Documentation

Latest documentation can be found in the documentation site

- + \ No newline at end of file diff --git a/docs/adverts/mediation/ironsource/index.html b/docs/adverts/mediation/ironsource/index.html index b862f6bba19..f024207dfc4 100644 --- a/docs/adverts/mediation/ironsource/index.html +++ b/docs/adverts/mediation/ironsource/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

IronSource

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from ironSource through mediation.

Step 1: Set up ironSource

The Google documentation contains a very detailed guide as to the process to setup your properties and IronSource account to display adverts:

Make sure you follow this guide closely.

Step 2: Configure mediation settings for your AdMob ad unit

You need to add ironSource to the mediation configuration for your ad unit:

Step 3: Import the ironSource SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.IronSource

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.admob.IronSource.ane # IronSource AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

You should call AdMobIronSource.instance.init(); in your code before you intend to display ads. This ensures the internal sdk is initialised correctly.

Step 5: Test your implementation

You should run the IronSource validateIntegration() function to ensure the extension and manifest additions have been added correctly.

AdMobIronSource.instance.validateIntegration();

This will output information to the native device log.

You can then follow the Google guides to add a test device to receive test ads:

Optional Steps

Under the Google EU User Consent Policy, you must ensure that certain disclosures are given to, and consents obtained from, users in the European Economic Area (EEA) regarding the use of device identifiers and personal data. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). When seeking consent, you must identify each ad network in your mediation chain that may collect, receive, or use personal data and provide information about each network's use. Google currently is unable to pass the user's consent choice to such networks automatically.

The code below shows you how to enable or disable personalized ads for ironSource.

AdMobIronSource.instance.setConsent( true );

If you choose to call this method, it is recommended that you do so prior to requesting ads via the Adverts extension.

- + \ No newline at end of file diff --git a/docs/adverts/mediation/pangle/index.html b/docs/adverts/mediation/pangle/index.html index a651fe49461..2e28b76f726 100644 --- a/docs/adverts/mediation/pangle/index.html +++ b/docs/adverts/mediation/pangle/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Pangle

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Pangle Ads via mediation.

Step 1: Set up Pangle

The Google documentation contains a very detailed guide as to the process to setup your properties and Pangle account to display adverts.

Make sure you follow this guide closely.

Step 2: Configure mediation settings for your AdMob ad unit

You need to add Pangle to the mediation configuration for your ad unit.

Step 3: Import the Pangle SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.Pangle

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ assets
| |____ android # Android assets
|____ ane
| |____ com.distriqt.admob.Pangle.ane # Pangle AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

  • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/android folder to the root of your Android application package. (The android folder contains the a series of files that are required on Android for the Pangle related SDKs).

info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

There is no additional code required.

- + \ No newline at end of file diff --git a/docs/adverts/mediation/tapjoy/index.html b/docs/adverts/mediation/tapjoy/index.html index b6aa706f330..395d2b4d722 100644 --- a/docs/adverts/mediation/tapjoy/index.html +++ b/docs/adverts/mediation/tapjoy/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Tapjoy

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Tapjoy through mediation.

Step 1: Set up Tapjoy

The Google documentation contains a very detailed guide as to the process to setup your properties and Tapjoy account to display adverts:

Make sure you follow this guide closely.

Step 2: Configure mediation settings for your AdMob ad unit

You need to add Tapjoy to the mediation configuration for your ad unit:

Step 3: Import the Tapjoy SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.TapJoy

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.admob.TapJoy.ane # TapJoy AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

No additional code required.

Optional Steps

Under the Google EU User Consent Policy, you must ensure that certain disclosures are given to, and consents obtained from, users in the European Economic Area (EEA) regarding the use of device identifiers and personal data. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). When seeking consent, you must identify each ad network in your mediation chain that may collect, receive, or use personal data and provide information about each network's use. Google currently is unable to pass the user's consent choice to such networks automatically.

The code below shows you how to enable or disable personalized ads for TapJoy.

TapJoy.instance.setUserConsent( true );

If you choose to call this method, it is recommended that you do so prior to requesting ads via the Adverts extension.

- + \ No newline at end of file diff --git a/docs/adverts/mediation/unityads/index.html b/docs/adverts/mediation/unityads/index.html index cca9fe0ad00..9f66d30132c 100644 --- a/docs/adverts/mediation/unityads/index.html +++ b/docs/adverts/mediation/unityads/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

UnityAds

This guide is intended for publishers who want to use the Google Mobile Ads SDK to load and display ads from Unity Ads via mediation.

Step 1: Set up Unity ads

The Google documentation contains a very detailed guide as to the process to setup your properties and Unity Ads account to display adverts.

Make sure you follow this guide closely.

https://developers.google.com/admob/android/mediation/unity#step_1_set_up_unity_ads

Step 2: Configure mediation settings for your AdMob ad unit

You need to add Unity Ads to the mediation configuration for your ad unit.

Step 3: Import the Unity Ads SDK and adapter ANE

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.admob.UnityAds

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.admob.UnityAds.ane # UnityAds AdMob mediation extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Step 4: Additional code required

There is no additional code required.

Step 5: Test your implementation

When testing always make sure you are adding your test device id to the request to ensuring AdMob do not block your account for policy violations:

new AdRequestBuilder()
.addTestDevice( "XXXXXXXXXXXXXXXXXX" )
.build()

See the Adverts docs for more details.

Optional Steps

Under the Google EU User Consent Policy, you must ensure that certain disclosures are given to, and consents obtained from, users in the European Economic Area (EEA) regarding the use of device identifiers and personal data. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). When seeking consent, you must identify each ad network in your mediation chain that may collect, receive, or use personal data and provide information about each network's use. Google currently is unable to pass the user's consent choice to such networks automatically.

Follow the instructions below to enable or disable personalized ads for Unity Ads.

Unity Ads provides a GDPR Compliance guide that describes both automatic and manual solutions for user consent.

The following sample code shows how to pass consent information to the Unity Ads SDK manually. Should you choose to pass consent information to the Unity Ads SDK manually, it is recommended that this code is called prior to requesting ads via the Google Mobile Ads SDK.

AdMobUnityAds.instance.setConsent(true);
- + \ No newline at end of file diff --git a/docs/adverts/migrating-from-version-4/index.html b/docs/adverts/migrating-from-version-4/index.html index 7fdde1547b5..a14057f1dc9 100644 --- a/docs/adverts/migrating-from-version-4/index.html +++ b/docs/adverts/migrating-from-version-4/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Migrating from version 4

Version 5 completely changes the way adverts are displayed, including more control over the ad units that are displayed. Migration is simple as laid out below.

The major difference is that you now will create an AdView or an InterstitialAd instance and use this to configure, load and display your adverts. Whereas you used to only have access to a single advert with one ad unit id, you can now create multiple and use as required. This means that you will need to hold onto an instance of your AdView or InterstitialAd to set properties, listen for events, load, and display your advert.

Banners

Initialise

With v5.0 you specify the unit id on the advert view. So you no longer have to set the unit id on the initialisePlatform functions.

This means the follow version 4 code,

Adverts.service.initialisePlatform( AdvertPlatform.PLATFORM_ADMOB, AD_UNIT_ID );

becomes:

Adverts.service.initialisePlatform( AdvertPlatform.PLATFORM_ADMOB );

var adView:AdView = Adverts.service.createAdView();
adView.setAdSize( AdSize.SMART_BANNER );
adView.setAdUnitId( AD_UNIT_ID );

Note: You must set an AdSize and a unit id on an AdView before attempting to load or display the ad.

Displaying an Banner Advert

Previously to display an advert:

var position:AdvertPosition = new AdvertPosition();
position.verticalAlign = AdvertPosition.ALIGN_BOTTOM;
position.horizontalAlign = AdvertPosition.ALIGN_CENTER;

Adverts.service.showAdvert( position );

This now becomes:

var adView:AdView = Adverts.service.createAdView();
adView.setAdUnitId( AD_UNIT_ID );
adView.setAdSize( AdSize.SMART_BANNER );
adView.setViewParams( new AdViewParamsBuilder()
.setVerticalAlign( AdViewParams.ALIGN_BOTTOM )
.setHorizontalAlign( AdViewParams.ALIGN_CENTER )
.build()
);
adView.load( new AdRequestBuilder().build() );
adView.show();

There is a bit more to the code now, however we believe this gives you much more functionality to control the way adverts are displayed in your application.

Events

Listening for events is much more specified now. The following:

Adverts.service.addEventListener( AdvertEvent.RECEIVED_AD, adverts_receivedAdHandler );
private function adverts_receivedAdHandler( event:AdvertEvent ):void
{
trace( "received an advertisement" );
}

becomes:

adView.addEventListener( AdViewEvent.LOADED, loadedHandler );

function loadedHandler( event:AdViewEvent ):void
{
// Ad loaded and ready to be displayed
}

You can listen for many more events on the AdView now as well.

Hiding an Advert

Hiding an advert is a simple change, the following:

Adverts.service.hideAdvert();

becomes:

adView.hide();

Refreshing/Updating an advert

If you wish to manually refresh the advert you can call the refresh function. This will make the advert update with a new ad request.

Adverts.service.refresh();

This now changes to a new load request:

adView.load( new AdRequestBuilder().build() );

Interstitials

Interstitials are still provided through the Adverts.service.interstitials singleton, however the process is now similar to the AdView process above.

Loading

Previously to load an interstitial you called load on the Interstitials class, however now you need to create an instance of an InterstitialAd and then call load on that instance.

So

Adverts.service.interstitials.addEventListener( InterstitialEvent.LOADED, loadedHandler );
Adverts.service.interstitials.addEventListener( InterstitialEvent.ERROR, errorHandler );

Adverts.service.interstitials.load( AD_UNIT_ID );

becomes:

var interstitial:InterstitialAd = Adverts.service.interstitials.createInterstitialAd();

interstitial.setAdUnitId( AD_UNIT_ID );
interstitial.addEventListener( InterstitialAdEvent.LOADED, loadedHandler );
interstitial.addEventListener( InterstitialAdEvent.ERROR, errorHandler );
interstitial.load( new AdRequestBuilder().build() );

The interstitial instance should be held onto and reused in your application.

Displaying an Interstitial

Previously to display an interstitial:

Adverts.service.interstitials.addEventListener( InterstitialEvent.DISMISSED, dismissedHandler );

if (Adverts.service.interstitials.isReady())
{
Adverts.service.interstitials.show();
}

This now becomes:

interstitial.addEventListener( InterstitialAdEvent.CLOSED, closedHandler );

if (interstitial.isLoaded())
{
interstitial.show();
}

Advertising Identifier

The uniqueId function has been deprecated. If you need access to the device unique id (vendorForIdentifier etc) please use the com.distriqt.Application ANE.

This will now only return the advertisting identifier, however we have improved its functionality to retrieve more information about the advertising identifier.

Previously:

var advertisingId:String = Adverts.service.uniqueId( Adverts.ADVERTISING );

Becomes:

Adverts.service.addEventListener( AdvertisingIdEvent.ADVERTISING_ID, advertisingIdHandler );
Adverts.service.getAdvertisingId();

function advertisingIdHandler( event:AdvertisingIdEvent ):void
{
var advertisingId:String = info.advertisingId;
}

The asynchronous nature of the new implementation resolves issues with the previous implementation sometimes returning incorrect values.

- + \ No newline at end of file diff --git a/docs/adverts/migrating-to-androidx/index.html b/docs/adverts/migrating-to-androidx/index.html index dbc977b546e..a041b0e378f 100644 --- a/docs/adverts/migrating-to-androidx/index.html +++ b/docs/adverts/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/adverts/migrating-to-version-10/index.html b/docs/adverts/migrating-to-version-10/index.html index bc7980fa2fe..ae1db0fec93 100644 --- a/docs/adverts/migrating-to-version-10/index.html +++ b/docs/adverts/migrating-to-version-10/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to version 10

Version 10 brings the latest consent gathering processes from Google utilising the User Messaging Platform and preparations for iOS 14's App Tracking Transparency framework requirement.

Android Manifest

Ensure you have the latest manifest additions:

<manifest android:installLocation="auto">

<!--Required. Used to access the Internet to make ad requests-->
<uses-permission android:name="android.permission.INTERNET"/>

<!--Optional. Used to check if an internet connection is available prior to making an ad request.-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
android:hardwareAccelerated="true"
android:appComponentFactory="androidx.core.app.CoreComponentFactory">

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>

<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-AAAAAAAAAAAAAAAA~XXXXXXXXXX"/>

<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:exported="false"
android:theme="@android:style/Theme.Translucent" />

<provider
android:name="com.google.android.gms.ads.MobileAdsInitProvider"
android:authorities="air.com.distriqt.test.debug.mobileadsinitprovider"
android:exported="false"
android:initOrder="100" />

<service
android:name="com.google.android.gms.ads.AdService"
android:enabled="true"
android:exported="false" />

</application>

</manifest>

See Add the Extension for details.

iOS Info Additions

Updates are required to support iOS 14, you need to make sure you have the following in your Info Addtions:

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-AAAAAAAAAAAAAAAA~XXXXXXXXXX</string>

<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>

<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>

See Add the Extension for details.

Initialisation

You may notice that the initialisePlatform() function has been deprecated. This is to ensure that you are aware that there is now a two step process involved:

The legacy call to :

Adverts.service.initialisePlatform( AdvertPlatform.PLATFORM_ADMOB );

Is now the equivalent of :

Adverts.service.setup( AdvertPlatform.PLATFORM_ADMOB );
Adverts.service.initialise();

This separation has been made so you can access the consent functionality before initialising the platform. setup() must be called to setup the platform and make consent functionality available. Once initialise is called the SDK may make calls to preload ads so be sure to request any consent you require before calling initialise().

To migrate you need to change any usages of the existing consent SDK to the new User Messaging Platform.

Any calls to Adverts.service.consent.* functionality need to be replaced with the new Adverts.service.ump.* functionality. See the documentation on the User Messaging Platform for details.

- + \ No newline at end of file diff --git a/docs/adverts/migrating-to-version-12/index.html b/docs/adverts/migrating-to-version-12/index.html index 6ef96a3d793..f6b1e2b9eed 100644 --- a/docs/adverts/migrating-to-version-12/index.html +++ b/docs/adverts/migrating-to-version-12/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to version 12

Version 12 brings the latest AdMob SDK which includes some significant changes to the Android SDK.

Android Manifest

Add the following 2 additional androidx dependencies:

Ensure you have the included the additional manifest additions for the androidx room and work libraries (inside the application node of your additions).

You should replace APPLICATION_PACKAGE with your AIR application package name on Android (eg air.com.distriqt.test). Note that it may be prefixed by air..

<!-- AndroidX Room -->
<service
android:name="androidx.room.MultiInstanceInvalidationService"
android:exported="false" />


<!-- AndroidX Work -->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="APPLICATION_PACKAGE.workmanager-init"
android:directBootAware="false"
android:exported="false"
android:multiprocess="true" />

<service
android:name="androidx.work.impl.background.systemalarm.SystemAlarmService"
android:directBootAware="false"
android:enabled="@bool/enable_system_alarm_service_default"
android:exported="false" />
<service
android:name="androidx.work.impl.background.systemjob.SystemJobService"
android:directBootAware="false"
android:enabled="@bool/enable_system_job_service_default"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />

<receiver
android:name="androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"
android:directBootAware="false"
android:enabled="true"
android:exported="false" />
<receiver
android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy"
android:directBootAware="false"
android:enabled="false"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<receiver
android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy"
android:directBootAware="false"
android:enabled="false"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BATTERY_OKAY" />
<action android:name="android.intent.action.BATTERY_LOW" />
</intent-filter>
</receiver>
<receiver
android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy"
android:directBootAware="false"
android:enabled="false"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
<action android:name="android.intent.action.DEVICE_STORAGE_OK" />
</intent-filter>
</receiver>
<receiver
android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy"
android:directBootAware="false"
android:enabled="false"
android:exported="false" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<receiver
android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver"
android:directBootAware="false"
android:enabled="false"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
<receiver
android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
android:directBootAware="false"
android:enabled="@bool/enable_system_alarm_service_default"
android:exported="false" >
<intent-filter>
<action android:name="androidx.work.impl.background.systemalarm.UpdateProxies" />
</intent-filter>
</receiver>

See Add the Extension for details.

- + \ No newline at end of file diff --git a/docs/adverts/migrating-to-version-13.6/index.html b/docs/adverts/migrating-to-version-13.6/index.html index d628a580317..0c08c41785d 100644 --- a/docs/adverts/migrating-to-version-13.6/index.html +++ b/docs/adverts/migrating-to-version-13.6/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to version 13.6

Version 13.6 brings version 9+ of the AdMob iOS SDK which includes some significant changes to the SDK. Most of the changes have been handled internal to the extension however there is one important piece of information that you must be aware of:

Ads stop serving on iOS 10

The minimum iOS version the Google Mobile Ads SDK version 9.0.0 supports is iOS 11.

Upgrading to Google Mobile Ads SDK version 9.0.0 will not break your app on iOS 10 devices, however, no ads will be served on those devices.

Life Time Value (LTV)

This update also includes the preview implementation of the life time value events.

Most of the adverts will now dispatch a PaidEvent.PAID event with information on the revenue obtained for presenting an advert. By implementing this event handler, you can use the data to calculate a user's life time value, or forward the data downstream to other relevant systems.

More information in the Life Time Value section.

- + \ No newline at end of file diff --git a/docs/adverts/migrating-to-version-13/index.html b/docs/adverts/migrating-to-version-13/index.html index 64bf3a7369e..33a896c0908 100644 --- a/docs/adverts/migrating-to-version-13/index.html +++ b/docs/adverts/migrating-to-version-13/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to version 13

Version 13 brings the latest AdMob SDK which includes some significant changes to the SDK. This update includes:

  • Android v20+
  • iOS v8+

App Open Ads

App Open Ads have been added with this release

Event Changes

Left Application Events

All LEFT_APPLICATION events have been removed and are no longer dispatched. This includes:

  • RewardedVideoAdEvent.LEFT_APPLICATION
  • InterstitialAdEvent.LEFT_APPLICATION
  • AdViewEvent.LEFT_APPLICATION

We suggest using the Application extension state events to handle background deactivate events instead.

FullScreenContentEvent

All the fullscreen ads (Interstitials, RewardedVideoAd, AppOpenAds) now dispatch FullScreenContentEvents when:

  • they are shown: FullScreenContentEvent.SHOW
  • they fail to show: FullScreenContentEvent.FAILED_TO_SHOW
  • they are dismissed: FullScreenContentEvent.DISMISSED

These events replace the equivalent events that were defined in the InterstitialAdEvent, and RewardedVideoAdEvent.

So you need to replace the following with their new equivalents:

  • InterstitialAdEvent.OPENED -> FullScreenContentEvent.SHOW
  • InterstitialAdEvent.CLOSED -> FullScreenContentEvent.DISMISSED
  • RewardedVideoAdEvent.OPENED -> FullScreenContentEvent.SHOW
  • RewardedVideoAdEvent.CLOSED -> FullScreenContentEvent.DISMISSED

eg for an interstitial, the following code:

var interstitial:InterstitialAd = Adverts.service.interstitials.createInterstitialAd();
interstitial.setAdUnitId( "AD_UNIT_ID" );

interstitial.addEventListener( InterstitialAdEvent.LOADED, interstitial_loadedHandler );
interstitial.addEventListener( InterstitialAdEvent.ERROR, interstitial_errorHandler );
interstitial.addEventListener( InterstitialAdEvent.OPENED, interstitial_openedHandler );
interstitial.addEventListener( InterstitialAdEvent.CLOSED, interstitial_closedHandler );

// ...

function interstitial_openedHandler( event:InterstitialAdEvent ):void
{
trace( "interstitial shown" );
}

function interstitial_closedHandler( event:InterstitialAdEvent ):void
{
trace( "interstitial dismissed" );
}

becomes:

var interstitial:InterstitialAd = Adverts.service.interstitials.createInterstitialAd();
interstitial.setAdUnitId( "AD_UNIT_ID" );

interstitial.addEventListener( InterstitialAdEvent.LOADED, interstitial_loadedHandler );
interstitial.addEventListener( InterstitialAdEvent.ERROR, interstitial_errorHandler );
interstitial.addEventListener( FullScreenContentEvent.SHOW, interstitial_showHandler );
interstitial.addEventListener( FullScreenContentEvent.DISMISSED, interstitial_dismissedHandler );

// ...

function interstitial_showHandler( event:FullScreenContentEvent ):void
{
trace( "interstitial shown" );
}

function interstitial_dismissedHandler( event:FullScreenContentEvent ):void
{
trace( "interstitial dismissed" );
}

We also suggest adding the listener for the FullScreenContentEvent.FAILED_TO_SHOW event, handling any errors that are specific to displaying the fullscreen adverts. This should be done similarly to the load error events eg InterstitialAdEvent.ERROR

RequestConfiguration

AdMob has moved some of the request options to a general "Request Configuration" API. This includes child directed treatments, targetting under age and max content ratings, along with the device ids used for testing. These options used to be set in the AdRequestBuilder but are now set globally through a RequestConfiguration object passed to Adverts.service.setRequestConfiguration().

In the past you may have used:

var builder:AdRequestBuilder = new AdRequestBuilder()
.tagForChildDirectedTreatment( false )
.tagForUnderAgeOfConsent( false )
.maxAdContentRating( "G" )
;

You should change these settings to be in a central location (after initialisation) using the following:

var config:RequestConfiguration = new RequestConfiguration()
.setTagForChildDirectedTreatment( RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE )
.setTagForUnderAgeOfConsent( RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_FALSE )
.setMaxAdContentRating( RequestConfiguration.MAX_AD_CONTENT_RATING_G )
.setTestDeviceIds( ["XXXSSSAAA"] )
;

Adverts.service.setRequestConfiguration( config );

Then when requesting an ad just construct a simple builder:

var builder:AdRequestBuilder = new AdRequestBuilder();

More information in the Targeting section.

- + \ No newline at end of file diff --git a/docs/adverts/migrating-to-version-14.0/index.html b/docs/adverts/migrating-to-version-14.0/index.html index 62537e2946e..26a1269c1ce 100644 --- a/docs/adverts/migrating-to-version-14.0/index.html +++ b/docs/adverts/migrating-to-version-14.0/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to version 14.0

Version 14.0 brings support for running the Adverts extension when using the runtimeInBackgroundThread configuration for AIR.

Most of the changes have been handled internally however there is one major change to the API that means creation of an AdView instance for banner adverts is now asynchronous.

Previously you would have written:

var adView:AdView = Adverts.service.createAdView();

// Set properties and load ads as required

The signature of the createAdView() function has been changed and now takes a callback function:

Adverts.service.createAdView(
function( adView:AdView ):void
{
// Set properties and load ads as required
});
- + \ No newline at end of file diff --git a/docs/adverts/native-ads/index.html b/docs/adverts/native-ads/index.html index 4053bb72559..35e50fab1af 100644 --- a/docs/adverts/native-ads/index.html +++ b/docs/adverts/native-ads/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Native Ads

Native ads allow you to customize the look and feel of the ads that appear in your app. You design the ads from the ground up: how they look, where they’re placed, and how they work within your existing app design.

Using native ads you can customize your ads resulting in a better user experience. Better user experiences can increase engagement and improve your overall yield.

Currently only Native Ad Templates are implemented. If you need a custom view implementation please contact our custom development team at airnativeextensions@distriqt.com

Load an Ad

Native ads are loaded via the NativeAd class.

Firstly create an instance of the NativeAd by calling Adverts.service.nativeAds.createNativeAd() passing your unit id:

var nativeAd:NativeAd = Adverts.service.nativeAds.createNativeAd( "ca-app-pub-3940256099942544/2247696110" );

To load an ad call the loadAd() function of the NativeAd instance and pass an AdRequest object which will specify the details of the ad request to load. You create an AdRequest by using the AdRequestBuilder. The builder is used to correctly create the request object and easily set the availble properties on the request.

The simplest example is to just use a generic request:

nativeAd.load( new AdRequestBuilder().build() );

You can set properties, such as adding a gender to the request, using the other methods on the builder:

var request:AdRequest = new AdRequestBuilder()
.setGender( AdRequest.GENDER_MALE )
.build();

nativeAd.load( request );

See Targeting for more on the AdRequestBuilder targetting options.

The load process will dispatch one of two events:

  • NativeAdEvent.LOADED: On successful load of a native ad;
  • NativeAdEvent.ERROR: If there was an error, (eg invalid account, unit id etc)
var nativeAd:NativeAd = Adverts.service.nativeAds.createNativeAd( "ca-app-pub-3940256099942544/2247696110" );

nativeAd.addEventListener( NativeAdEvent.LOADED, loadedHandler );
nativeAd.addEventListener( NativeAdEvent.ERROR, errorHandler );
nativeAd.load( new AdRequestBuilder().build() );

function loadedHandler( event:NativeAdEvent ):void
{
trace( "native ad loaded" );
}

function errorHandler( event:NativeAdEvent ):void
{
trace( "errorHandler: " + event.errorCode + "::"+event.errorMessage );
}

As opposed to some other formats, you cannot show a native ad until the load is complete.

Testing and Development

It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.

While in development you should either use the test ad unit ids available or specify your test device id in your ad requests. More information on this is located in the section on Test Ads

Display

We have provided access to the native templates to get started with native ads.

If you require more specific customisation on how your ads are displayed, you can contact our custom development team at airnativeextensions@distriqt.com

There are two templates: small and medium.

Small Template

The small template is ideal for lists or any time you need a long rectangular ad view (similar to a banner).

Medium Template

The medium template is meant to be a one-half to three-quarter page view but can also be used in feeds. It is good for landing pages or splash pages.

Show

To use a template call the showWithTemplate() function. This function takes two parameters, the type of template and view parameters to position and size the ad.

For the small sized template:

nativeAd.showWithTemplate( NativeAdTemplate.SMALL, params );

For the medium sized template:

nativeAd.showWithTemplate( NativeAdTemplate.MEDIUM, params );

You must specify the size and position for the advert in order for it to be correctly created. Here params is an instance of AdViewParams. You must at least provide the width and height for the ad:

var params:AdViewParams = new AdViewParams();
params.width = 800;
params.height = 800;

nativeAd.showWithTemplate( NativeAdTemplate.MEDIUM, params );

Size and Position

To control the size and position of the advert, use the setViewParams() function. This function uses the AdViewParams class to communicate position and size of the native ad.

To set the position:

var params:AdViewParams = new AdViewParams();
params.x = 50;
params.y = 50;
params.width = 800;
params.height = 400;

nativeAd.setViewParams( params );

You must specify a width or height for a native ad! Unlike other ad formats the content is created and sized from a template according to your needs so it is very important that you provide size information.

To retrieve the displayed position and size of the advert use the getViewParams() function.

var params:AdViewParams = nativeAd.getViewParams();

trace( "AD WIDTH: " + params.width );
trace( "AD HEIGHT: " + params.height );

Styling

You can style the templates by providing a custom NativeAdTemplateStyle instance to the showWithTemplate() function.

The NativeAdTemplateStyle has a range of functions to control various styles, such as text sizes and background colours.

var style:NativeAdTemplateStyle = new NativeAdTemplateStyle()
.setMainBackgroundColor( 0xFFFF00FF )
.setCallToActionBackgroundColor( 0xFFFF0000 )
.setPrimaryTextBackgroundColor( 0xFF00FF00 )
.setSecondaryTextBackgroundColor( 0xFF0000FF )
.setTertiaryTextBackgroundColor( 0xFF000000 );

This instance is passed as the second parameter to the showWithTemplate() function:

nativeAd.showWithTemplate( NativeAdTemplate.MEDIUM, params, style );

Example

var nativeAd:NativeAd = Adverts.service.nativeAds.createNativeAd( "ca-app-pub-3940256099942544/2247696110" );

nativeAd.addEventListener( NativeAdEvent.LOADED, loadedHandler );
nativeAd.addEventListener( NativeAdEvent.ERROR, errorHandler );

nativeAd.load( new AdRequestBuilder().build() );


function loadedHandler( event:NativeAdEvent ):void
{
var params:AdViewParams = new AdViewParams();
params.width = 800;
params.height = 400;

var style:NativeAdTemplateStyle = new NativeAdTemplateStyle()
.setMainBackgroundColor( 0xFFFF00FF )
.setCallToActionBackgroundColor( 0xFFFF0000 )
.setPrimaryTextBackgroundColor( 0xFF00FF00 )
.setSecondaryTextBackgroundColor( 0xFF0000FF )
.setTertiaryTextBackgroundColor( 0xFF000000 );

nativeAd.showWithTemplate(
NativeAdTemplate.SMALL,
params,
style
);
}

function errorHandler( event:NativeAdEvent ):void
{
trace( "errorHandler: " + event.errorCode + "::"+event.errorMessage );
}
- + \ No newline at end of file diff --git a/docs/adverts/platform/admob/index.html b/docs/adverts/platform/admob/index.html index 350ecc333be..f14928426b6 100644 --- a/docs/adverts/platform/admob/index.html +++ b/docs/adverts/platform/admob/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ impacted by ATS on iOS 9 devices, while NSAllowsArbitraryLoadsForMedia and NSAllowsAribtraryLoadsInWebContent are required to make sure your ads are not impacted by ATS on iOS 10 devices.

Add the SKAdNetworkItems key with Google's SKAdNetworkIdentifier value of cstr6suwn9.skadnetwork:

<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>

For iOS 14 you need to add the NSUserTrackingUsageDescription string to specify the message shown to users when requesting app tracking through the new App Tracking Transparency framework. The string specified here will be shown to users when the permission request is presented.

<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>

Example:

<iPhone>
<InfoAdditions><![CDATA[
<key>UIDeviceFamily</key>
<array>
<string>1</string>
<string>2</string>
</array>

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsForMedia</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-AAAAAAAAAAAAAAAA~XXXXXXXXXX</string>

<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>

<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>
]]></InfoAdditions>
<requestedDisplayResolution>high</requestedDisplayResolution>
<Entitlements>
<![CDATA[
]]>
</Entitlements>
</iPhone>

MultiDex Applications

danger

This is enabled by default with the latest AIR builds (33.1.1.x and higher). You should no longer add the android.multidex extension.

This information is for legacy developers only!

If you have a large application and are supporting Android 4.x then you will need to ensure you enable your application to correctly support MultiDex to allow the application to be broken up into smaller dex packages.

This is enabled by default with releases of AIR v25+, except in the Android 4.x case where you need to change the manifest additions for the application tag to match the following and use the MultiDexApplication.

This will require the addition of the androidx.multidex extension which contains the androidx.multidex.MultiDexApplication implementation.

<manifest android:installLocation="auto">
<!-- PERMISSIONS -->

<application android:name="androidx.multidex.MultiDexApplication">

<!-- ACTIVITIES / RECEIVERS / SERVICES -->

</application>
</manifest>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Adverts.isSupported)
{
// Functionality here
}

Check Google Play Services Availability

This extension requires the use of Google Play Services.

You should use the GoogleApiAvailability helper in the com.distriqt.playservices.Base ANE. The documentation for this class is available in the Google Play Services wiki.

For example:

import com.distriqt.extension.playservices.base.ConnectionResult;
import com.distriqt.extension.playservices.base.GoogleApiAvailability;
var result:int = GoogleApiAvailability.instance.isGooglePlayServicesAvailable();
if (result != ConnectionResult.SUCCESS)
{
if (GoogleApiAvailability.instance.isUserRecoverableError( result ))
{
GoogleApiAvailability.instance.showErrorDialog( result );
}
else
{
trace( "Google Play Services aren't available on this device" );
}
}
else
{
trace( "Google Play Services are Available" );
}

If Google Play Services aren't available then you may not be able to use the functionality in this extension.

- + \ No newline at end of file diff --git a/docs/adverts/platform/huawei/index.html b/docs/adverts/platform/huawei/index.html index e50ccfa8dc4..1b200e04daa 100644 --- a/docs/adverts/platform/huawei/index.html +++ b/docs/adverts/platform/huawei/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Huawei Ads Kit

This section describes how to setup your AIR application to use Huawei Ads Kit with this extension. Huawei devices use a variant of Android.

You should make sure you have been through the process of creating an Huawei developer account and setup your Ads application in the console :

You will need to gather a few resources from the console,

  • agconnect-services.json configuration file;
  • Ad Unit ids for the advertisements you plan to display;

AppGallery Connect Configuration File

  • Sign in to AppGallery Connect and select My apps.
  • Find your app from the list and click the app name.

  • Go to Development > Overview > App information.
  • Click agconnect-services.json to download the configuration file.

  • Add agconnect-services.json to the root of your application and ensure it is packaged.

Install

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the Huawei variant of the extension by running:

apm install com.distriqt.Adverts-huawei

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ assets
| |____ android
| | |____ grs_sdk_global_route_config_apptouchupdatesdk.json
| | |____ grs_sdk_global_route_config_hmscoreInstallerSDK.json
| | |____ grs_sdk_global_route_config_opensdkService.json
| | |____ grs_sdk_global_route_config_updatesdk.json
| | |____ grs_sdk_server_config.json
| | |____ grs_sp.bks
| | |____ hmsincas.bks
| | |____ hmsrootcas.bks
| | |____ updatesdkcas.bks
|____ ane
| |____ com.distriqt.Adverts.ane # Adverts extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

  • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/android folder to the root of your Android application package. (It contains the resource files for the Huawei SDK). You do not need to add this to your iOS application package.

apm project config set com.distriqt.Adverts
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Adverts.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/adverts/rewarded-interstitial-ads/index.html b/docs/adverts/rewarded-interstitial-ads/index.html index 9e1bfd1f74a..a84aff277ae 100644 --- a/docs/adverts/rewarded-interstitial-ads/index.html +++ b/docs/adverts/rewarded-interstitial-ads/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ See the Initialise Platform section.

Support

The rewarded interstitial ads have their own isSupported flag as rewarded interstitial ads may not be available on all platform and services.

To check if rewarded interstitial ads are supported:

if (Adverts.service.rewardedInterstitialAds.isSupported)
{
// rewarded interstitial ads are supported
}

This allows you to create a fallback scenario if rewarded interstitial ads aren't supported on the current platform and device.

RewardedInterstitialAd

To create a RewardedInterstitialAd instance use the createRewardedInterstitialAd() function:

var rewardedAd : RewardedInterstitialAd = Adverts.service.rewardedInterstitialAds.createRewardedInterstitialAd();

This will instanciate an instance of the RewardedInterstitialAd class. You are required to destroy this instance when you are finished with it.

You are required to set the ad unit id by calling the setAdUnitId function before any loading is performed.

rewardedAd.setAdUnitId( "REWARDED_AD_UNIT_ID" );

Loading

Rewarded interstitial Ads should be preloaded in your application. This allows you to start the load at any time, and only display when your application is ready and when the advert has been loaded. You cannot display a rewarded interstitial ad until it is loaded and ready.

To load an advert you use the load function and pass it an AdRequest object which will specify the details of the ad request to load.

The simplest example is to just use a generic request:

rewardedAd.load( new AdRequestBuilder().build() );

See Targeting for more on the AdRequestBuilder targetting options.

You can listen for events that will inform you on when an advert is available or if there were any errors in loading the advert.

rewardedAd.addEventListener( RewardedInterstitialAdEvent.LOADED, loadedHandler );
rewardedAd.addEventListener( RewardedInterstitialAdEvent.ERROR, errorHandler );

function loadedHandler( event:RewardedInterstitialAdEvent ):void
{
// rewarded interstitial ad loaded and ready to be displayed
}

function errorHandler( event:RewardedInterstitialAdEvent ):void
{
// Load error occurred. The errorCode will contain more information
trace( "Error" + event.errorCode );
}

If an error occurs you can use the errorCode on the event to determine what type of error occurred. See the troubleshooting guide to determine what happened.

Testing and Development

It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.

While in development you should either use the test ad unit ids available or specify your test device id in your ad requests. More information on this is located in the section on Test Ads

The following Ad Unit IDs can be used to test rewarded interstitial ads in your application:

Checking Loaded

You can check whether the advert is loaded by waiting for the RewardedInterstitialAdEvent.LOADED or checking the isLoaded() flag. It is useful to use the flag to confirm that the ad is loaded before attempting to display the ad:

if (rewardedAd.isLoaded())
{
// Show the ad
}

Display

When you are ready to display the rewarded interstitial you call show() as below:

rewardedAd.show();

You should check whether the ad is loaded before calling show to ensure that there is an ad available to display (as noted above). If there isn't this call will fail and return false.

if (rewardedAd.isLoaded())
{
rewardedAd.show();
}

Events

There are several events dispatched by the rewarded interstitial ad as the user interacts with it (in addition to the loaded and error events already mentioned):

rewardedAd.addEventListener( FullScreenContentEvent.SHOW, showHandler );
rewardedAd.addEventListener( FullScreenContentEvent.DISMISSED, dismissedHandler );

function showHandler( event:FullScreenContentEvent ):void
{
// The rewarded interstitial ad has been shown and is now visible to the user
}

function dismissedHandler( event:FullScreenContentEvent ):void
{
// Control has returned to your application
// you should reactivate any paused / stopped parts of your application.
}

Rewards

Rewarding your user should take place after the RewardedInterstitialAdEvent.REWARD event is dispatched. This is the important event that is dispatched after the user has finished watching the video ad and is when you should give the reward associated with this event to your user.

rewardedAd.addEventListener( RewardedInterstitialAdEvent.REWARD, rewardHandler );

function rewardHandler( event:RewardedInterstitialAdEvent ):void
{
// Here you should reward your user

// event.rewardAmount contains the amount that should be awarded to your user
// event.rewardType contains the type of this reward
}

Refresh

Once you have displayed a rewarded interstitial ad a new ad needs to be loaded in order to display the rewarded interstitial ad again. This is a simple matter of starting a new ad request load:

rewardedAd.load( new AdRequestBuilder().build() );

The FullScreenContentEvent.DISMISSED event is generally a good place to trigger this load so that you ensure you always have a loaded ad available to display in your application, however you can handle this process as you see fit.

- + \ No newline at end of file diff --git a/docs/adverts/rewarded-video-ads/index.html b/docs/adverts/rewarded-video-ads/index.html index 2be767d5732..12ee7945528 100644 --- a/docs/adverts/rewarded-video-ads/index.html +++ b/docs/adverts/rewarded-video-ads/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ See the Initialise Platform section.

Support

The rewarded video ads have their own isSupported flag as rewarded video ads may not be available on all platform and services.

To check if rewarded video ads are supported:

if (Adverts.service.rewardedVideoAds.isSupported)
{
// rewarded video ads are supported
}

This allows you to create a fallback scenario if rewarded video ads aren't supported on the current platform and device.

RewardedVideoAd

To create a RewardedVideoAd instance use the createRewardedVideoAd() function:

var rewardedVideoAd : RewardedVideoAd = Adverts.service.rewardedVideoAds.createRewardedVideoAd();

This will instanciate an instance of the RewardedVideoAd class. You are required to destroy this instance when you are finished with it.

You are required to set the ad unit id by calling the setAdUnitId function before any loading is performed.

rewardedVideoAd.setAdUnitId( "REWARDED_AD_UNIT_ID" );

Loading

Rewarded Video Ads should be preloaded in your application. This allows you to start the load at any time, and only display when your application is ready and when the advert has been loaded. You cannot display a rewarded video ad until it is loaded and ready.

To load an advert you use the load function and pass it an AdRequest object which will specify the details of the ad request to load.

The simplest example is to just use a generic request:

rewardedVideoAd.load( new AdRequestBuilder().build() );

See Targeting for more on the AdRequestBuilder targetting options.

You can listen for events that will inform you on when an advert is available or if there were any errors in loading the advert.

rewardedVideoAd.addEventListener( RewardedVideoAdEvent.LOADED, loadedHandler );
rewardedVideoAd.addEventListener( RewardedVideoAdEvent.ERROR, errorHandler );

function loadedHandler( event:RewardedVideoAdEvent ):void
{
// rewarded video ad loaded and ready to be displayed
}

function errorHandler( event:RewardedVideoAdEvent ):void
{
// Load error occurred. The errorCode will contain more information
trace( "Error" + event.errorCode );
}

If an error occurs you can use the errorCode on the event to determine what type of error occurred. See the troubleshooting guide to determine what happened.

Testing and Development

It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.

While in development you should either use the test ad unit ids available or specify your test device id in your ad requests. More information on this is located in the section on Test Ads

The following Ad Unit IDs can be used to test rewarded video ads in your application:

Checking Loaded

You can check whether the advert is loaded by waiting for the RewardedVideoAdEvent.LOADED or checking the isLoaded() flag. It is useful to use the flag to confirm that the ad is loaded before attempting to display the ad:

if (rewardedVideoAd.isLoaded())
{
// Show the ad
}

Display

When you are ready to display the rewarded video you call show() as below:

rewardedVideoAd.show();

You should check whether the ad is loaded before calling show to ensure that there is an ad available to display (as noted above). If there isn't this call will fail and return false.

if (rewardedVideoAd.isLoaded())
{
rewardedVideoAd.show();
}

Events

There are several events dispatched by the rewarded video ad as the user interacts with it (in addition to the loaded and error events already mentioned):

rewardedVideoAd.addEventListener( FullScreenContentEvent.SHOW, showHandler );
rewardedVideoAd.addEventListener( FullScreenContentEvent.DISMISSED, dismissedHandler );

function showHandler( event:FullScreenContentEvent ):void
{
// The rewarded video ad has been shown and is now visible to the user
}

function dismissedHandler( event:FullScreenContentEvent ):void
{
// Control has returned to your application
// you should reactivate any paused / stopped parts of your application.
}

Rewards

Rewarding your user should take place after the RewardedVideoAdEvent.REWARD event is dispatched. This is the important event that is dispatched after the user has finished watching the video ad and is when you should give the reward associated with this event to your user.

rewardedVideoAd.addEventListener( RewardedVideoAdEvent.REWARD, rewardHandler );

function rewardHandler( event:RewardedVideoAdEvent ):void
{
// Here you should reward your user

// event.rewardAmount contains the amount that should be awarded to your user
// event.rewardType contains the type of this reward
}

Refresh

Once you have displayed a rewarded video ad a new ad needs to be loaded in order to display the rewarded video ad again. This is a simple matter of starting a new ad request load:

rewardedVideoAd.load( new AdRequestBuilder().build() );

The FullScreenContentEvent.DISMISSED event is generally a good place to trigger this load so that you ensure you always have a loaded ad available to display in your application, however you can handle this process as you see fit.

- + \ No newline at end of file diff --git a/docs/adverts/server-side-verification/index.html b/docs/adverts/server-side-verification/index.html index 054ae0d9cf5..da88a2a1e0c 100644 --- a/docs/adverts/server-side-verification/index.html +++ b/docs/adverts/server-side-verification/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Server Side Verification

Server-side verification callbacks are URL requests, with query parameters expanded by Google, that are sent by Google to an external system to notify it that a user should be rewarded for interacting with a rewarded or rewarded interstitial ad.

For information on the server-side implementation see the documentation

Custom Data

Apps that require additional data in server-side verification callbacks should use the custom data feature of rewarded ads. Any string value set on a rewarded ad object is forwarded within the custom_data query parameter of the SSV callback. If no custom data value is set, the custom_data query parameter value will not be present in the SSV callback.

The code snippet below demonstrates how to set custom data on a rewarded ad object before requesting an ad.

var rewardedAd : RewardedVideoAd = Adverts.service.rewardedVideoAds.createRewardedVideoAd();


rewardedAd.setServerSideVerificationOptions(
new ServerSideVerificationOptions()
.setUserId( "user_1023" )
.setCustomData( "some custom data" )
);

If you want to set the custom reward string, you must do so before showing the ad.

This applies to a rewarded video or rewarded interstitial ad.

note

Note that the custom reward string will be percent escaped and may require decoding when parsed from the SSV callback.

- + \ No newline at end of file diff --git a/docs/adverts/targeting/index.html b/docs/adverts/targeting/index.html index 908fd00b7e3..c19a7a57e44 100644 --- a/docs/adverts/targeting/index.html +++ b/docs/adverts/targeting/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Targeting

This guide explains how to provide targeting information to an ad request.

RequestConfiguration

RequestConfiguration is an object that collects targeting information to be applied globally.

To update the request configuration retrieve the current configuration and perform any desired updates as follows:

var requestConfiguration:RequestConfiguration = Adverts.service.getRequestConfiguration();

requestConfiguration.setTagForChildDirectedTreatment(
RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE
);

Adverts.service.setRequestConfiguration( requestConfiguration );

Child-directed setting

For purposes of the Children's Online Privacy Protection Act (COPPA), there is a setting called "tag for child-directed treatment". By setting this tag, you certify that this notification is accurate and you are authorized to act on behalf of the owner of the app. You understand that abuse of this setting may result in termination of your Google account.

Note: It may take some time for this designation to take effect in applicable Google services.

As an app developer, you can indicate whether you want Google to treat your content as child-directed when you make an ad request. If you indicate that you want Google to treat your content as child-directed, we take steps to disable IBA and remarketing ads.

  • Call setTagForChildDirectedTreatment() with TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE to indicate that you want your content treated as child-directed for purposes of COPPA.
  • Call setTagForChildDirectedTreatment() with TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE to indicate that you don't want your content treated as child-directed for purposes of COPPA.
  • Call setTagForChildDirectedTreatment() with TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED if you do not wish to indicate how you would like your content treated with respect to COPPA in ad requests.

The following example indicates that you want your content treated as child-directed for purposes of COPPA:

var requestConfiguration:RequestConfiguration = Adverts.service.getRequestConfiguration()
.setTagForChildDirectedTreatment( RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE )
;
Adverts.service.setRequestConfiguration( requestConfiguration );

You can mark your ad requests to receive treatment for users in the European Economic Area (EEA) under the age of consent. This feature is designed to help facilitate compliance with the General Data Protection Regulation (GDPR). Note that you may have other legal obligations under GDPR. Please review the European Union’s guidance and consult with your own legal counsel. Please remember that Google's tools are designed to facilitate compliance and do not relieve any particular publisher of its obligations under the law. Learn more about how the GDPR affects publishers.

When using this feature, a Tag For Users under the Age of Consent in Europe (TFUA) parameter will be included in the ad request. This parameter disables personalized advertising, including remarketing, for that specific ad request. It also disables requests to third-party ad vendors, such as ad measurement pixels and third-party ad servers.

Like child-directed settings, there is a method in RequestConfiguration for setting the TFUA parameter: setTagForUnderAgeOfConsent, with the following options:

  • Call setTagForUnderAgeOfConsent() with TAG_FOR_UNDER_AGE_OF_CONSENT_TRUE to indicate that you want the ad request to receive treatment for users in the European Economic Area (EEA) under the age of consent.
  • Call setTagForUnderAgeOfConsent() with TAG_FOR_UNDER_AGE_OF_CONSENT_FALSE to indicate that you want the ad request to not receive treatment for users in the European Economic Area (EEA) under the age of consent.
  • Call setTagForUnderAgeOfConsent() with TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED to indicate that you have not specified whether the ad request should receive treatment for users in the European Economic Area (EEA) under the age of consent.

The following example indicates that you want TFUA included in your ad request:

var requestConfiguration:RequestConfiguration = Adverts.service.getRequestConfiguration()
.setTagForUnderAgeOfConsent( RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_TRUE )
;
Adverts.service.setRequestConfiguration( requestConfiguration );

The tags to enable the Child-directed setting and setTagForUnderAgeOfConsent should not both simultaneously be set to true. If they are, the child-directed setting takes precedence.

Ad content filtering

Apps can set a maximum ad content rating for their ad requests using the setMaxAdContentRating() function. AdMob ads returned have a content rating at or below that level. The possible values for this network extra are based on digital content label classifications, and should be one of the following values:

  • RequestConfiguration.MAX_AD_CONTENT_RATING_G
  • RequestConfiguration.MAX_AD_CONTENT_RATING_PG
  • RequestConfiguration.MAX_AD_CONTENT_RATING_T
  • RequestConfiguration.MAX_AD_CONTENT_RATING_MA

The following code configures an RequestConfiguration object to specify that ad content returned should correspond to a digital content label designation no higher than G:

var requestConfiguration:RequestConfiguration = Adverts.service.getRequestConfiguration()
.setMaxAdContentRating( RequestConfiguration.MAX_AD_CONTENT_RATING_G )
;
Adverts.service.setRequestConfiguration( requestConfiguration );

Note: Content rating filter settings specified via the SDK will override any settings configured using the AdMob UI.

Ad request

The AdRequest object collects targeting information to be sent with an ad request.

caution

This is legacy information, you should look into the User Messaging Platform for the current approach that automatically applies this information

Under the Google EU User Consent Policy, you must make certain disclosures to your users in the European Economic Area (EEA) and obtain their consent to use cookies or other local storage, where legally required, and to use personal data (such as AdID) to serve ads. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). To support publishers in meeting their duties under this policy, Google offers a Consent SDK.

Ads served by Google can be categorized as personalized or non-personalized, both requiring consent from users in the EEA. By default, ad requests to Google serve personalized ads, with ad selection based on the user's previously collected data. Google also supports configuring ad requests to serve non-personalized ads. Learn more about personalized and non-personalized ads.

You should ensure that somewhere in your application you ask for consent from your users to serve personalised ads. Once you have retrieved this response from your user if they have denied consent then ensure you pass it to your AdRequests.

The default behavior of the Google Mobile Ads SDK is to serve personalized ads. If a user has consented to receive only non-personalized ads, you can configure an AdRequest object with the following code to specify that only non-personalized ads should be returned:

var request:AdRequest = new AdRequestBuilder()
.nonPersonalisedAds( true )
.build();

You must add this to all your AdRequests.

Further information:

- + \ No newline at end of file diff --git a/docs/adverts/test-ads/index.html b/docs/adverts/test-ads/index.html index eb19cadf387..1ed12732abc 100644 --- a/docs/adverts/test-ads/index.html +++ b/docs/adverts/test-ads/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Test Ads

It is very important that while you are developing your application that you do not serve live ads. This is a requirement of the usage of AdMob and not following this correctly can have your application id blocked from using AdMob.

It is important to enable test ads during development so that you can click on them without charging Google advertisers. If you click on too many ads without being in test mode, you risk your account being flagged for invalid activity.

Sample ad units

The quickest way to enable testing is to use Google-provided test ad units. These ad units are not associated with your AdMob account, so there's no risk of your account generating invalid traffic when using these ad units. Here are sample ad units that point to specific test creatives for each format:

Android

Ad formatSample ad unit ID
Bannerca-app-pub-3940256099942544/6300978111
Interstitialca-app-pub-3940256099942544/1033173712
Interstitial Videoca-app-pub-3940256099942544/8691691433
Rewarded Videoca-app-pub-3940256099942544/5224354917
Native Advancedca-app-pub-3940256099942544/2247696110
Native Advanced Videoca-app-pub-3940256099942544/1044960115
App Open Adca-app-pub-3940256099942544/3419835294

iOS

Ad formatSample ad unit ID
Bannerca-app-pub-3940256099942544/2934735716
Interstitialca-app-pub-3940256099942544/4411468910
Interstitial Videoca-app-pub-3940256099942544/5135589807
Rewarded Videoca-app-pub-3940256099942544/1712485313
Native Advancedca-app-pub-3940256099942544/3986624511
Native Advanced Videoca-app-pub-3940256099942544/2521693316
App Open Adca-app-pub-3940256099942544/5662855259

Test Devices

If you want to do more rigorous testing with production-looking ads, you can now configure your device as a test device and use your own ad unit IDs that you've created. Test devices can either be added in the AdMob UI or programmatically.

var config:RequestConfiguration = Adverts.service.getRequestConfiguration()
.setTestDeviceIds( [ "33BE2250B43518CCDA7DE426D04EE231" ] )
;

Adverts.service.setRequestConfiguration( config );

This test id is listed in the device logs when testing an ad request.

Android

Check the logcat output for a message that looks like this:

I/Ads: Use RequestConfiguration.Builder.setTestDeviceIds(Arrays.asList("33BE2250B43518CCDA7DE426D04EE231")) to get test ads on this device.

Android emulators are automatically configured as test devices.

Read more here

iOS

Check the console (device logs) for a message that looks like this:

<Google> To get test ads on this device, set: GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers = @[ @"2077ef9a63d2b398840261c8221a0c9b" ];

Read more here

- + \ No newline at end of file diff --git a/docs/adverts/troubleshooting/index.html b/docs/adverts/troubleshooting/index.html index 57607afa82c..6a25913ce73 100644 --- a/docs/adverts/troubleshooting/index.html +++ b/docs/adverts/troubleshooting/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Troubleshooting

Common Issues

Account Setup

It is important that you have completed the account setup through the AdMob console. An incomplete account setup will generally mean all ad requests will fail.

Accounts require a linked application before they can be reviewed and approved by AdMob. Without this you will not receive live ads and may not receive test ads. (This requirement is being rolled out through 2021).

Note that new apps must be listed and linked to a supported store in order to be approved and remove the ad serving limit. New apps not listed to any supported stores won't be able to be reviewed. To have an app reviewed and eligible for approval, list and link the app to a supported store.

Reference: https://support.google.com/admob/answer/10417515

Resolve common onboarding issues

Carefully review the details you receive from the Google Mobile Ads SDK to determine the issue you're having. Click on the error message you received to view more details about how to fix the issue.

https://support.google.com/admob/answer/9905175

iOS Crash on Launch

If you encounter a crash on launch, ensure you have added the info additions correctly. The AdMob SDK will terminate your application if you haven't provided your application identifier in the info additions.

Waiting

It can take an hour or two for a new ad unit to become available. Make sure you have waited a decent amount of time before testing your ad unit ids.

AdMob Error Codes

Error Code 0

Error code 0 (ERROR_CODE_INTERNAL_ERROR) can occur for many reasons. It is an Internal Error that may indicate that something unexpected has happened, such as an error from the SDK, or an invalid response from the server.

Firstly check that your identifier's are all correct. If you are on iOS also check that you have provided the correct account id to the initialisePlatform call.

The most common cause that we have encountered of this issue is an application id (package name) that has been denied or blocked by AdMob. This can occur if you have been using live ad unit ids while developing your application rather than using the test id's or specifying the test device id.

To confirm this you can try changing your application id and serving the same ad unit id from this new application id. If it works from this new application id then you can assume your application id has been blocked.

If you suspect that your app's Package Name has been blocked from serving ads, then it's not something specific to the Mobile Ads SDK and this ANE. We recommend that you reach out to the Product Support Team to get this issue sorted out, or you can use this Troubleshooter.

Make sure to provide them the necessary information, such as any affected Ad Unit IDs and Package Names for them to assist you quicker.

Error Code 1

Error code 1 (ERROR_CODE_INVALID_REQUEST ) can occur in certain situations.

The most common situation is that your AdUnit ID is incorrect. Check that it was correctly transferred from the console and no irregular characters or spaces have been included.

This error can also occur if the user of this device has enabled ad limiting. This can affect the requests to AdMob and result in this error.

This error can also be caused by an incomplete account setup.

- + \ No newline at end of file diff --git a/docs/adverts/user-messaging-platform/index.html b/docs/adverts/user-messaging-platform/index.html index 9848aafcec1..631bdf16694 100644 --- a/docs/adverts/user-messaging-platform/index.html +++ b/docs/adverts/user-messaging-platform/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ If you don't add the advertising identifier library the UMP calls will fail.

UMP uses the advertising identifier which isn't installed by default with the Adverts extension now as it defaults to the new AppSet identifier.

In order to use UMP you will need to add the advertising identifier dependencies. We suggest you install the IDFA extension to achieve this.

Usage

You retrieve the consent information through the ConsentInformation instance accessible via:

var consentInformation:ConsentInformation = Adverts.service.ump.getConsentInformation();

This object has the consent information including:

It is recommended that you request an update of the consent information at every app launch. This will determine whether or not your user needs to provide consent.

To update consent information call the requestConsentInfoUpdate() function on the consent information object.

var params:ConsentRequestParameters = new ConsentRequestParameters();

consentInformation.requestConsentInfoUpdate( params );

This will dispatch one of two possible events:

var consentInformation:ConsentInformation = Adverts.service.ump.getConsentInformation();
consentInformation.addEventListener( ConsentInformationEvent.CONSENT_INFO_UPDATE_SUCCESS, updateSuccessHandler );
consentInformation.addEventListener( ConsentInformationEvent.CONSENT_INFO_UPDATE_FAILURE, updateFailureHandler );


var params:ConsentRequestParameters = new ConsentRequestParameters();

consentInformation.requestConsentInfoUpdate( params );

function updateSuccessHandler( event:ConsentInformationEvent ):void
{
// consent information has been updated
}

function updateFailureHandler( event:ConsentInformationEvent ):void
{
trace( "ERROR: [" + event.error.errorID + "] " + event.error.message );
}

Load a form if available

Once you've determined that you will ask a user for consent, the next step is to determine if a form is available.

There are a variety of reasons why a form may not be available, such as:

To check if a form is available, use the isConsentFormAvailable() method on the ConsentInformation instance.

if (consentInformation.isConsentFormAvailable())
{
// A form is available to load
Adverts.service.ump.addEventListener( UserMessagingPlatformEvent.CONSENT_FORM_LOAD_SUCCESS, loadFormSuccessHandler );
Adverts.service.ump.addEventListener( UserMessagingPlatformEvent.CONSENT_FORM_LOAD_FAILURE, loadFormFailureHandler );
Adverts.service.ump.loadConsentForm();
}

To load the form call the loadConsentForm() of the UserMessagingPlatform instance. This will dispatch one of two possible events:

if (consentInformation.isConsentFormAvailable())
{
Adverts.service.ump.addEventListener( UserMessagingPlatformEvent.CONSENT_FORM_LOAD_SUCCESS, loadFormSuccessHandler );
Adverts.service.ump.addEventListener( UserMessagingPlatformEvent.CONSENT_FORM_LOAD_FAILURE, loadFormFailureHandler );
Adverts.service.ump.loadConsentForm();
}

function loadFormSuccessHandler( event:UserMessagingPlatformEvent ):void
{
// Form loaded and ready to be shown
}

function loadFormFailureHandler( event:UserMessagingPlatformEvent ):void
{
// An error occurred
}

Present the form if required

To present the form use the showConsentForm() on the UserMessagingPlatform instance.

Adverts.service.ump.showConsentForm();

You should determine if the user requires consent prior to presenting the form. To check if consent is required, check the getConsentStatus() method on the ConsentInformation object, which returns an value from the ConsentStatus class. There are four possible values:

For example:

function loadFormSuccessHandler( event:UserMessagingPlatformEvent ):void
{
// Form loaded and ready to be shown
if (Adverts.service.ump.getConsentInformation().getConsentStatus() == ConsentStatus.REQUIRED)
{
Adverts.service.ump.showConsentForm();
}
}

You can also use the form to give your user the option to change their consent status. You may wish to do this in a settings screen, and call the showConsentForm() to present the form so the user can change their consent as required.

The showConsentForm() process will dispatch the ConsentInformationEvent.CONSENT_FORM_DISMISSED event when the consent form was dismissed.

Adverts.service.ump.addEventListener( UserMessagingPlatformEvent.CONSENT_FORM_DISMISSED, formDismissedHandler );
Adverts.service.ump.showConsentForm();

function formDismissedHandler( event:UserMessagingPlatformEvent ):void
{
// Handle form dismissal
}

Testing

Force a geography

The UMP SDK provides a simple way to test your app's behavior as though the device was located in the EEA or UK using the debugGeography.

You will need to provide your test device's hashed ID in your app's debug settings to use the debug functionality. If you call requestConsentUpdate() without setting this value, your app will log the required ID hash when run to the native device log.

var params:ConsentRequestParameters = new ConsentRequestParameters()
.setTagForUnderAgeOfConsent( false )
.setConsentDebugSettings(
new ConsentDebugSettings()
.addTestDeviceHashedId( "TEST-DEVICE-HASHED-ID" )
.setDebugGeography( com.distriqt.extension.adverts.ump.DebugGeography.DEBUG_GEOGRAPHY_EEA )
)
;

Adverts.service.ump.getConsentInformation()
.requestConsentInfoUpdate( params );

To force the SDK to treat the device as though it is not in the EEA or UK, use DEBUG_GEOGRAPHY_NOT_EEA. Note that debug settings only work on test devices. Emulators do not need to be added to the device id list as they have testing enabled by default.

Reset

In testing your app with the UMP SDK, you may find it helpful to reset the state of the consent SDK so that you can simulate a user's first install experience. The SDK provides the reset() method of the ConsentInformation interface to do this.

Adverts.service.ump.getConsentInformation().reset();

You should also call reset if you decide to remove the UMP SDK completely from your project.

Delay app measurement (optional)

By default, the Google Mobile Ads SDK initializes app measurement and begins sending user-level event data to Google immediately when the app starts. This initialization behavior ensures you can enable AdMob user metrics without making additional code changes.

However, if your app requires user consent before these events can be sent, you can delay app measurement until you explicitly initialize the Mobile Ads SDK or load an ad.

Android

To delay app measurement, add the following <meta-data> tag in your manifest additions, inside the <application> node:

<!-- Delay app measurement until MobileAds.initialize() is called. -->
<meta-data
android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
android:value="true"/>

iOS

To delay app measurement, add the GADDelayAppMeasurementInit key with a boolean value of true to your app’s InfoAdditions:

<key>GADDelayAppMeasurementInit</key>
<true/>
- + \ No newline at end of file diff --git a/docs/appconfig/add-the-extension/index.html b/docs/appconfig/add-the-extension/index.html index 8de1bfaac60..ef57a5afb40 100644 --- a/docs/appconfig/add-the-extension/index.html +++ b/docs/appconfig/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.AppleSignIn

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.AppConfig.ane # AppConfig extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set the configuration values for usage in the extension. Call the following to step through the configuration values for this extension:
apm project config set com.distriqt.AppConfig

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (AppConfig.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/appconfig/changelog/index.html b/docs/appconfig/changelog/index.html index cc30f1db30d..75a978ba2c1 100644 --- a/docs/appconfig/changelog/index.html +++ b/docs/appconfig/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.03.16 [v1.0.0]

initial release
- + \ No newline at end of file diff --git a/docs/appconfig/index.html b/docs/appconfig/index.html index 21e8d71e7f2..8829be7c3dd 100644 --- a/docs/appconfig/index.html +++ b/docs/appconfig/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

AppConfig

The AppConfig extension gives you access to ...

TODO

We provide complete guides to get you up and running with sharing quickly and easily.

Features

  • ...
  • Single API interface - your code works across iOS and Android with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

AIR

More information here:

com.distriqt.AppConfig

License

You can purchase a license for using this extension:

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/appconfig/setup/index.html b/docs/appconfig/setup/index.html index 0aed529f114..84b961a1867 100644 --- a/docs/appconfig/setup/index.html +++ b/docs/appconfig/setup/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Setup

Android Configuration

The AppConfig extension requires a few additions to the manifest to specify the restrictions configuration for your application.

To define your app's remote configuration options, put the following element in your manifest's <application> element:

<meta-data android:name="android.content.APP_RESTRICTIONS"
android:resource="@xml/app_restrictions" />

You will need to define some custom resources and ensure they are packaged with your applicaiton.

Generally we suggest creating a directory named res and adding that to your application package, and ensure you add the following resdir tag to your application descriptor (ideally right after the android tag):

<android>
</android>
<resdir>res</resdir>

In this res directory create two files as below:

res
|_ values
|_ app_restrictions_strings.xml
|_ xml
|_ app_restrictions.xml

The app_restrictions.xml file contains the predefined values for your app configuration:

app_restrictions.xml
<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">

<restriction
android:key="url"
android:title="@string/restriction_url_title"
android:restrictionType="string"
android:description="@string/restriction_url_description"
android:defaultValue="https://airnativeextensions.com" />

</restrictions>

The app_restrictions_strings.xml file contains any string constants used in the app_restrictions.xml file.

app_restrictions_strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="restriction_url_title">Url endpoint</string>
<string name="restriction_url_description">Url endpoint description</string>
</resources>

Change these files as required for your application. More information on the format can be found in the documentation on Android Managed Configuration

- + \ No newline at end of file diff --git a/docs/appconfig/usage/index.html b/docs/appconfig/usage/index.html index 0240c90df10..b64505c7643 100644 --- a/docs/appconfig/usage/index.html +++ b/docs/appconfig/usage/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ (eg on Android the value in the restrictions resource xml) otherwise null will be returned.

List Keys

You can retrieve a list of the available keys by calling getKeys()

var keys:Array = AppConfig.instance.getKeys();

for each (var key:String in keys)
{
var value:String = AppConfig.instance.getString( key );
}

If default values are available (eg on Android as defined in the resources) then these will also be listed as available keys here.

In other cases (eg on iOS) the keys may only return keys for values that have been set via MDM.

Events

You can listen to the AppConfigEvent.CHANGED event to be notified of when the values are changed.

AppConfig.instance.addEventListener( AppConfigEvent.CHANGED, changedHandler );

function changedHandler( event:AppConfigEvent ):void
{
trace( "values changed" );
}
caution

On iOS this may be triggered when any of the NSUserDefaults values are changed, not just values in the managed config. So you should use this event to refresh your values, but just be aware that it may not have been the managed config that changed.

Testing

iOS Simulator

You can set values in the simulator using the following command:

xcrun simctl spawn booted defaults write com.distriqt.test 'com.apple.configuration.managed' -dict 'url' 'https://airnativeextensions.com' 'port' 80 'some_key' 'some_value'

You can clear the values using:

xcrun simctl spawn booted defaults delete com.distriqt.test

In these commands replace com.distriqt.test with your application id.

- + \ No newline at end of file diff --git a/docs/appgroupdefaults/add-the-extension/index.html b/docs/appgroupdefaults/add-the-extension/index.html index 4728645905f..43e7a117ec3 100644 --- a/docs/appgroupdefaults/add-the-extension/index.html +++ b/docs/appgroupdefaults/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -32,7 +32,7 @@ We suggest you use the content provider method and this documentation is left here only as reference for legacy users

The default is the provider method however if you wish to use the shared file method you can specify the type in the setup call:

AIR
AppGroupDefaults.service.setup( 
"12345678",
"group.com.distriqt.test",
AppGroupDefaults.TYPE_FILE
);
Unity
AppGroupDefaults.Instance.Setup( 
"12345678", // salt
"group.com.distriqt.test", // app group identifier
AppGroupDefaults.TYPE_FILE // Android type
);

This method writes to a public file with the content encrypted.

This requires read / write permissions to the external storage:

<android>
<manifestAdditions><![CDATA[
<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
]]></manifestAdditions>
</android>

With recent versions of Android you will need to request runtime permissions to access the storage.

With AIR you can use the Permissions ANE to request the permissions at runtime.

AIR
Permissions.service.setPermissions( [
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
]);

if (!Permissions.service.hasAuthorisation())
Permissions.service.requestAuthorisation();

Unity you can use the UnityEngine.Android.Permission helper class to request permissions.

Unity
if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite) 
|| !Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead))
{
Permission.RequestUserPermission(Permission.ExternalStorageWrite);
Permission.RequestUserPermission(Permission.ExternalStorageRead);
}

MultiDex Applications

danger

This is enabled by default with the latest AIR builds (33.1.1.x and higher). You should no longer add the android.multidex extension.

This information is for legacy developers only!

If you have a large application and are supporting Android 4.x then you will need to ensure you enable your application to correctly support MultiDex to allow the application to be broken up into smaller dex packages.

This is enabled by default with releases of AIR v25+, except in the Android 4.x case where you need to change the manifest additions for the application tag to match the following and use the MultiDexApplication.

This will require the addition of the androidx.multidex extension which contains the androidx.multidex.MultiDexApplication implementation.

<manifest android:installLocation="auto">
<!-- PERMISSIONS -->

<application android:name="androidx.multidex.MultiDexApplication">

<!-- ACTIVITIES / RECEIVERS / SERVICES -->

</application>
</manifest>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (AppGroupDefaults.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/appgroupdefaults/add-the-plugin/index.html b/docs/appgroupdefaults/add-the-plugin/index.html index 941f7665045..9270aaaedea 100644 --- a/docs/appgroupdefaults/add-the-plugin/index.html +++ b/docs/appgroupdefaults/add-the-plugin/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ each of your applications but must be matchable using the matcher. We suggest using the example above replacing [APPID] with your application id, for example an app_authority may be, group.com.distriqt.test.app1.provider as below:

    <meta-data android:name="app_authority" android:value="group.com.distriqt.test.app1.provider" />

You must place the application authority both in the meta-data tag and in the provider.

Queries

Since Android API v30, Google has limited the ability to discover other applications via use of the <queries> tag in your manifest. You must specify the applications you wish to access in this area otherwise the application won't be able to discover other applications.

Add the following to your manifest:

<queries>
<provider android:authorities="app_authority" />
</queries>

You should add a provider line for each application you are communicating with and replacing app_authority with the app_authority value for that application.

Alternatively you can add the QUERY_ALL_PACKAGES permission, however this is discouraged.

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (AppGroupDefaults.isSupported)
{
// Functionality here
}

Configuration

To configure your application open the AppGroupDefaultsConfig.cs file and change the configuration values for your application. (This file is located at /Assets/distriqt/AppGroupDefaultsUnity/AppGroupDefaults/Editor/AppGroupDefaultsConfig.cs).

This file has 2 important configuration values:

These values are used to configure the iOS Xcode project and the Android manifest. There are some additional configuration values supplied at runtime.

iOS

For iOS the groupIdentifier is the identifier for the group you created in the developer console, eg group.com.distriqt.test.

The applicationAuthority value is not used on iOS.

To confirm this was done successfully (or to do it manually) you can open the Xcode project after your build and simply select Capabilities in your project settings and ensure the App Group capability is enabled. Then select your application groups you plan to use in this application.

Android

The groupIdentifier can be anything you require, generally for simplicity we suggest leaving it as the same identifier as for the iOS group. This value should be the same for every application you use inside this group.

The applicationAuthority uniquely identifies this application content provider, while being in a specific pattern that the plugin uses to identify other providers that it can potentially synchronise with. To this end we suggest using group.COMMON.UNIQUE.provider as this value, replacing COMMON with some common value used across all your applications and UNIQUE with something unique for this application, for example:

info

If you are manually managing the manifest for your Android application make sure you set these values directly in the manifest as described above

- + \ No newline at end of file diff --git a/docs/appgroupdefaults/android/index.html b/docs/appgroupdefaults/android/index.html index 33218dccdff..8b121afb6f4 100644 --- a/docs/appgroupdefaults/android/index.html +++ b/docs/appgroupdefaults/android/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Android Setup

There are two methods available on Android to share settings between applications.

  • Provider Method - uses a content provider and broadcast receiver to share variables
  • File Method - uses an encrypted file to share variables. Deprecated

Provider Method

This method requires that you define a string value for an APPGROUP or groupIdentifier. Similar to iOS it should be a unique string that you share between your applications, eg group.com.distriqt.test. The group identifier can be anything you require, generally for simplicity we suggest leaving it as the same identifier as for the iOS group. This value should be the same for every application you use inside this group.

The applicationAuthority uniquely identifies this application content provider, while being in a specific pattern that the plugin uses to identify other providers that it can potentially synchronise with. To this end we suggest using group.COMMON.UNIQUE.provider as this value, replacing COMMON with some common value used across all your applications and UNIQUE with something unique for this application, for example:

  • group.com.distriqt.authority.unity1.provider
  • group.com.distriqt.authority.unity2.provider
  • group.com.distriqt.authority.unity3.provider

You then place this information in your configuration for you platform or directly in the manifest depending on how you have setup your application.

- + \ No newline at end of file diff --git a/docs/appgroupdefaults/changelog/index.html b/docs/appgroupdefaults/changelog/index.html index df54201bd0f..907d7cc795b 100644 --- a/docs/appgroupdefaults/changelog/index.html +++ b/docs/appgroupdefaults/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.12 [v4.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(docs): update docs for android 30 queries (resolves #14)

2023.01.12 [v4.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(docs): update docs for android 30 queries (resolves #14)

2022.02.02 [v4.1.68]

Update for Android 31
Add documentation for installing using apm
Release air package

2021.04.06 [v4.1.065]

Updated unity minimum requirements and proguard settings + updated docs

2020.08.22 [v4.1.058]

Android: Resolved crash in content provider shared pref (resolves #6)

2020.03.23 [v4.0.054]

Android X migration (resolves #3)

2020.02.24 [v3.0.047]

Updated examples

2020.02.24 [v3.0.047]

Corrected initialise event to correctly return on iOS

2020.01.31 [v3.0.046]

Added initialised event to correctly handle setup completion

2020.01.24 [v3.0.038]

Unity plugin build

2019.08.16 [v2.0.004]

Android 64bit support (resolves #2)
Updated minimum iOS version to 9.0

2019.03.28 [v1.2.041]

Updated minimum iOS version to 8.0 (resolves #1)
Embedded iOS bitcode

2018.07.27 [v1.1.038]

First release
- + \ No newline at end of file diff --git a/docs/appgroupdefaults/index.html b/docs/appgroupdefaults/index.html index b0e04a9c321..747bb3bb912 100644 --- a/docs/appgroupdefaults/index.html +++ b/docs/appgroupdefaults/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

App Group Defaults

The AppGroup Defaults extension provides the ability to be able to share settings in a key-value store between your different applications installed on a users device.

The simple API allows you to quickly integrate saving data. The key-value storage allows you to store discrete values for preferences, configuration, or state variables that need to be shared between applications. Key-value storage is similar to the local user defaults database; but values that you place in key-value storage are available to every application in your group. If one instance of your app changes a value, the other instances see that change and can use it to update their configuration.

We provide complete guides to get you up and running with app group defaults quickly and easily.

It supports both Unity and Adobe AIR frameworks on iOS and Android, allowing you to use the same functionality on all frameworks and platforms.

Features:

Save key/value pairs to App Cloud Defaults on:

  • Ability to share key-value settings between applications;
    • App Group Defaults on iOS;
    • Content Provider based on Android;
  • Your code works across iOS and Android with minimal modifications;
  • Your code works across Unity and Adobe AIR allowing communication between frameworks;
  • Sample project code and ASDocs reference;

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.AppGroupDefaults

License

You can purchase a license for using this extension:

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/appgroupdefaults/ios/index.html b/docs/appgroupdefaults/ios/index.html index bbc3cf61107..53761429b79 100644 --- a/docs/appgroupdefaults/ios/index.html +++ b/docs/appgroupdefaults/ios/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

iOS Setup

iOS requires set up of an "App Group" for your application(s).

Log into the developer member center and go to your application identifiers.

Firstly you will need to create an App Group.

  • Go to App Groups
  • Click the "+" in the top right to register a new group
  • Enter a description and an identifier.
    • The identifier is recommended to be a reverse domain style and starting with group.
    • eg: group.com.distriqt.test

Once you have created a group you need to enable it for the applications that are going to be placed in this group.

  • Go to App IDs
  • Select the application of interest and click edit
  • Enable "App Groups" in the "iOS App ID Settings"
  • Click "Edit" in the "App Groups" row
    • Select the App Group you created previously
    • Click "Continue" and then "Assign"

You will need to regenerate your provisioning profiles and download them again so make sure you do this now.

Next you will need to add this group identifier to the entitlements of your application.

- + \ No newline at end of file diff --git a/docs/appgroupdefaults/unity/index.html b/docs/appgroupdefaults/unity/index.html index bd74c10567f..17769b74f17 100644 --- a/docs/appgroupdefaults/unity/index.html +++ b/docs/appgroupdefaults/unity/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ that the Setup function hasn't been called, or if the isSupported flag is false.

Listing Keys

You can use the GetKeys function to retrieve an Array of all the current keys set in the defaults.

This allows you to list all settings currently stored in the defaults.

string[] keys = AppGroupDefaults.Instance.GetKeys();
foreach (string key in keys)
{
string value = AppGroupDefaults.Instance.GetValue(key);
Debug.Log(key + " = " + value);
}

Removing Values

If you wish to clear a value and remove it from the defaults, simply call the Remove function with the key of interest.

AppGroupDefaults.Instance.Remove("some_key");

Removing All Values

If you wish to remove all values from the defaults, simply call the RemoveAll function:

AppGroupDefaults.Instance.RemoveAll();

Take care with this one as it will affect data across all your applications

Example

The following example shows the core concepts, i.e. the setup process, listening to the OnInitialised event, and getting and setting values.

if (AppGroupDefaults.isSupported)
{
AppGroupDefaults.Instance.OnInitialised += Instance_OnInitialised;

AppGroupDefaults.Instance.Setup(
"12345678", // salt
"group.com.distriqt.test", // app group identifier
AppGroupDefaults.TYPE_CONTENTPROVIDER // Android type
);
}


private void Instance_OnInitialised(AppGroupDefaultsEvent e)
{
Debug.Log("OnInitialised");

string someValue = AppGroupDefaults.Instance.GetValue("someKey");

AppGroupDefaults.Instance.SetValue("anotherKey", "Sample text from Unity!");

}

Support

If you need further support integrating or using this extension please feel free to contact us.

We have been supporting developers for over 10 years and always happy to help.





- + \ No newline at end of file diff --git a/docs/appgroupdefaults/usage/index.html b/docs/appgroupdefaults/usage/index.html index 91233644309..5a191622b78 100644 --- a/docs/appgroupdefaults/usage/index.html +++ b/docs/appgroupdefaults/usage/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ set in the defaults.

This allows you to list all settings currently stored in the defaults.

var keys:Array = AppGroupDefaults.service.getKeys();
for each (var key:String in keys)
{
var value:String = AppGroupDefaults.service.getValue( key );
trace( key + " = " + value );
}

Removing a Value

If you wish to clear a value and remove it from the defaults, simply call the remove function with the key of interest.

AppGroupDefaults.service.remove( "some_key" );

Removing All Values

If you wish to remove all values from the defaults, simply call the removeAll function:

AppGroupDefaults.service.removeAll();

Example

The following example shows the core concepts, i.e. the setup process, listening to the AppGroupDefaultsEvent.INITIALISED event, and getting and setting values.

if (AppGroupDefaults.isSupported)
{
AppGroupDefaults.service.addEventListener( AppGroupDefaultsEvent.INITIALISED, initialisedHandler );
AppGroupDefaults.service.setup(
"12345678",
"group.com.distriqt.test",
AppGroupDefaults.TYPE_FILE
);


}

function initialisedHandler( event:AppGroupDefaultsEvent ):void
{
var someValue:String = AppGroupDefaults.service.getValue( "some_key" );

AppGroupDefaults.service.setValue("anotherKey", "Sample text from AIR!");
}
- + \ No newline at end of file diff --git a/docs/applesignin/add-the-extension/index.html b/docs/applesignin/add-the-extension/index.html index a3ecb868df3..a297e942f08 100644 --- a/docs/applesignin/add-the-extension/index.html +++ b/docs/applesignin/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

iOS SDK

This extension requires to be packaged against iOS SDK v13 or higher. This is included with the latest AIR 33 builds however older releases do not support this so you will need to ensure the version of the iOS SDK contains this or provide the iOS SDK in the platform sdk option at package time.

More information here.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.AppleSignIn

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.AppleSignIn.ane # AppleSignIn extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (AppleSignIn.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/applesignin/changelog/index.html b/docs/applesignin/changelog/index.html index 79b1ec0bafa..d161ac011c3 100644 --- a/docs/applesignin/changelog/index.html +++ b/docs/applesignin/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.13 [v2.3.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #30)

2022.02.02 [v2.2.94]

Update documentation for apm 
Update Android 31 support
Update air package dependencies

2021.09.22 [v2.2.93]

Added air package 
Updated documentation

2021.02.05 [v2.2.088]

Updated documentation links (resolves #22)

2021.02.05 [v2.2.087]

Updated documentation links (resolves #22)

2020.12.23 [v2.2.087]

Added Android raw nonce implementation (resolves #21)

2020.06.18 [v2.1.082]

Added return of the nonce used during authentication for subsequent sign in with Firebase and similar services

2020.04.29 [v2.1.074]

Added additional options and return values for processing android signin (resolves #7)

2020.03.24 [v2.0.069]

Android X migration (resolves #6)

2020.03.02 [v1.1.065]

Updated docs

2020.03.02 [v1.1.065]

Android AppleSignIn implementation

2019.11.16 [v1.0.029]

Updated image

2019.11.15 [v1.0.029]

Updated docs

2019.11.15 [v1.0.029]

Initial beta release
- + \ No newline at end of file diff --git a/docs/applesignin/get-user-credentials/index.html b/docs/applesignin/get-user-credentials/index.html index ab3e9df48ba..a3b12a500a2 100644 --- a/docs/applesignin/get-user-credentials/index.html +++ b/docs/applesignin/get-user-credentials/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Get User Credentials

This has proved highly unreliable on iOS and we currently don't recommend using this process. It seems to commonly return an error even though everything seems correct. We are waiting for feedback / updates from Apple on this

Instead we recommend implementing a server to perform authentication checks using the auth code / tokens.

State

You can check the user credential state by calling the getCredentialStateForUser() and passing the "user" received when authentication succeeded.

Note: This is supported on iOS only

The user value is the AppleIdCredential.user property and you should store this value as an identifier for your user.

AppleSignIn.instance.getCredentialStateForUser( user );

Events

Calling getCredentialStateForUser() will dispatch one of two events:

  • AppleSignInEvent.GET_CREDENTIAL_STATE_SUCCESS: If the credential state was successfully ;
  • AppleSignInErrorEvent.GET_CREDENTIAL_STATE_ERROR: If an error occurred;
AppleSignIn.instance.addEventListener( AppleSignInEvent.GET_CREDENTIAL_STATE_SUCCESS, getCredentials_successHandler );
AppleSignIn.instance.addEventListener( AppleSignInErrorEvent.GET_CREDENTIAL_STATE_ERROR, getCredentials_errorHandler );

AppleSignIn.instance.getCredentialStateForUser( user );


function getCredentials_successHandler( event:AppleSignInEvent ):void
{
trace( "getCredentials_successHandler(): " + event.state );
}

function getCredentials_errorHandler( event:AppleSignInErrorEvent ):void
{
trace( "getCredentials_errorHandler(): [" + event.errorID + "] :: " + event.text );
}

Returned State

The value of the state property in the returned event will be one of the AppleIDCredentialState defined values:

  • AppleIDCredentialState.REVOKED : The user ID was revoked by the user;
  • AppleIDCredentialState.AUTHORIZED : The user ID is in good state;
  • AppleIDCredentialState.NOT_FOUND : The user ID was not found;
- + \ No newline at end of file diff --git a/docs/applesignin/index.html b/docs/applesignin/index.html index 66755b84c7b..2549ae64d29 100644 --- a/docs/applesignin/index.html +++ b/docs/applesignin/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

AppleSignIn

The AppleSignIn extension gives you the ability to sign in your users using the "Sign in with Apple" functionality on iOS / tvOS and Android.

Sign in with Apple makes it easy for users to sign in to your apps and websites using their Apple ID. Instead of filling out forms, verifying email addresses, and choosing new passwords, they can use Sign in with Apple to set up an account and start using your app right away. All accounts are protected with two-factor authentication for superior security, and Apple will not track users’ activity in your app or website.

More information in the Apple documentation

Features

  • Sign in using the user's Apple ID;
  • Single API interface - your code works across supported platforms with no modifications;
  • Sample project code and ASDocs reference

Documentation

The documenation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

AppleSignIn.instance.addEventListener( AppleSignInErrorEvent.ERROR, errorHandler );
AppleSignIn.instance.addEventListener( AppleSignInEvent.SUCCESS, successHandler );

AppleSignIn.instance.loginWithAppleId();

function successHandler( event:AppleSignInEvent ):void
{
// User signed in
}

function errorHandler( event:AppleSignInErrorEvent ):void
{
// Sign in failed
}

More information here:

com.distriqt.AppleSignIn

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/applesignin/login-with-apple-id/index.html b/docs/applesignin/login-with-apple-id/index.html index a9279cdf24a..fa911794988 100644 --- a/docs/applesignin/login-with-apple-id/index.html +++ b/docs/applesignin/login-with-apple-id/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Login with Apple Id

Login

To initiate login call the loginWithAppleId() function:

AppleSignIn.instance.loginWithAppleId();

This will initiate the sign in process and present the "Sign In with Apple" UI.

Options

You can pass a few options to the login function allowing you to control some aspects of the process. Mainly whether the email and full name of the user should be requested.

This is done by passing an instance of the AppleSignInOptions to the loginWithAppleId() function.

For example, to request both the email and full name scopes:

var options:AppleSignInOptions = new AppleSignInOptions()
.setRequestedScopes([
AppleSignInScopes.FULL_NAME,
AppleSignInScopes.EMAIL
]);

AppleSignIn.instance.loginWithAppleId( options );

iOS

Important: To sign in with an Apple account, users must:

  • Have an Apple ID with two-factor authentication (2FA) enabled.
  • Be signed in to iCloud on an Apple device.

See How to use Sign in with Apple. You will also need to meet these requirements to test your integration with Sign In with Apple.

Android

If you are deploying to Android as well then you will need to provide your Service ID (client id) and redirect url in the options.

For example:

var options:AppleSignInOptions = new AppleSignInOptions()
.setRequestedScopes([
AppleSignInScopes.FULL_NAME,
AppleSignInScopes.EMAIL
])
.setClientId( "com.distriqt.test.applesignin" )
.setRedirectUrl( "https://auth.distriqt.com/appleoauth" )
;

The client id is the identifier used to create your Service ID in the apple developer console.

The redirect url is one of the urls you entered when creating your Service ID that you intend to use for this login request.

These values are ignored on iOS.

Events

During the login process you will receive one of the following events:

  • AppleSignInEvent.SUCCESS: Upon successfully authentication;
  • AppleSignInErrorEvent.ERROR: If an error occurred during login;

You should listen for both of these events and handle accordingly.

AppleSignIn.instance.addEventListener( AppleSignInErrorEvent.ERROR, errorHandler );
AppleSignIn.instance.addEventListener( AppleSignInEvent.SUCCESS, successHandler );

function successHandler( event:AppleSignInEvent ):void
{
trace( "user: " + event.appleIdCredential.user );
trace( "identityToken: " + event.appleIdCredential.identityToken );
trace( "authorizationCode: " + event.appleIdCredential.authorizationCode );
trace( "raw Nonce: " + event.rawNonce );
}

function errorHandler( event:AppleSignInErrorEvent ):void
{
trace( "errorHandler(): [" + event.errorID + "] :: " + event.text );
}

You can access the "nonce" used to initiate this authorisation request in the success handler via the event.rawNonce property. This can be used to further authenticate with services such as Firebase.

Encoding

Please note that the identityToken and authorizationCode are Base64 encoded.

This ensures we preserve the contents of the byte data correctly. Some endpoints will use the Base64 encoded string whereas others will require the decoded version.

To decode it you can use the utility class:

var decoded:String = Base64.decode( event.appleIdCredential.identityToken )

User Revoke

The user can revoke the authentication through their apple account. You can listen for a revoke event which will be dispatched if the authentication is ever revoked by the user:

AppleSignIn.instance.addEventListener( AppleSignInEvent.REVOKED, revokedHandler );


function revokedHandler( event:AppleSignInEvent ):void
{
// User revoked authentication
}

Example

AppleSignIn.instance.addEventListener( AppleSignInErrorEvent.ERROR, errorHandler );
AppleSignIn.instance.addEventListener( AppleSignInEvent.SUCCESS, successHandler );

var options:AppleSignInOptions = new AppleSignInOptions()
.setRequestedScopes([
AppleSignInScopes.FULL_NAME,
AppleSignInScopes.EMAIL
])
.setClientId( "com.distriqt.test.applesignin" )
.setRedirectUrl( "https://auth.distriqt.com/appleoauth" );

AppleSignIn.instance.loginWithAppleId( options );



function successHandler( event:AppleSignInEvent ):void
{
trace( "user: " + event.appleIdCredential.user );
trace( "identityToken: " + event.appleIdCredential.identityToken );
trace( "authorizationCode: " + event.appleIdCredential.authorizationCode );
}

function errorHandler( event:AppleSignInErrorEvent ):void
{
trace( "errorHandler(): [" + event.errorID + "] :: " + event.text );
}

Android

With Android the process uses a webview and the OAuth web login.

In order to successfully complete this process you need to setup a server that will exchange the authorisation code for the identity token and user.

There are a few differences with this process that you should be aware of as it will affect how you implement login on Android.

  • User's name components are only returned the first time they log in.
- + \ No newline at end of file diff --git a/docs/applesignin/setup-application/index.html b/docs/applesignin/setup-application/index.html index 590d1141222..9a684d63799 100644 --- a/docs/applesignin/setup-application/index.html +++ b/docs/applesignin/setup-application/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Setup Application

This is an overview of the steps to enable Sign in with Apple in the developer console.

More details can be found in the official Apple documentation here:

The process is divided into 4 key steps:

Enable App ID

Log into the developer console and edit your application identifier:

https://developer.apple.com/account/resources/identifiers/list

Find the "Sign in with Apple" setting, enable it and set the configuration as required for your application.

You will need to update your provisioning profile and ensure you download the updated version.

Create Key

In order to communicate with Apple from your server you will need to setup a key. You will use this to exchange tokens for user data etc especially for the Android / Web implementation.

In the console, select Keys and register a new key by pressing the plus icon. Give your key a name and enable the Sign In with Apple option.

Select Configure and select the application identifier that you enabled Apple Sign-In for above. Save and register the new key.

At this point you will download the key as a p8 file. This is the key that you will upload to your server to use to communicate with the Apple servers.

Save this file in a safe location as you will not be able to download it again.

At this point, select the key again from the list of keys.

Take note of the Key ID

Create Service ID for Web Authentication

This is only required if you are looking to implement sign in for Android or Web using Oauth or if you need to access user details from your server. If you are only implementing this on Apple (iOS/tvOS) you can ignore this section.

To create a service identifier, go to the Identifiers secton and press the plus button. Select Services IDs as the type of the new identifier

Press continue, then enter a description and the identifier, and enable Sign In with Apple

Take note of this identifier you will need it to configure your web application. This is referred to as the "Service ID" or "Client ID".

eg: com.distriqt.test.applesignin

Click Configure for the Sign in with Apple option. Select your application identifier (created above) and enter the domain and return url that you will be using for authentication requests.

If you haven't already, you will need to verify your ownership of this domain by uploading a file to the .well-known directory on your server. Be patient with this process, it can take a while for Apple to pick up a file being uploaded.

Click Continue and then Save to complete the service identifier setup.

Note: To view these service ids you need to change the drop down in the top left of the Identifiers page from App IDs to Service IDs

Register Email Sources for Communication

'Sign in with Apple' gives the users the option to hide their email address when they login. If you wish to contact these users you will need to setup a domain and contact email in your developer account.

Under the "More" section you can setup domains and users for Apple Sign in:

You can register domains and individual email addresses that can contact users using Apple’s private email relay service:

Follow the directions to verify your domain.

- + \ No newline at end of file diff --git a/docs/applesignin/setup-auth-server/index.html b/docs/applesignin/setup-auth-server/index.html index 4017d4df76d..2db00e81400 100644 --- a/docs/applesignin/setup-auth-server/index.html +++ b/docs/applesignin/setup-auth-server/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Setup Auth Server

Setup Auth Server

When implementing Sign in with Apple on Android devices you need to setup a server that will receive the authorisation code and return data to the application. This server application catches the user data posted by Apple and passes it to the extension. The extension will then use this information to further gather the identity token and user identifier.

The below is an NodeJS example (taken from https://github.com/johncodeos-blog/SignInWithAppleBackendServer) which works with our implementation of Sign In with Apple on Android.

This needs to be installed the server redirect url that you verified earlier and you should change the /appleoauth endpoint to match your needs.

To correctly setup the application you will need to enter all the information you gathered earlier into the .env configuration file, including the filename of the key (p8 file) that you created. You must upload this file to the server alongside this code making sure it's not publicly accessible.

If you wish to create your own version, you can use the logic in the below code.

app.js

require('dotenv').config();

const express = require('express');
const app = express();
const fs = require('fs');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const getClientSecret = () => {
const time = new Date().getTime() / 1000; // Current time in seconds since Epoch
const privateKey = fs.readFileSync(process.env.PRIVATE_KEY_FILE);
const headers = {
kid: process.env.KEY_ID,
typ: undefined
}
const claims = {
'iss': process.env.TEAM_ID,
'iat': time, // The time the token was generated
'exp': time + 86400 * 180, // Token expiration date
'aud': 'https://appleid.apple.com',
'sub': process.env.SERVICE_ID,
}
token = jwt.sign(claims, privateKey, {
algorithm: 'ES256',
header: headers
});
return token
}

app.post('/appleoauth', bodyParser.urlencoded({ extended: true }), (req, res) => {
if (res.statusCode == 200) {
var returnURL = "";
var firstName = "";
var middleName = "";
var lastName = "";
var email = "";
if (req.body.hasOwnProperty('user')) {
const userdata = req.body.user;
const user = JSON.parse(userdata);
firstName = '&first_name=' + user.name['firstName'];
middleName = '&middle_name=' + user.name['middleName'];
lastName = '&last_name=' + user.name['lastName'];
email = '&email=' + user.email;
}
var code = '&code=' + req.body.code;
var clientSecret = '&client_secret=' + getClientSecret();
returnURL = '?success=true' + code + clientSecret + firstName + middleName + lastName + email;
res.redirect(returnURL);
} else {
res.redirect('?success=false');
}
})

var port = process.env.PORT;
app.listen(port, () => console.log(`Your app is listening on port ` + port + '.'))

.env

# Private Key .p8 file name
PRIVATE_KEY_FILE=YOUR_KEY_NAME.p8

# Key ID (Certificates, Identifiers & Profiles > Keys > Choose your app > Key ID)
KEY_ID=YYYYYYYYYY

# Team ID (Membership > Team ID)
TEAM_ID=XXXXXXXXXX

# Service ID (Certificates, Identifiers & Profiles > Identifiers > Change to Service IDs on the top right corner -> Choose your app -> Identifier)
SERVICE_ID=YOUR.SERVICE.IDENTIFIER

# The port to run the app
PORT=3000
- + \ No newline at end of file diff --git a/docs/application/add-the-extension/index.html b/docs/application/add-the-extension/index.html index 51bb277f512..8c4ddff5d24 100644 --- a/docs/application/add-the-extension/index.html +++ b/docs/application/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ however if you are only building an iOS application feel free to remove the Google Play Services ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Application.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/application/alarm-manager/index.html b/docs/application/alarm-manager/index.html index ec99316b20b..4188c9ee806 100644 --- a/docs/application/alarm-manager/index.html +++ b/docs/application/alarm-manager/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ Using exact alarms will affect the performance and battery life of the device so you are suggested to use them only if necessary.

To set an exact alarm, call setExact( true ) on your AlarmBuilder:

Application.service.alarmManager.cancelAlarm(
new AlarmBuilder()
.setTime( timestamp )
.setExact( true )
.build()
);

Exact Alarm Permissions

If your app targets Android 12 (API level 31) or higher, you must declare one of the "Alarms & reminders" permissions; otherwise, a SecurityException occurs and your alarm will not be registered.

To do so, declare the SCHEDULE_EXACT_ALARM permission in your manifest additions, as shown in the following code snippet:

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>

To add these permissions you need to add some additional configuration to apm. Firstly add a custom Android configuration file by running:

apm generate config android

Edit the config/android/AndroidManifest.xml file that was generated to resemble the following, adding the required permissions, eg:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

</manifest>

You can add any other additions you require in your application here and these will be merged by apm when you generate your application descriptor.

info

Make sure you regenerate your application descriptor after modifying this file. See the section in add the extension for details.

- + \ No newline at end of file diff --git a/docs/application/application-state-events/index.html b/docs/application/application-state-events/index.html index 56a6a9b4cbc..56ecb625196 100644 --- a/docs/application/application-state-events/index.html +++ b/docs/application/application-state-events/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Application State Events

The AIR standard ACTIVATE and DEACTIVATE events will inform your application when the AIR application loses focus. This is often used to stop application rendering and other operations that you wish to perform when your application enters the background or returns to the foreground.

However these events will not completely inform you of when your application enters the background or foreground, as these events can be triggered when other elements are overlaid on your application, such as dialogs or even the iOS control center. In these cases generally you don't want to deactivate your application as your application is still running in the foreground.

Instead if you wish to only monitor when your application enters the background either by being minimised or by the device being closed you can use the ApplicationStateEvents.

  • ApplicationStateEvent.BACKGROUND: This event is dispatched when your application enters the background rather than a deactivated state
    • This has the advantage over the Event.DEACTIVATE event (including the normal AIR Event) that it isn't dispatched when a dialog or another activity is launched from your application, where the AIR stage may lose focus but your application is still in the foreground.
  • ApplicationStateEvent.FOREGROUND: This event is dispatched when your application returns from a background state and enters the foreground
    • This has the advantage over the Event.ACTIVATE event that it isn't dispatched when your AIR stage gains focus after a dialog or other activity was closed. Instead it is only dispatched if your application was minimised and is now returning to the foreground.

There are also ACTIVATE and DEACTIVATE events here to be able to monitor the complete lifecycle from a single location:

  • ApplicationStateEvent.ACTIVATE:
    • Similar to the standard AIR Event.ACTIVATE event
  • ApplicationStateEvent.DEACTIVATE: Dispatched when the application is deactivated.
    • This is an alternative of the AIR Event.DEACTIVATE which will contain more information about whether the application screen was turned off in the deactivation process.

Android

On Android there are a few manifest additions to add to be able to correctly monitor your entire application state.

The following will need to be added into the <application> node of your manifest additions. You will need to replace APPLICATION_PACKAGE with your AIR applications Java package name. Generally this is your application id prefixed with air..

<!-- APPLICATION STATE EVENTS -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="APPLICATION_PACKAGE.androidx-startup"
android:exported="false" >
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
</provider>

Usage

Listening for the events is a very simple process, simply add the event listener to the Application singleton.

Application.service.addEventListener( ApplicationStateEvent.ACTIVATE, stateEventHandler );
Application.service.addEventListener( ApplicationStateEvent.DEACTIVATE, stateEventHandler );
Application.service.addEventListener( ApplicationStateEvent.FOREGROUND, stateEventHandler );
Application.service.addEventListener( ApplicationStateEvent.BACKGROUND, stateEventHandler );

function stateEventHandler( event:ApplicationStateEvent ):void
{
trace( event.type + "::" + event.code );

if (event.type == ApplicationStateEvent.BACKGROUND)
{
// Your application is in the background
}

if (event.type == ApplicationStateEvent.FOREGROUND)
{
// Your application is in the foreground
}

}
- + \ No newline at end of file diff --git a/docs/application/auto-start/index.html b/docs/application/auto-start/index.html index c6a7dee7af6..ee301c7684b 100644 --- a/docs/application/auto-start/index.html +++ b/docs/application/auto-start/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Auto Start

This is an Android only feature.

Auto Start

This process allows your application to automatically start when the device is booted or turned on.

You must run your application at least once before automatic starting can be initialised. You enable it by calling the setAutoStart function as below:

Application.service.setAutoStart( true );

If you wish to disable auto start at a later point you can pass false to this same function:

Application.service.setAutoStart( false );

State

You can check if auto start is enabled by checking the isAutoStartEnabled() flag.

if (Application.service.isAutoStartEnabled())
{
//
}

Was Auto Started

You can check if your application was launched using the auto start mechanism using the wasAutoStarted() flag.

if (Application.service.wasAutoStarted())
{
// This launch was from an auto start
}

Manifest Additions

You must make sure you have added the following receiver and permission to your application descriptors manifest additions.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Required for Android 30 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

<application>
<receiver android:enabled="true" android:name="com.distriqt.extension.application.receivers.ApplicationStartupReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>

Android 30

With Android 30, the approach that was used in previous versions of Android to auto-launch your application has been removed meaning that we can no longer directly launch your application on boot.

The new approach requires a system permission from the user to "Display over other apps". With this permission we can still launch your application on launch using an updated approach.

To check if the user has granted this permission you can call the hasAutoStartPermission() method:

var hasPermission:Boolean = Application.service.hasAutoStartPermission();

If the user hasn't granted it you can open the system settings via the requestAutoStartPermission() method:

if (!Application.service.hasAutoStartPermission())
{
Application.service.requestAutoStartPermission();
}

Unfortunately there is no feedback from this process but you should be able to use the application state events to handle an activation of your application after calling this.

Once you have this permission, then auto start will work as above.

note

Some Android TV devices don't support this permission request. We have added an additional function to check if the auto start permission request is available:

if (Application.service.canRequestAutoStartPermission())
{
Application.service.requestAutoStartPermission();
}

Also the requestAutoStartPermission() method will return false if the permission request isn't supported or not required

- + \ No newline at end of file diff --git a/docs/application/changelog/index.html b/docs/application/changelog/index.html index 446f3a097bc..3d6e633438a 100644 --- a/docs/application/changelog/index.html +++ b/docs/application/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.11.02 [v7.1.0]

feat(android): update activity lifecycle listener to new android implementation
feat(ios): update database for new iphone 15 models (resolves #280)

2023.09.26 [v7.0.3]

fix(android): handle null activity case when updating visibility state (resolves #278)

2023.07.31 [v7.0.2]

feat(ios): update device database for latest ipad and iphone device details (resolves #276)
feat(ios): add retrieval of device name and model for ios simulators (resolves #259)

2023.06.22 [v7.0.0]

feat(accessibility): add guided mode detection (resolves #273)
feat(android): air background thread handling (resolves #274)

2023.01.13 [v6.12.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Add ability to check for availability of the request auto start permission (resolves #240)
feat(android): Move to new permissions request process

2022.09.09 [v6.11.0]

fix(alarms): Android 12+ alarms require additional permissions, this adds checks for the permission and error event if missing (resolves #255)

2022.09.05 [v6.10.0]

feat(display): add ability to retrieve bounding rectangle dimensions for screen cutouts/notches (resolves #241) 

2022.06.23 [v6.9.2]

feat(defaults): add ability to use shared preferences on android to access gdpr values
feat(defaults): add docs for changing shared preferences approach
feat(device): add ability to retrieve unique id through the appset play services library
fix(ios): update device database to add iPad12,1,2 ipad models (resolves #248)
fix(ios): update device database to add iPad13,4,5,6,7,8,9,10,11 (iPad Pro 2021) iPad13,16,17 (iPad AIR 2022) iPhone14,6 (SE 3rd) (resolves #248)

2022.03.15 [v6.8.5]

Android: Update to make compatible with latest androidx.core lifecycle library 

2022.01.28 [v6.8.4]

Update for Android 31 exported attribute requirement
Add docs for apm usage

2022.01.18 [v6.8.3]

Update android startup receiver to use new AIR app entry activity name (resolves #234)

2021.12.21 [v6.8.2]

Add minimise function for Android (resolves #231)

2021.09.02 [v6.8.1]

Added air package
Android: Removed logging output from wasAutoStarted function (resolves #224)
Android: Added new method for auto start on Android 30 (including new permission access) (resolves #222)
Android: Corrected behaviour of status bar light / dark on Android 30 (resolves #225)
Android: Security flags on activities (resolves #214)
Corrected documentation on DefaultsEvent.CHANGED event on iOS (resolves #212)

2021.08.05 [v6.7.7]

Corrected tvOS implementation (issue with set brightness integration)

2021.07.01 [v6.7.4]

Added screen brightness implementation

2021.06.09 [v6.6.003]

Updated ios device definitions and clarified documentation for year class and device information (resolves #218)

2021.03.22 [v6.5.056]

Added better alarm handling when app active

2021.03.16 [v6.5.051]

Removed ios_version_min

2020.12.11 [v6.5.049]

Updated docs

2020.12.11 [v6.5.049]

Updated docs

2020.12.11 [v6.5.049]

Android: Added ability to show keyboard manually (resolves #206)
Android: Added ability to retrieve the automatic time and time zone (resolves #207)

2020.09.11 [v6.4.021]

Added Android x64 support (resolves #201)

2020.09.08 [v6.3.019]

Added changed event to default fallback implementation (resolves #198)

2020.08.12 [v6.3.017]

Updated iOS device definitions with new 2020 iPads and iPhone SE (resolves #196)

2020.07.23 [v6.3.015]

Android: Added access to getExternalFilesDir important for external storage on API 29

2020.06.09 [v6.2.010]

Updated iOS device list with recent devices

2020.04.15 [v6.1.008]

iOS: Added nativeScale for detecting zoomed state (resolves #116)

2020.03.26 [v6.0.006]

Updated documentation

2020.03.24 [v6.0.006]

Android X migration (resolves #177)

2020.03.12 [v5.1.469]

iOS: Corrected issue with status bar and dark mode on iOS 13 (resolves #176)

2019.11.22 [v5.1.465]

Updated docs

2019.11.22 [v5.1.465]

Dark Mode detection - retrieve user interface style 
Android: Additional checks for display related crash (#165)

2019.11.02 [v5.0.453]

iOS: Updated device database to support latest iPhone devices (resolves #166)

2019.10.03 [v5.0.452]

Updated docs

2019.10.02 [v5.0.452]

Android: Fix for keyboard info on some devices running Android 4.3
Android: Resolved keyboard monitor crash (resolves #158)

2019.09.06 [v5.0.439]

Updated docs

2019.09.06 [v5.0.439]

Android 64bit support (resolves #149)

Added information about display cutouts (notches) (resolves #138, resolves #120)

Added Keyboard information
- heights (resolves #11)
- activation events (resolves #74)

Android: Added helper for back button issue with android target sdk 28+ (resolves #153)
Android: Fixed issue with black screen helper (resolves #130)
Android: Added function to determine if app was auto launched (resolves #23)
Android: Added ability to set navigation bar colour + style
Android: Added ability to control system ui visibility flags (resolves #150)
iOS: Updated iOS device list
Updated minimum iOS version to 9.0

2019.03.17 [v4.7.182]

Updated documentation on auto start and alarm manager

2019.03.12 [v4.7.180]

Updated minimum iOS version to 8.0 (resolves #137)
Updated Status Bar styles and added Android support (resolves #136)

2019.02.18 [v4.6.173]

Added time zone information (resolves #131)

2019.02.11 [v4.5.167]

Added Locale information
Embedded bitcode

2018.10.20 [v4.4.159]

iOS: Updated device definitions for latest Apple iPhone devices (resolves #123

2018.08.09 [v4.4.150]

Added yearClass device information for performance decisions (resolves #115)
Updated iOS device information database

2018.06.29 [v4.3.141]

Android: Removed initial dispatch of foreground application state event (resolves #110)

2018.06.26 [v4.3.139]

Android: Added checks around system ui visibility changes (#109)

2018.06.20 [v4.3.138]

Android: Fixed crash with lifecycle listener (resolves #108)

2018.06.20 [v4.3.137]

Updated example to show authorisation

2018.04.04 [v4.3.130]

Additional state checks to avoid Android crashes (#103)

2018.03.12 [v4.3.122]

Added Power Save mode detection and idle mode on Android (resolves #96)

2018.03.11 [v4.3.110]

Added Apple tvOS implementation 
Added better ApplicationStateEvents for application foreground / background rather than activate / deactivate (resolves #94)

2018.03.03 [v4.2.058]

Corrected return values for device display metrics on latest iOS devices

2017.11.15 [v4.2.054]

Fixed issue with defaults setString and getString

2017.11.10 [v4.2.052]

Fixed issue with default values of settings on Android (resolves #89)

2017.09.22 [v4.2.049]

iOS 7 crash on launch fix

2017.08.17 [v4.1.041]

Updated missing functionality from default lib

2017.08.11 [v4.0.038]

Added Keychain iOS implementation (resolves #75)
Added Settings implementation (resolves #76)
Updated iOS model names to better represent actual devices (resolves #77)

2017.07.10 [v3.4.006]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.04.28 [v3.4.004]

Fixed lockstate rejection issue (resolves #68)

2017.04.03 [v3.3.009]

Updated documentation

2017.04.03 [v3.3.009]

Added ability to add AIR bitmap overlay (resolves #67)
Added Accessibility options to get access to the voice over state
Android: Added the blackScreenHelper function

2016.12.22 [v3.2.007]

Updating documentation

2016.12.22 [v3.2.007]

Updating documentation

2016.12.15 [v3.2.007]

Added Defaults getObject to read dictionary values (#55)
Added Device Orientation Events to get orientation changes irrespective of UI lock

2016.12.09 [v3.1.013]

Added display metrics for accurate dpi (resolves #57)
Android: Fix for black screen on lock screen (resolves #53)

2016.11.23 [v3.0.031]

Added alarm manager cancel all and cancel by id (#52)

2016.11.22 [v3.0.029]

Added the cancelAlarm functionality (resolves #52)

2016.10.24 [v3.0.024]

Corrected default implementation (#47)

2016.10.24 [v3.0.023]

Added getStatusBarHeight to default implementation (resolves #47)

2016.10.22 [v3.0.022]

Added getFilesDir for lookup of system directory (resolves #46)

2016.09.30 [v3.0.020]

Android: Alarm will now attempt to unlock device, or run in front of lock screen (resolves #44)

2016.09.28 [v3.0.019]

Added wiki documentation

2016.09.28 [v3.0.019]

Added wiki documentation

2016.09.28 [v3.0.019]

Added wiki documentation

2016.09.28 [v3.0.019]

Added wiki documentation

2016.08.25 [v3.0.019]

iOS: Corrected persistent device id (resolves #39)

2016.08.24 [v3.0.016]

Android: Added access to the AlarmManager to set device alarms
Added getStatusBarHeight function (resolves #37)
iOS: Corrected persistent id to not restore on different devices (resolves #38)

2016.08.03

Updated Core library compatibility

2016.08.01

Android: Added ability to set the alpha of the status bar (resolves #36)
Android: Added new display mode to work with semi-transparent status bar

2016.07.05

Android: Changed os.version to be the version string (6.0.1) and added the api_level field (resolves #31)

2016.07.02

Expanded defaults implementation to use SharedPreferences on Android and SharedObject on unsupported platforms (resolves #30)

2016.04.27

Android: Added IMMERSIVE display mode (resolves #28)

2016.04.05

Corrected setStatusBarColour and device properties on Android 6.0 (resolves #25)

2016.03.16

Added access to the device phone number on Android (resolves #21)

2016.02.01

iOS: Added persistent ID storage in the Keychain (resolves #19)

2016.01.28

Fixed issue with ACTIVATE / DEACTIVATE events when not supported (resolves #18)
Android: Add Android Status bar colour (resolves #14)

2015.10.06

Updated documentation (resolves #13)

2015.07.13

Android: Implemented the checkUrlSchemeSupport function

2015.06.15

Added information about the device such as OS version, device name  
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: Changed name of resource folder to avoid conflicts
Android: x86 Support

2015.02.12

Changed class structure to support FlashBuilder 4.6

2015.01.31

Added check for .debug suffix in application id

2014.12.22

iOS: Fixed crash on deactivation due to lock/home check (resolves #3)

2014.12.17

iOS: Included arm64 support (resolves #2) 
Android: Corrected application id check when doesn't contain air prefix (resolves #1)

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.11.26

Updated README with correct links

2014.11.26

New application based key check, removing server checks

2014.10.22

iOS Update for iOS 8
- + \ No newline at end of file diff --git a/docs/application/defaults/index.html b/docs/application/defaults/index.html index 792a31af785..8519d58624c 100644 --- a/docs/application/defaults/index.html +++ b/docs/application/defaults/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ personalisation settings and other user data sharing requirements.

When you need access to these values we suggest changing the behaviour to use the shared values by setting the value of useSharedDefaults to true:

Application.service.defaults.useSharedDefaults = true;
note

You will not be able to access values that were stored when this value is changed, i.e. if you have previously saved values in the custom object, and then change to the shared object, they will no longer be available.

You can change this value as you require before accessing values, however be aware that changing this value does dispose and create objects so will have a performance hit if you do this regularly.

We suggest moving to one consistent method to avoid switching methods.

Access

You access the defaults functionality through the defaults accessor, eg:

Application.service.defaults.getString( "key" );

Setting and Retrieving Values

Values can be stored in a series of basic types, including:

String Values

String values are retrieved by using the getString() function specifying the key of the value you wish to retrieve.

For example, say you are storing a "nick name" for a user:

trace( "Nickname = " + Application.service.defaults.getString( "nick_name" ) );

You set a string value by using the setString() function specifying the key and the new value you wish to set.

For example:

Application.service.defaults.setString( "nick_name", "My Nick Name" );

Boolean Values

Boolean values are set and retrieved using the setBoolean and getBoolean functions respectively.

For example:

Application.service.defaults.setBoolean( "firstRun", false );

And to retrieve:

var firstRun:Boolean = Application.service.defaults.getBoolean( "firstRun" );

Number Values

Number values are set and retrieved using the setNumber and getNumber functions respectively.

For example:

Application.service.defaults.setNumber( "progress", 0.36 );

And to retrieve:

var progress:Number = Application.service.defaults.getNumber( "progress" );

int Values

Integer values are set and retrieved using the setInt and getInt functions respectively.

For example:

Application.service.defaults.setInt( "count", 17 );

And to retrieve:

var count:int = Application.service.defaults.getInt( "count" );

Object Values

Object values are set and retrieved using the setObject and getObject functions respectively. Objects can only contain primitive types as they are internally encoded as JSON objects for storage.

For example to set an object with a few properties:

var value:Object = {
test: "some string",
number: 3
};

Application.service.defaults.setObject( "test.object", value );

And to retrieve:

var value:Object = Application.service.defaults.getObject( "test.object" );
if (value != null)
{
trace( "get object : " + value.test + ":"+value.number );
}

A null value will be returned if there is no value set for the specified key.

Removing a Value

To remove a value you can call the remove() function and specify the key of the value you wish to remove.

Application.service.defaults.remove( "nick_name" );

Once you call this the value will no longer be set in the user's defaults and any attempts to retrieve it will return invalid data.

Saving

The values are saved periodically automatically, however if you wish to force any caching to be written to permanent storage you can call the save() function whenever needed.

Application.service.defaults.save();

This function is useful after you have updated a series of default values or set some initialisation data on first run of your application but is not necessary.

Changed Event

Whenever a default value is changed a DefaultsEvent.CHANGED will be dispatched and will contain the key of the value that changed.

note

iOS does not give information on the key that was changed only that the defaults have changed so the key will always be empty on iOS

Application.service.defaults.addEventListener( DefaultsEvent.CHANGED, defaults_changedHandler );

function defaults_changedHandler( event:DefaultsEvent ):void
{
trace( "defaults_changedHandler(): " + event.key );
}
info

The changed event will be fired whenever a value is changed in the underlying storage medium. Some platforms have crossover with other features so the changed event may not only be dispatched for changes through the defaults functionality.

For example, this can happen when values are changed through the settings functionality in this extension as both these features use the same underlying Preferences functionality.

You may also notice values that our extensions store for state information, so you should be aware only to respond to change events for keys that you are aware of.

- + \ No newline at end of file diff --git a/docs/application/device-information/accessibility/index.html b/docs/application/device-information/accessibility/index.html index 3895fb43384..ea733b5c6dd 100644 --- a/docs/application/device-information/accessibility/index.html +++ b/docs/application/device-information/accessibility/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ for the blind and sight impaired. It uses combination of interactions to speak what is currently on the screen.

While this is helpful for purely native applications this generally results in a poor user experience for Adobe AIR applications.

To check if voice over is enabled:

var voiceOverEnabled:Boolean = Application.service.accessibility.voiceOverEnabled;

This indicates that the following services are enabled:

You can use this to change your UI accordingly or even limit the operation of your application.

iOS: VoiceOver

To enable VoiceOver on iOS:

Android: TalkBack

To enable TalkBack on Android:

- + \ No newline at end of file diff --git a/docs/application/device-information/device-state/index.html b/docs/application/device-information/device-state/index.html index 5f8ab2c5aaf..217cfa9d212 100644 --- a/docs/application/device-information/device-state/index.html +++ b/docs/application/device-information/device-state/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Device State

Power Save Mode

Recent releases of both iOS and Android have introduced a "power save mode" where applications should reduce their functionality in order to conserve battery as much as possible.

You can determine if the power save mode is active with the isPowerSaveMode() function, which returns true if the power save mode is currently active.

var powerSaveMode:Boolean = Application.service.device.isPowerSaveMode();

You can monitor changes of this state by listening for the DeviceStateEvent.POWER_SAVE_MODE_CHANGED event:

Application.service.device.addEventListener( DeviceStateEvent.POWER_SAVE_MODE_CHANGED, deviceStateEventHandler );

function deviceStateEventHandler( event:DeviceStateEvent ):void
{
// power save mode changed
}
AndroidiOS

Idle Mode

The idle mode indicates when a device has been sitting unused and unmoving for a sufficiently long period of time, so that it decides to go into a lower power-use state. This may involve things like turning off network access to apps.

Currently the idle mode is only support on Android.

You can detect this with the isDeviceIdleMode() function, which returns true if the device is currently in idle mode.

var idleMode:Boolean = Application.service.device.isDeviceIdleMode();

You can monitor changes of this state by listening for the DeviceStateEvent.IDLE_MODE_CHANGED event:

Application.service.device.addEventListener( DeviceStateEvent.IDLE_MODE_CHANGED, deviceStateEventHandler );

function deviceStateEventHandler( event:DeviceStateEvent ):void
{
// idle mode changed
}

Testing

You can use the adb command line to test the changing of this state.

Using the following will send the device into the idle state:

adb shell dumpsys deviceidle force-idle

Using the following will bring the device out of the idle state:

adb shell dumpsys deviceidle step

Each of these commands should trigger the dispatch of the DeviceStateEvent.IDLE_MODE_CHANGED.

- + \ No newline at end of file diff --git a/docs/application/device-information/device/index.html b/docs/application/device-information/device/index.html index a2091ae1ba3..9c1581832ba 100644 --- a/docs/application/device-information/device/index.html +++ b/docs/application/device-information/device/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Device Information

Device functionality allows you to retrieve information about the device.

Device information

There are many pieces of information available through the Device interface that allow you to determine what device you are currently running on, including things like the operating system version and the device model.

  • name : The name of the device, generally this is a user set name for their device, eg My iPhone;
  • brand : The consumer-visible brand with which the product/hardware will be associated, if any, eg Apple;
  • manufacturer : The manufacturer of the product/hardware, eg Apple ;
  • device : The device type, ie. a simple name for the device eg iPhone;
  • model : The end-user-visible name for the end product eg iPhone 11;
  • product : The name of the overall product hardware, eg iPhone12,1;

For example, the following on an iPhone 11

trace( "DEVICE INFO ============================" );
trace( " name: " + Application.service.device.name );
trace( " brand: " + Application.service.device.brand );
trace( " manufacturer: " + Application.service.device.manufacturer );
trace( " device: " + Application.service.device.device );
trace( " model: " + Application.service.device.model );
trace( " product: " + Application.service.device.product );

will output:

DEVICE INFO ============================
name: My iPhone
brand: Apple
manufacturer: Apple
device: iPhone
model: iPhone 11
product: iPhone12,1

Locale

The device locale settings can be retrieved through the locale accessor:

var locale:Locale = Application.service.device.locale

This object contains information about the device locale:

  • locale.country: The country/region code for this locale, which should either be the empty string, an uppercase ISO 3166 2-letter code, or a UN M.49 3-digit code;
  • locale.language: The language code of this Locale, or the empty string if none is defined

Paths

The functionality also includes some access to some system dependant paths, such as the getFilesDir() and getExternalFilesDir() on Android.

trace( "PATHS ==================================" );
trace( "files dir: " + Application.service.device.getFilesDir() );
trace( "ext files dir: " + Application.service.device.getExternalFilesDir() );

The returned values are native paths to common storage locations for Android applications. Generally no additional file permissions are required to read and write to these locations.

Time Zone

You can access information about the current system time zone on the device using the localTimeZone accessor:

var timezone:TimeZone = Application.service.device.localTimeZone;

The TimeZone class represents a time zone offset indicating the standard time policies for a geopolitical region.

Time zones have identifiers like "America/Los_Angeles" which can be accessed through the id property:

var timezoneId:String = Application.service.device.localTimeZone.id;

You can also access the offset from UTC using the utcOffset property. This gives you the amount of time in milliseconds to add to UTC to get standard time in this time zone.

var utcOffset:Number = Application.service.device.localTimeZone.utcOffset;

Automatic Time

You can check whether the user has enabled automatic time / time zone settings on their device using the isAutoTimeEnabled() and the isAutoTimeZoneEnabled().

var autoTime:Boolean = Application.service.device.isAutoTimeEnabled();

This can be useful if you are attempting to check the accuracy of the time on the device (for example, to check if the user is attempting to cheat some time based operations in your game or app).

Available on Android only.

These will return false on all unsupported platforms.

Year Class

Year Class

Phone Number

Phone Number

Operating system

Operating System

Device State

Device State

Device Orientation

Device Orientation

- + \ No newline at end of file diff --git a/docs/application/device-information/operating-system/index.html b/docs/application/device-information/operating-system/index.html index c8ed69788f8..61ee35585d6 100644 --- a/docs/application/device-information/operating-system/index.html +++ b/docs/application/device-information/operating-system/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Operating System

You can also use the device functionality to retrieve information about the operating system running on the device. This includes information such as the name and version of the OS.

This allows you to customise your application based on the simpler operating system
rather than particular device models or manufacturers.

trace( "OPERATING SYSTEM =======================" );
trace( " name: " + Application.service.device.os.name );
trace( " type: " + Application.service.device.os.type );
trace( " version: " + Application.service.device.os.version );
trace( " API Level: " + Application.service.device.os.api_level );
- + \ No newline at end of file diff --git a/docs/application/device-information/orientation-events/index.html b/docs/application/device-information/orientation-events/index.html index 1f08992d242..bf127136851 100644 --- a/docs/application/device-information/orientation-events/index.html +++ b/docs/application/device-information/orientation-events/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Orientation Events

The orientation of the device is sometimes important to applications, irrespective of the orientation of the UI. The DeviceOrientationEvent will give you information about the orientation of the device even if your UI doesn't change.

This can be useful in situations when you have locked your UI to an aspect ratio but still want to react to the user rotating their device.

Accessing the current orientation

You can access the current orientation of the device by checking the deviceOrientation flag of the device instance:

var currentOrientation:String = Application.service.device.deviceOrientation;

This will return one of the DeviceOrientation constants.

Note: The DeviceOrientation.UNKNOWN orientation will be returned if the device is flat on a desk ie. when there is no distinct orientation of the device.

Listening for orientation changes

Listening for changes is as simple as adding a listener for the DeviceOrientationEvent.CHANGED event.

Application.service.device.addEventListener( DeviceOrientationEvent.CHANGED, orientationChangedHandler );

Then in your event handler you can respond to the orientation change appropriately:

private function orientationChangedHandler( event:DeviceOrientationEvent ):void
{
trace( "orientationChangedHandler(): " + event.orientation );
switch (event.orientation)
{
case DeviceOrientation.DEFAULT:
case DeviceOrientation.UPSIDE_DOWN:
case DeviceOrientation.ROTATED_LEFT:
case DeviceOrientation.ROTATED_RIGHT:
break;
}
}

Starting orientation events

By default orientation events are not dispatched. This is due to a small amount of monitoring that is required to detect these changes.

To start generating orientation events you must call the startGeneratingDeviceOrientationEvents function:

Application.service.device.startGeneratingDeviceOrientationEvents();

Conversely if you wish to stop the events you can call stopGeneratingDeviceOrientationEvents:

Application.service.device.stopGeneratingDeviceOrientationEvents();
- + \ No newline at end of file diff --git a/docs/application/device-information/phone-number/index.html b/docs/application/device-information/phone-number/index.html index 3ec828f6f9b..1724fa52397 100644 --- a/docs/application/device-information/phone-number/index.html +++ b/docs/application/device-information/phone-number/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Phone Number

If you require access to the user's phone number you will need to request permission to access the phone state.

Android

Add the android.permission.READ_PHONE_STATE permission to your manifest additions:

<manifest android:installLocation="auto">

<uses-sdk android:targetSdkVersion="29" />

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<!-- OTHER MANIFEST ENTRIES -->

and then request permission to access it on recent versions:

switch (Application.service.authorisationStatus())
{
case AuthorisationStatus.AUTHORISED:
{
// User has granted access
break;
}

case AuthorisationStatus.NOT_DETERMINED:
case AuthorisationStatus.SHOULD_EXPLAIN:
{
Application.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
Application.service.requestAccess();
break;
}

case AuthorisationStatus.DENIED:
{
// User has denied access
break;
}
}

function authorisationChangedHandler( event:AuthorisationEvent ):void
{
// check authorisation status again
}

iOS

Not supported

- + \ No newline at end of file diff --git a/docs/application/device-information/unique-device-id/index.html b/docs/application/device-information/unique-device-id/index.html index 39a484946e0..2f187e427dd 100644 --- a/docs/application/device-information/unique-device-id/index.html +++ b/docs/application/device-information/unique-device-id/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Unique Device ID

Retrieving a Unique Device ID

Retrieving a Unique Device ID is as simple as calling the uniqueId() function:

Application.init( APPLICATION_KEY );
if (Application.isSupported)
{
var uniqueId:String = Application.service.device.uniqueId();
}

Android

On Android the ID is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device, The value may change if a factory reset is performed on the device. It will be the same for all application independent of the developer.

iOS

On iOS the value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them.

If you wish the value to persist beyond installations you should set the persistent parameter to be true. This will store the first generated value of the id in the user's keychain which will persist if the application is uninstalled.

- + \ No newline at end of file diff --git a/docs/application/device-information/year-class/index.html b/docs/application/device-information/year-class/index.html index cc35aea9c53..bf4a2498f65 100644 --- a/docs/application/device-information/year-class/index.html +++ b/docs/application/device-information/year-class/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Year Class

The current Android device list has around more than 10k different handsets. So it's hard to know how your application will perform on different devices. All having different amount of RAM, CPU speed, number of cores etc.

The year class is an attempt to categorise the device by placing it in a year where the device specifications would have placed it alongside the high-end devices. This allows you to easily modify the behavior of your application according the capabilities of the phone’s hardware. It is not neccessarily the year of manufacture or release of the device.

To retrieve this value use the yearClass property on the Device instance:

var year:int = Application.service.device.yearClass;
info

If the extension cannot determine the year of the device -1 will be returned. Generally this indicates that the device is newer than our algorithm allows for, so you can use your top performance level, however you may choose to use other methods to determine it yourself.

You can use this property to make decisions on the performance to attempt in your application, for example:

if (year >= 2018) 
{
// Do advanced animation
}
else if (year > 2015)
{
// Do simple animation
}
else if (year == -1)
{
// Could not determine year - assume very recent
}
else
{
// Phone too slow, don't do any animations
}

Implementation

On Android this uses the "Device Year Class" provided by Facebook: https://github.com/facebook/device-year-class

On iOS this returns the year of release as Apple devices generally are high-end when released.

- + \ No newline at end of file diff --git a/docs/application/display/cutouts/index.html b/docs/application/display/cutouts/index.html index 112ae553237..6f58a6cad51 100644 --- a/docs/application/display/cutouts/index.html +++ b/docs/application/display/cutouts/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Cutouts

A display cutout (or notch) is an area on some devices that extends into the display surface to allow for an edge-to-edge experience while providing space for important sensors on the front of the device.

When dealing with display cutouts the display mode and layout mode affect greatly how the cutouts affect your application. So it's important that you have set the display mode before attempting to deal with cutouts. The information returned here will change based on the display mode.

Support

Android officially supports display cutouts on devices running Android 9 (API level 28) and higher.

iOS supports notches from iOS 11.

Affected

The first check you will want to perform is to determine whether the device's display cutout will affect your view.

This will enable you to determine whether you will need to adjust your applications UI to account for the cutout.

if (Application.service.display.willCutoutAffectView)
{
// The current view is affected by a display cutout
}

Display Cutout

You can then retrieve information about the cutout by calling getDisplayCutout():

var cutout:DisplayCutout = Application.service.display.getDisplayCutout();

The DisplayCutout class represents the cutouts of the device. It represents the area of the application view that is not functional for displaying content.

This contains the safe distance from each edge of the device that can be used to display content relative to the current orientation.

For example in portrait, cutout.safeInsetTop will represent the height of any cutout at the top of the device. This will account not only for notches but also some devices with curved corners and the iOS controls bar.

The image below represents the safe area for an iPhone X landscape device, note the area on the right is to keep the controls out of the curved corners and symmetric on the device:

Apple has some good guidelines on usage of the safe insets:

Inset essential content to prevent clipping. In general, content should be centered and symmetrically inset so it looks great in any orientation, isn’t clipped by rounded corners, isn’t hidden by a sensor housing, and isn’t obscured by the indicator for accessing the Home screen.

We recommend you should present any UI controls inside the safe insets. You can (and should) draw outside these regions though.

Bounding Rectangles

On Android we can provide detailed information about the cutouts in the form of "bounding rectangles" of the content area affected by the cutout.

The DisplayCutout class has a property boundingRects which is a list of Rectangle objects each of which is the bounding rectangle for a non-functional area on the display. There will be at most one non-functional area per edge of the device.

var displayCutout:DisplayCutout = Application.service.display.getDisplayCutout();
for each (var rect:Rectangle in displayCutout.boundingRects)
{
// rect represents an area of the screen affected by a cutout
}

Testing

Be sure to test all of your app's screens and experiences. Test on devices with different types of cutouts, if possible.

Android

If you don't have a device with a cutout, you can simulate some common cutout configurations on any device or emulator running Android 9 by doing the following:

  1. Enable developer options.
  2. In the Developer options screen, scroll down to the Drawing section, and select Simulate a display with a cutout.
  3. Select the cutout type.

- + \ No newline at end of file diff --git a/docs/application/display/dark-mode/index.html b/docs/application/display/dark-mode/index.html index 47995b01a93..c5163d89be0 100644 --- a/docs/application/display/dark-mode/index.html +++ b/docs/application/display/dark-mode/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Dark Mode

User Interface Style - Dark Mode

iOS 13 and Android 10 introduced the concept of a "dark mode" for applications. This allowed a user to set a flag to request a "dark mode" be used wherever possible in applications. In this mode applications replace a normal light background and dark text with a dark background and light text.

To check if the user's requested display mode you can check the value of the userInterfaceStyle property:

var style:String = Application.service.display.userInterfaceStyle;

This will be one of the values defined in the UserInterfaceStyle class:

  • UserInterfaceStyle.DARK : Dark mode is enabled and the application should render with a dark background and light text;
  • UserInterfaceStyle.LIGHT : Dark mode is disabled and the application should render with the default light background and dark text;

You should switch your UI colours accordingly.

iOS

In order for your application to support dark mode on iOS it must be linked against version 13 or higher of the iOS SDK. If you don't the application will default to "light" mode and ignore the user settings.

Opt Out of Dark Mode Entirely

The system automatically opts in any app linked against the iOS 13.0 or later SDK to both light and dark appearances. If you need extra time to work on your app's Dark Mode support, you can temporarily opt out by including the UIUserInterfaceStyle key (with a value of Light) in your app’s info additions node in your application descriptor. Setting this key to Light causes the system to ignore the user's preference and always apply a light appearance to your app.

<key>UIUserInterfaceStyle</key>
<string>Light</string>

Important

Supporting Dark Mode is strongly encouraged. Use the UIUserInterfaceStyle key to opt out only temporarily while you work on improvements to your app's Dark Mode support.

Android

Dark mode should be supported on any device running Android API v29 or higher.

- + \ No newline at end of file diff --git a/docs/application/display/display-metrics/index.html b/docs/application/display/display-metrics/index.html index f889c487271..60ce751d2e8 100644 --- a/docs/application/display/display-metrics/index.html +++ b/docs/application/display/display-metrics/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Display Metrics

This allows you to get information about the display on the current device.

The densityDpi value is the 'bucket' DPI which is useful for scaling your UI.

The more accurate values are the xdpi and ydpi which provide the actual x and y dpi for the device.

The screenHeight and screenWidth represent the fullscreen pixel height and width of the device.

trace( "DISPLAY METRICS ========================" );
trace( "densityDpi: " + Application.service.display.displayMetrics.densityDpi );
trace( "screenHeight: " + Application.service.display.displayMetrics.screenHeight );
trace( "screenWidth: " + Application.service.display.displayMetrics.screenWidth );
trace( "xdpi: " + Application.service.display.displayMetrics.xdpi );
trace( "ydpi: " + Application.service.display.displayMetrics.ydpi );
trace( "nativeScale: " + Application.service.display.displayMetrics.nativeScale );

These values are taken from the underlying APIs, in particular:

The iOS screen density is determined from a lookup and is not provided by the API.

Native Scale

The nativeScale property is only valid on iOS.

This value reflects the scale factor needed to convert from the default logical coordinate space into the device coordinate space of this screen. The default logical coordinate space is measured using points. For Retina displays, the scale factor may be 3.0 or 2.0 and one point can represented by nine or four pixels, respectively. For standard-resolution displays, the scale factor is 1.0 and one point equals one pixel.

This native scale property will change on an iOS device if the screen is put into it's "zoomed" display state and knowing this value can allow you to react accordingly.

- + \ No newline at end of file diff --git a/docs/application/display/index.html b/docs/application/display/index.html index a5a01b2db62..8a89c40e8cc 100644 --- a/docs/application/display/index.html +++ b/docs/application/display/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Display

This is only applicable to Android currently as these modes don't have an equivalent on iOS.

Display Modes

Display modes allows you to control how your application displays the user interface decorations such as the status bar and navigation bar.

There are several main display modes defined in the DisplayMode class:

  • DisplayMode.NORMAL: Shows both the status bar and navigation bar;
  • DisplayMode.FULLSCREEN: Shows the navigation bar and hides the status bar;
  • DisplayMode.IMMERSIVE: Hides both the status bar and navigation bar, the user can reveal them with a swipe.

In order to set the display mode, you use the Display class and call the setDisplayMode function:

Application.service.display.setDisplayMode( DisplayMode.FULLSCREEN );

IMPORTANT: You must set the fullscreen flag in your application descriptor to false in order to disable the AIR fullscreen mode and allow the native code to work correctly. Without this AIR will affect the display mode and keyboard information.

<initialWindow>
...
<fullScreen>false</fullScreen>
...

If you set this to true then we cannot guarantee the display modes will work correctly.

RECOMMENDED: We suggest you pass a reference to the stage through to the ANE to be able to control certain aspects of the stage automatically for you and to change the displayState automatically on unsupported platforms.

Application.service.setStage( yourStageInstance );

This is also useful to allow the ANE to control the stage display state on

Layout Modes

Modern devices are moving towards smaller bezels and larger aspect ratios. On these devices, display cutouts or "notches" are a popular way to achieve an edge-to-edge experience while providing space for important sensors on the front of the device.

We have two main options when displaying our content around cutouts, and how it will appear will depend on the display mode you are using.

  • LayoutMode.CUTOUT_SHORT_EDGES: The window is allowed to extend into the cutout areas;
  • LayoutMode.CUTOUT_NEVER: The window is never allowed to overlap with the cutout area;

To set the layout mode, pass the required mode as the second parameter to the setDisplayMode() function:

Application.service.display.setDisplayMode( DisplayMode.FULLSCREEN, LayoutMode.CUTOUT_SHORT_EDGES );

These modes mainly have an effect in fullscreen or immersive modes where the view has the potential of displaying around the cutout.

Eg The following screenshots so the differences when using the various modes:

Application.service.display.setDisplayMode( 
DisplayMode.NORMAL
);

Application.service.display.setDisplayMode( 
DisplayMode.FULLSCREEN,
LayoutMode.CUTOUT_NEVER
);

Application.service.display.setDisplayMode( 
DisplayMode.FULLSCREEN,
LayoutMode.CUTOUT_SHORT_EDGES
);

In order to render your content around the cutout see the documentation on getting information about the Cutouts.

Examples:

Application.service.display.setDisplayMode( 
DisplayMode.FULLSCREEN,
LayoutMode.CUTOUT_SHORT_EDGES
);

Application.service.display.setDisplayMode( 
DisplayMode.IMMERSIVE,
LayoutMode.CUTOUT_SHORT_EDGES
);

Aspect Ratios

As devices change in size we have seen a change in aspect ratios. You may encounter black letterboxing on some Android devices with your AIR application. For example, the following image is from a Google Pixel 3 XL with fullscreen flag:

In order to resolve this, simply add the following tag inside the application in your manifest additions of your application descriptor:

<meta-data android:name="android.max_aspect" android:value="2.5" />

This image still has a black area at the top due to the cutout.

To resolve this you will need to use the the methods above eg:

Application.service.display.setDisplayMode( 
DisplayMode.IMMERSIVE,
LayoutMode.CUTOUT_SHORT_EDGES
);

Ensure you place this within the application tag eg:

<android>
<manifestAdditions><![CDATA[
<manifest android:installLocation="auto">

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="28"/>

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application>
</application>

</manifest>
]]></manifestAdditions>
</android>
iOS

If you encounter this on iOS then most likely you are missing the launch storyboard or a "Default.png" matching the resolution of the device.


Migration from v4

Previously you called setDisplayMode on the main application with a value from the ApplicationDisplayModes class. This functionality has been deprecated as it was too cumbersome and we could not use it to cleanly handle cutouts.

To migrate to the new code is fairly simple, previously you would have set fullscreen through the following:

Application.service.setDisplayMode( ApplicationDisplayModes.FULLSCREEN );

This now becomes:

Application.service.display.setDisplayMode( DisplayMode.FULLSCREEN );

Brightness

You can set the screen brightness using the setBrightness() method. This method accepts a numeric value between 0 and 1, representing the percentage brightness from lowest brightness (0) to highest brightness (1).

Application.service.display.setBrightness( 0.4 );

Setting the brightness will attempt to set the system brightness levels on Android. This may present an authorisation dialog on certain versions of Android. If denied the brightness will only affect the current window and not the entire device.

You should add the following permission to your application:

<!-- To control the system screen brightness setting -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
- + \ No newline at end of file diff --git a/docs/application/display/soft-keyboard/index.html b/docs/application/display/soft-keyboard/index.html index 2a25712de06..476bc97b9d5 100644 --- a/docs/application/display/soft-keyboard/index.html +++ b/docs/application/display/soft-keyboard/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Soft Keyboard

Experimental

This functionality is a native implementation for getting access to the keyboard size and activation events.

In order to use this functionality on Android you must use this extension to set a display mode. If you don't set a display mode through this extension then the keyboard information may not be correct.

Application.service.display.setDisplayMode( DisplayMode.FULLSCREEN );

The keyboard functionality is accessed through the Keyboard interface, via Application.service.keyboard.

If you plan on using the keyboard functionality in your application, we suggest you call in the init() function on the Application.service.keyboard instance some time before attempting to access any of the functionality. This will initialise the internal listeners and ensure you have a valid initial state.

Application.service.keyboard.init();

You can do this alongside your display mode, eg :

Application.service.display.setDisplayMode( DisplayMode.FULLSCREEN );
Application.service.keyboard.init();

Keyboard Information

Keyboard Size

You can access the position and size of the keyboard through the interface accessors:

var keyboardY:int = Application.service.keyboard.y;
var keyboardHeight:int = Application.service.keyboard.height;

These values are in native pixel dimensions, so if you are using scaling you'll need to take that into account.

Activation events

You can get notified when the keyboard activates and deactivates through the flash.events.SofyKeyboardEvents:

Application.service.keyboard.addEventListener( SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, keyboard_activateHandler );
Application.service.keyboard.addEventListener( SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, keyboard_deactivateHandler );

These are global events and will be dispatched independent of the method that triggered the keyboard.

Android IMMERSIVE mode considerations

If you are using Android's immersive mode, you may wish to display the navigation bar when the keyboard appears. By default the navigation bar is always hidden in immersive mode, which will hide the default navigation controls even when the keyboard is displayed. This can easily be overcome with the following code in your keyboard activate and deactivate handlers:

function keyboard_activateHandler( event:SoftKeyboardEvent ):void
{
// Show the navigation bar
var visibility:int = Application.service.display.getSystemUiVisibility();
Application.service.display.setSystemUiVisibility(
visibility & ~AndroidSystemUiFlags.SYSTEM_UI_FLAG_HIDE_NAVIGATION
);
}

function keyboard_deactivateHandler( event:SoftKeyboardEvent ):void
{
// Return to previous display mode (will adjust navigation bar if required)
Application.service.display.setDisplayMode( DisplayMode.IMMERSIVE );
}

Show

Android only

On Android we can attempt to force show the keyboard. This can be useful in some scenarios where the keyboard fails to show in AIR, especially when changing focus between stage text input fields.

To show the keyboard, simply call show():

Application.service.keyboard.show();

Notes

If you call this while the keyboard is being shown, this may cause the keyboard to be hidden. This is due to the nature of the native call being a "toggle" more than a force show, so if we fail to detect that the keyboard has been triggered from a different source we may inadvertently trigger a toggle to hide the keyboard.

Related issues:

- + \ No newline at end of file diff --git a/docs/application/general-helpers/index.html b/docs/application/general-helpers/index.html index 844c753c1c3..40344b327b1 100644 --- a/docs/application/general-helpers/index.html +++ b/docs/application/general-helpers/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ ACTIVATE events will be fine.

We normally use a flag to only call it when an activate event was preceeded by a deactivate event, eg:

private var _deactivated:Boolean = false;

private function deactivateHandler( event:Event ):void
{
_deactivated = true;
}

private function activateHandler( event:Event ):void
{
if (_deactivated)
{
_deactivated = false;
Application.service.blackScreenHelper();
}
}

Starling Context Loss Overlay

This functionality gives you the ability to add a screenshot over the application while you rebuild a context loss or something similar.

The functionality simply allows you to add a bitmap overlay over the AIR application

overlay = Starling.current.stage.drawToBitmapData();

Application.service.addBitmapOverlay( overlay );

To remove the overlay:

Application.service.removeBitmapOverlay();

AIR Android SDK 28 Back Button

If you are using AIR 33 latest release or higher this issue has been fixed.

AIR for Android when targeting SDK 28 caused an issue where the back button Keyboard Event failed to be dispatched.

This affects AIR 32 and early releases of AIR 33 from Harman when setting the target SDK to 28.

<uses-sdk android:targetSdkVersion="28" />

This can be resolved by calling the following early in your application:

Application.service.backButtonHelper();

Then the back button event should dispatch correctly:

NativeApplication.nativeApplication.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );

function keyDownHandler( event:KeyboardEvent ):void
{
trace( event.keyCode );
if (event.keyCode == Keyboard.BACK)
{
event.preventDefault();
}
}
- + \ No newline at end of file diff --git a/docs/application/index.html b/docs/application/index.html index e709a8e6ca1..228e6b44aff 100644 --- a/docs/application/index.html +++ b/docs/application/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Application

The Application extension gives you access to some additional application options that aren't availble in the default AIR SDK.

The simple API allows you to quickly customise top level UI elements, such as status bars, in just a few lines of code. You can use the device information to identify a user, change UI based on operating system, determine device manufacturer and other device specific information. The user defaults can be used to save user settings in the native user databases, having all the advantages of using the native system for user settings.

Features:

  • Set the status bar colour on Android;
  • Set advanced display modes;
  • Customise your application based on the device information;
  • Auto start your application on Android boot;
  • Save defaults (simple data values) using:
    • SharedPreferences on Android;
    • NSUserDefaults on iOS/tvOS;
    • and SharedObject on unsupported platforms

This documentation forms the best source of detailed documentation for the extension along with the asdocs.

- + \ No newline at end of file diff --git a/docs/application/keychain/index.html b/docs/application/keychain/index.html index 06ed4a4794c..e545f9ef1d8 100644 --- a/docs/application/keychain/index.html +++ b/docs/application/keychain/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Keychain

The keychain functionality is similar to the defaults however this data is stored in the users keychain encrypted storage.

Data stored here will generally survive an application reinstallation so is useful for storing critical pieces of user information.

Data is stored as strings in key/value pairs.

Supported

To check if the keychain functionality is available on the current device you can use the isSupported flag:

if (Application.service.keychain.isSupported)
{
// Keychain functionality is supported
}

Set a value

To set a value call set with the key you wish to set and the value to associate:

Application.service.keychain.set( "key",  value );

Get a value

To retrieve a value, call get with the key of interest:

var value:String = Application.service.keychain.get(key);

Remove a value

If you wish to completely remove or delete a key/value pair, call remove with the key of interest:

Application.service.keychain.remove(key);
- + \ No newline at end of file diff --git a/docs/application/migrating-to-androidx/index.html b/docs/application/migrating-to-androidx/index.html index 654dd992d78..fd60c02da0c 100644 --- a/docs/application/migrating-to-androidx/index.html +++ b/docs/application/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

Manifest changes

This extension requires changes to the manifest additions for Android X.

Previously you may have had the following ProcessLifecycleOwnerInitializer provider in your manifest:

<!-- Add this for FOREGROUND / BACKGROUD events -->
<provider
android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="APPLICATION_PACKAGE.lifecycle-trojan"
android:exported="false"
android:multiprocess="true" />

It should be removed and changed to be the following (not the change both in the android:name and android:authorities attributes):

<!-- APPLICATION STATE EVENTS -->
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="APPLICATION_PACKAGE.lifecycle-process"
android:exported="false"
android:multiprocess="true" />

With the latest release this should now be:

<!-- APPLICATION STATE EVENTS -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="APPLICATION_PACKAGE.androidx-startup"
android:exported="false" >
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
</provider>
- + \ No newline at end of file diff --git a/docs/application/migrating-to-v6.12/index.html b/docs/application/migrating-to-v6.12/index.html index 1154bd06803..1a6e645f46f 100644 --- a/docs/application/migrating-to-v6.12/index.html +++ b/docs/application/migrating-to-v6.12/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v6.12

v6.12 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/application/settings/index.html b/docs/application/settings/index.html index 5a2905f717f..1473038e6d1 100644 --- a/docs/application/settings/index.html +++ b/docs/application/settings/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ the items to display in the settings screen.

Manifest Additions

In order to display the settings activity you need to add the SettingsActivity to your manifest:

<activity android:name="com.distriqt.extension.application.settings.SettingsActivity" android:label="Settings" />

You can change the label as you need for your application, it will be displayed at the top of the preferences panel.

Creating the Settings (Preferences) XML resource

To add resources to your application you will need to create a custom resources ANE. You can use the script and instructions here to create this ANE.

In the following we will go through the resources you will need to add to this ANE.

The following resource (res/xml/settings.xml) defines several settings :

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<EditTextPreference
android:key="name_preference"
android:title="Name"
android:summary="Your name"
android:defaultValue="default"/>

<SwitchPreference
android:key="enabled_preference"
android:title="Enabled"
android:summary="This is a checkbox enabled"/>

<ListPreference
android:key="multi_preference"
android:title="Multiple options"
android:defaultValue="1"
android:entries="@array/multi_preference_titles"
android:entryValues="@array/multi_preference_values" />

</PreferenceScreen>

The list uses values in the array values (res/values/array.xml) as below:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="multi_preference_titles">
<item>Option 1</item>
<item>Option 2</item>
<item>Option 3</item>
</string-array>
<string-array name="multi_preference_values">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>
- + \ No newline at end of file diff --git a/docs/application/status-bar/index.html b/docs/application/status-bar/index.html index 9e0640414fa..be92050c4f2 100644 --- a/docs/application/status-bar/index.html +++ b/docs/application/status-bar/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Status Bar

Status Bar

The status bar is the small area at the top of a device that contains information such as the battery level, network connectivity and notification icons.

Style

You can control the style of the status bar by using the Display.setStatusBarStyle() function. This allows you to set whether the content (icons, time etc) is light or dark, allowing you to better fit the status bar content with your application.

This function takes a StatusBarStyle constant as the parameter:

  • StatusBarStyle.LIGHT: Light (white) icons and status bar content
  • StatusBarStyle.DARK: Dark (black/grey) icons and status bar content
  • StatusBarStyle.DEFAULT: Differs between the platforms, is DARK on iOS and LIGHT on Android
Application.service.display.setStatusBarStyle( StatusBarStyle.LIGHT );

Please note the older styles defined in IOSStatusBarStyles have been deprecated in favour of the StatusBarStyle constants however the deprecated values will still work when passed into this function.

Hide

On iOS, you can hide the status bar by using the Display.setStatusBarHidden() function:

Application.service.display.setStatusBarHidden( false );

and display it again using:

Application.service.display.setStatusBarHidden( true );

Colour

On Android version 21 (Lollipop) and newer you can set the background colour of the status bar using the Display.setStatusBarColour() function.

The following example shows setting the colour to Red.

Application.service.display.setStatusBarColour( 0xFF0000 );

You can also control the transparency with the second parameter being the alpha value between 0 and 1.

Application.service.display.setStatusBarColour( 0xFF0000, 0.4 );

Height

If you need to know the height of the status bar in pixels you can use the getStatusBarHeight() function:

var statusBarHeight:int = Application.service.display.getStatusBarHeight();

Note: you may also need to consider the display cutout on modern devices.

Android contains a navigation bar towards the bottom of the screen, containing the back and menu buttons but varying depending on the version and manufacturer.

You can set the colour and style of using setNavigationBarColour() and setNavigationBarStyle() respectively.

To set the colour:

Application.service.display.setNavigationBarColour( 0xFF0000 );

To set the style, you must use one of the constants defined in NavigationBarStyle:

  • NavigationBarStyle.LIGHT: Light navigation bar style will make the icons light for use on dark backgrounds;
  • NavigationBarStyle.DARK: Dark navigation bar style will make the icons dark for use on light backgrounds
Application.service.display.setNavigationBarStyle( NavigationBarStyle.LIGHT );
- + \ No newline at end of file diff --git a/docs/applicationrater/add-the-extension/index.html b/docs/applicationrater/add-the-extension/index.html index 47fad7fcc57..684b965267c 100644 --- a/docs/applicationrater/add-the-extension/index.html +++ b/docs/applicationrater/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS/macOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ApplicationRater.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/applicationrater/add-the-plugin/index.html b/docs/applicationrater/add-the-plugin/index.html index 9c4b18cec2b..b7d272ff1e4 100644 --- a/docs/applicationrater/add-the-plugin/index.html +++ b/docs/applicationrater/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Add the Plugin

First step is always to add the plugin to your development environment.

Asset Store

Open the Asset Store in your browser and add the plugin to your assets.

Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

Manual Installation

In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.ApplicationRater.unitypackage.

You can manually download the extension from our repository:

Import the Plugin

This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

The plugin will be added to your project and you can now use the plugins functionality in your application.

Resolve Android Dependencies

This plugin depends on some common Android libraries, particularly the Google Play Core Library, which enables in-app reviews.

You can get these dependencies using one of the following methods.

Unity Jar Resolver

This is the suggested method.

Use the Unity Jar Resolver plugin to download and manage the Android dependencies.

Importing

If you already use the Unity Jar Resolver in your project you can skip this step.

  • Download the latest version of the Unity Jar Resolver
  • Import the plugin by selecting Assets / Import Package / Custom Package ... and locate the plugin you downloaded. The plugin will be in the zip named: external-dependency-manager-latest.unitypackage
  • In the Import Unity Package window, click Import

Resolving

By default, the resolver should run automatically and will add the dependencies required by this plugin.

If you have need to resolve the dependencies manually then you will need to:

  • Open the menu under: Assets / External Dependency Manager / Android Resolver
  • Select Resolve or Force Resolve

More information on the Unity Jar Resolver can be found here

Custom Gradle Template

Unity's in-built gradle build support and exporting to android studio does not support per plugin gradle script. Therefore, this plugin cannot add the dependencies by itself.

The mainTemplate.gradle is generated when you enable the Custom Gradle Template property on the Player window.

The build.gradle exists in generated Gradle project when you enable the Export Project property on the Player window and Build the project.

Update the dependencies section in your mainTemplate.gradle or build.gradle as below:

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

implementation 'com.google.android.play:core:1.9.1'
}
Proguard

If you are using a custom proguard configuration you may need to add the following line to ensure the interface class for the plugin is accessible to unity at runtime.

-keep class com.distriqt.extension.applicationrater.ApplicationRaterUnityPlugin {*;}

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ApplicationRater.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/applicationrater/application-id/index.html b/docs/applicationrater/application-id/index.html index 9e804ffaa27..60ed88cddf7 100644 --- a/docs/applicationrater/application-id/index.html +++ b/docs/applicationrater/application-id/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ the Google Play console to setup your application in the Play Store.

Additionally note if you are using the NO_ANDROID_FLAIR flag you will not have the air. prefix mentioned above.

The default value uses the value from the NativeApplication applicationId variable, preceeded by air. which should be the valid id for your Android application in the Google Play store.

iOS / tvOS / macOS

Under Apple the value is a little more complicated. It's the value of the Apple ID in your iTunes Connect application page. For example, the distriqt test application com.distriqt.test has an iOS Apple ID of 552872162.

It may be different for your macOS and iOS applications.

It can also be found in the iTunes App Store link URL which will be of the form https://itunes.apple.com/us/app/[APP_NAME]/id[APP_ID]

Automatic Setup

The extension can also automatically retrieve the appropriate application id's information for you. This is done using either information about the application package or querying the applicable store for information.

This will most likely not work for a test application, where you may not yet have a valid application store entry for your application.

To retrieve the id's automatically simply call the retrieveApplicationId() function.

An error could result if the application is not yet in the app store or if the current application id does not match the one in the store.

ApplicationRater.service.retrieveApplicationId();

This will dispatch an event when the id is determined:

  • ApplicationIDEvent.RETRIEVED: If the application id was retrieved correctly;
  • ApplicationIDEvent.ERROR: If the application could not be identified.

For example:

ApplicationRater.service.addEventListener( 
ApplicationIDEvent.RETRIEVED, retrievedHandler );
ApplicationRater.service.addEventListener(
ApplicationIDEvent.ERROR, errorHandler );
ApplicationRater.service.retrieveApplicationId();

function retrievedHandler( event:ApplicationIDEvent ):void
{
trace( event.applicationId );
}

function errorHandler( event:ApplicationIDEvent ):void
{
trace( "error: [" + event.errorCode + "] " + event.error )
}

Manual Setup

Manually setting the application id can be useful if you want to ensure the rating process is working during testing or other situations where you don't want to rely on the automatic retrieval.

You can call the setApplicationId() function multiple times with the platform string (and store if required) specifying the platform for the applicationId so you won't have to determine the OS to set the correct ID.

If you don't specify the platform then it is assumed you have determined to correct ID and it will overwrite any previous value.

You should pass the above id's to the extension as early as possible, preferably just after you initialise the extension as below:

ApplicationRater.service.setApplicationId( 
"air.com.distriqt.test", ApplicationRater.IMPLEMENTATION_ANDROID );
ApplicationRater.service.setApplicationId(
"XXXXXXXXX", ApplicationRater.IMPLEMENTATION_IOS );
ApplicationRater.service.setApplicationId(
"YYYYYYYYY", ApplicationRater.IMPLEMENTATION_MACOS );

Using Automatic and Manual

You can combine both these methods to provide a fallback in the cases where the automatic method fails especially for testing.

Doing the following will set the fallback application id's first and then attempt to correct them using the automatic method.

// Set the default / fallback
ApplicationRater.service.setApplicationId(
"air.com.distriqt.test", ApplicationRater.IMPLEMENTATION_ANDROID );
ApplicationRater.service.setApplicationId(
"XXXXXXXXX", ApplicationRater.IMPLEMENTATION_IOS );
ApplicationRater.service.setApplicationId(
"YYYYYYYYY", ApplicationRater.IMPLEMENTATION_MACOS );

// Attempt automatic retrieval
ApplicationRater.service.retrieveApplicationId();
- + \ No newline at end of file diff --git a/docs/applicationrater/application-rate-dialog---states/index.html b/docs/applicationrater/application-rate-dialog---states/index.html index b0728c0ec7b..92c3d6c7e22 100644 --- a/docs/applicationrater/application-rate-dialog---states/index.html +++ b/docs/applicationrater/application-rate-dialog---states/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Application Rate Dialog - States

There are several states that the service can be in:

  • ApplicationRater.STATE_MONITORING : monitoring the system for conditions to display the rate dialog
  • ApplicationRater.STATE_LATER : the user clicked on the "remind me later" button and the system will wait until the conditions have been met
  • ApplicationRater.STATE_DECLINED : the user declined to rate the application by clicking on the "decline" button
  • ApplicationRater.STATE_RATED : the user has clicked on the "rate" button. Nothing more will be done and this will be taken as the completed state
  • ApplicationRater.STATE_PROMPT : has prompted the user to rate the application, ie that the rate dialog has been displayed. This state is transitional and only while the dialog is being shown to the user.

You can access the current state by calling, state :

var state:String = ApplicationRater.service.state;

The particular states control how the hasMetConditions function processes the conditions and triggers the dialog.

  • In the STATE_DECLINED and STATE_RATED states, hasMetConditions will always return false;
  • In the STATE_MONITORING state, hasMetConditions will return based on the current set conditions;
  • In the STATE_LATER state the hasMetConditions function will return after the set reminder period has passed.
- + \ No newline at end of file diff --git a/docs/applicationrater/application-rate-dialog/index.html b/docs/applicationrater/application-rate-dialog/index.html index fc454c44cf7..db0e76aed54 100644 --- a/docs/applicationrater/application-rate-dialog/index.html +++ b/docs/applicationrater/application-rate-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ or significant user events) you should set this value to -1:

ApplicationRater.service.setDaysUntilPrompt( -1 );

The default value is 5.

User Significant Events

You can also enable the condition of significant user events. These could be events such as games completed or photos taken, and depends entirely on your application.

You can change the value of the number of events until prompt by using the setSignificantEventsUntilPrompt() function. By default these are disabled which you can acheive by setting the value to -1.

For example, to set the condition that after 5 events the dialog should be displayed:

ApplicationRater.service.setSignificantEventsUntilPrompt( 5 );

When you wish to log a significant event, simply call:

ApplicationRater.service.userDidSignificantEvent();

Require All Conditions

By default, if you have set multiple conditions then the first condition to be met will cause the rate dialog to be displayed, unless you have altered the requireAllConditions option.

When requireAllConditions is true then all of the conditions that you have set are required to have been met in order for the rate dialog to be presented.

For example, if you call setDaysUntilPrompt( 5 ), setting the days until prompt to be 5 and setLaunchesUntilPrompt( 5 ), setting the launches until prompt to be 5 as well then if requireAllConditions is:

Reminder Period

If a user presses the "Remind me later" button then the interval until the user is presented with the rate dialog again is controlled by the setTimeBeforeReminding function. This accepts a number of days and is from the date that the user pressed the "Remind me later" button.

For example, to remind a user one week later, set this value to 7:

ApplicationRater.service.setTimeBeforeReminding( 7 );
- + \ No newline at end of file diff --git a/docs/applicationrater/changelog/index.html b/docs/applicationrater/changelog/index.html index b4f22b04c27..42cd5293e4d 100644 --- a/docs/applicationrater/changelog/index.html +++ b/docs/applicationrater/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.06.13 [v6.3.2]

fix(android): add additional error checking when dispatching events to catch background app crash (#79)

2023.05.18 [v6.3.1]

fix(android): remove unused encryption code

2023.01.11 [v6.3.0]

feat(dialog): add ability to set the dialog theme (resolves #75)
feat(ios): remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #74)
feat(android): update to android-play v1.10.3

2022.11.16 [v6.2.0]

feat: add ability to use the Samsung Galaxy Store (resolves #73)

2022.02.02 [v6.1.3]

Add check for isSupported call on unsupported platforms (M1)
Update docs to use apm
Update air package dependencies

2021.09.09 [v6.1.0]

Added air package
Updated com.google.android.play dependency to 1.10.1

2021.07.19 [v6.0.12]

Removed ios minimum version flag

2021.03.15 [v6.0.011]

Updated docs on unity proguard usage and included proguard rules in plugin aar

2021.02.15 [v6.0.002]

Unity plugin release

2021.02.12 [v5.5.001]

Added macOS support including AppStore redirects and Review Controller (resolves #56)
Removed deprecated IOS10 variant

2021.01.13 [v5.4.012]

Added Huawei App Gallery support (resolves #49)
Deprecated wiki

2020.09.16 [v5.3.008]

Corrected issue with hasMetConditions and default params (-1) (resolves #48)

2020.08.25 [v5.2.001]

Implemented Google Play In-App Review

2020.04.02 [v5.1.016]

Added option to require all conditions before hasMetConditions returns true (resolves #45)

2020.03.23 [v5.0.012]

Android X migration (resolves #44)

2019.08.13 [v4.0.002]

Android 64bit update (resolves #40)
Updated minimum iOS version to 9.0

2019.04.18 [v3.5.080]

Android: Added error handling for missing app store application (#37)

2019.03.12 [v3.5.078]

Embedded iOS bitcode

2019.02.26 [v3.5.075]

Updated minimum iOS version to 8.0

2018.11.06 [v3.4.073]

Corrected dispatching of displayed event

2018.10.13 [v3.4.072]

Added null reference check for application launched date (#32)

2018.10.12 [v3.4.069]

Corrected issue with first run initialisation (#31)

2018.08.29 [v3.4.063]

Updated documentation

2018.08.29 [v3.4.062]

Apple TV implementation
iOS: Fixed crash when retrieving application id without network (resolves #28)
iOS: Migrated dialog to latest UIKit implementation

2017.11.07 [v3.3.043]

Updated documentation

2017.10.25 [v3.3.043]

Corrected iOS 11 review link
Created build without review controller (resolves #11, #13)
Added Amazon store support (resolves #14)
Added ability to retrieve the store the application was installed from
Added automatic application id retrieval:

2017.07.10 [v3.2.015]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.05.26 [v3.2.014]

Added iOS Review Controller (resolves #9)

2016.12.22 [v3.1.005]

Updating documentation

2016.12.01 [v3.1.004]

Updated documentation with new wiki

2016.10.05 [v3.1.003]

Updated Android dialog theme to device defaults

2015.06.15

iOS: Updated to latest common library
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: Changed name of resource folder to avoid conflicts
Android: x86 Support (resolves #2)

2015.02.12

Changed class structure to support FlashBuilder 4.6

2015.01.31

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.11.27

Updated README

2014.11.26

New application based key check, removing server checks

2014.10.22

iOS Update for iOS 8
- + \ No newline at end of file diff --git a/docs/applicationrater/handling-stores/index.html b/docs/applicationrater/handling-stores/index.html index 9784795eaa1..87f38714e15 100644 --- a/docs/applicationrater/handling-stores/index.html +++ b/docs/applicationrater/handling-stores/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Handling Stores

Retrieving the Store

You can retrieve the store that the application was installed through by using the getInstallerStore() function. This function will attempt to determine which store the application was installed through and return one of the following values:

  • STORE_GOOGLEPLAY: The application was installed from the Google Play Store;
  • STORE_AMAZON: The application was installed from the Amazon Store;
  • STORE_HUAWEI_APPGALLERY: The application was installed from the Huawei App Gallery;
  • STORE_SAMSUNG: The application was installed from the Samsung Galaxy Store;
  • STORE_APPSTORE: The application was installed from the Apple AppStore. This is the default for all iOS / macOS devices and will be returned on iOS / macOS whether the application was installed through the AppStore or not;
  • STORE_UNKNOWN: Returned if the store could not be determined. This will happen when your application wasn't installed through a store eg when testing on Android.

Example:

var store:String = ApplicationRater.service.getInstallerStore();

You can then use this value to set the appropriate application id if you use different application id's in different stores.

For example, say we have air.com.distriqt.test in the Google Play Store and air.com.distriqt.amazon in the Amazon store:

var store:String = ApplicationRater.service.getInstallerStore();
switch (store)
{
case ApplicationRater.STORE_AMAZON:
ApplicationRater.service.setApplicationId( "air.com.distriqt.amazon", ApplicationRater.IMPLEMENTATION_ANDROID );
break;

default:
case ApplicationRater.STORE_GOOGLEPLAY:
ApplicationRater.service.setApplicationId( "air.com.distriqt.test", ApplicationRater.IMPLEMENTATION_ANDROID );
break;

}
- + \ No newline at end of file diff --git a/docs/applicationrater/index.html b/docs/applicationrater/index.html index e7a5b4fcd82..f07a5ae0ee1 100644 --- a/docs/applicationrater/index.html +++ b/docs/applicationrater/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Application Rater

The Application Rater extension allows you to ask the user for feedback on your application by displaying a native dialog and asking them to rate your application in the appropriate application store. When the user agrees to rate your application they are taken to your applications page in the store.

It also allows you to control this process yourself and use the extension to correctly redirect to the appropriate store review page.

Additionally you can use the modern in-app review controllers allowing simple in-app ratings and reviews so your user never has to leave your application.

The simple API allows you to quickly integrate application rating in your AIR application in just a few lines of code. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

We provide complete guides to get you up and running with application ratings and reviews quickly and easily.

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Features

  • Native interface to ask a user to rate your application;
  • Range of conditions to automatically display the dialog;
  • Reminder code to ask the user to rate at a later point if the user clicked the "remind me later" option;
  • Customisable labels and conditions;
  • Direct link to appropriate stores review page;
  • Supports different Android stores including Amazon and Google Play;
  • In App Reviews using:
    • Google Play In-App Review, and;
    • Apple StoreKit Review Controller;

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

ApplicationRater.service.setApplicationId( "air.com.distriqt.test", ApplicationRater.IMPLEMENTATION_ANDROID );
ApplicationRater.service.setApplicationId( "552872162", ApplicationRater.IMPLEMENTATION_IOS );
ApplicationRater.service.setApplicationId( "552872162", ApplicationRater.IMPLEMENTATION_MACOS );
ApplicationRater.service.applicationLaunched();

More information here:

com.distriqt.ApplicationRater

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/applicationrater/requesting-review/index.html b/docs/applicationrater/requesting-review/index.html index f1b4cbb8e12..95e106cff8e 100644 --- a/docs/applicationrater/requesting-review/index.html +++ b/docs/applicationrater/requesting-review/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Requesting Review

If you don't wish to use the rate dialog you can use this extension to simply open the appropriate store page for your user to review your application.

You should still set the application id by one of the methods described in the Application ID section.

Once you have set the application id you can call rate() to direct the user to the appropriate place for them to rate and review your application.

ApplicationRater.service.rate();
- + \ No newline at end of file diff --git a/docs/applicationrater/review-controller/index.html b/docs/applicationrater/review-controller/index.html index 05f264600e5..3065acf00b3 100644 --- a/docs/applicationrater/review-controller/index.html +++ b/docs/applicationrater/review-controller/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Review Controller

The review controller allows you to gather user reviews inside your application without redirecting them to the store. This process generally does not give you feedback about whether a user wrote a review however it does give you the ability to simplify a review request, presenting the review screens directly in your application.

Apple

Apple introduced the "Store Review Controller" in iOS 10.3.

and in macOS 10.14:

Google

Google has made available the "In-App Review Activity" as part of the Play Core library running on Android v5.0 (API level 21) and higher that have the Google Play Store installed.

Availability

To check if this functionality is supported on the current device you can call isSupported as below:

if (ApplicationRater.service.review.isSupported)
{
// InApp Review is supported
}

Currently this is supported on iOS 10.3+, macOS 10.14+ and on Android 5.0+ (API 21+) through Google Play.

Note: this simply checks the operating system version and some basic requirements. It will not definitely report that your application was installed through an application store. If your application has multiple distribution avenues, make sure you use a method to check whether the application was installed via a store as well.

Requesting Review

To start the review process you call the requestReview() function. This function attempts to ask the user to rate or review your app, if appropriate.

if (ApplicationRater.service.review.isSupported)
{
ApplicationRater.service.review.requestReview();
}

Although you should call this method when it makes sense in the user experience flow of your app, the actual display of a rating/review request view is governed by App Store / Google Play policy and quotas and this logic is outside the control of the extension.

Because this method may or may not present any UI, it's not appropriate to call it in response to a button tap or other user action.

When to request

Follow these guidelines to help you decide when to request in-app reviews from users:

  • Trigger the in-app review flow after a user has experienced enough of your app or game to provide useful feedback.
  • Do not prompt the user excessively for a review. This approach helps minimize user frustration and limit API usage.
  • Your app should not ask the user any questions before or while presenting the rating button or card, including questions about their opinion (such as “Do you like the app?”) or predictive questions (such as “Would you rate this app 5 stars”).

Quotas

Limits are placed on when the UI will be displayed. This logic is dependent on the stores and outside the control of the developer.

iOS: The system automatically limits the display of the prompt to three occurrences per app within a 365-day period.

Android: Google Play enforces a quota on how often a user can be shown the review dialog.

Testing

Apple

With iOS and macOS while your app is still in development mode, a rating/review request view is always displayed so that you can test the user interface and experience. However, this method has no effect when you call it in an app that you distribute using Testflight.

Google

Follow the steps in the guide below for instructions on testing:

- + \ No newline at end of file diff --git a/docs/applicationrater/unity/index.html b/docs/applicationrater/unity/index.html index 5150407a82c..50497b052db 100644 --- a/docs/applicationrater/unity/index.html +++ b/docs/applicationrater/unity/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ of days and is from the date that the user pressed the "Remind me later" button.

For example, to remind a user one week later, set this value to 7:

ApplicationRater.Instance.SetTimeBeforeReminding( 7 );

States

There are several states that the service can be in:

You can access the current state by calling, state :

string state = ApplicationRater.Instance.state;

The particular states control how the HasMetConditions() function processes the conditions and triggers the dialog.

Requesting Review

If you don't wish to use the rate dialog you can use this extension to simply open the appropriate store page for your user to review your application.

You should still set the application id by one of the methods described in the Application ID section.

Once you have set the application id you can call Rate() to direct the user to the appropriate place for them to rate and review your application.

ApplicationRater.Instance.Rate();

Handling Stores

You can retrieve the store that the application was installed through by using the GetInstallerStore() function. This function will attempt to determine which store the application was installed through and return one of the following values:

Example:

string store = ApplicationRater.Instance.GetInstallerStore();

You can then use this value to set the appropriate application id if you use different application id's in different stores.

For example, say we have com.distriqt.test in the Google Play Store and com.distriqt.amazon in the Amazon store:

string store = ApplicationRater.Instance.GetInstallerStore();
switch (store)
{
case ApplicationRater.STORE_AMAZON:
ApplicationRater.Instance.SetApplicationId( "com.distriqt.amazon", ApplicationRater.IMPLEMENTATION_ANDROID );
break;

default:
case ApplicationRater.STORE_GOOGLEPLAY:
ApplicationRater.Instance.SetApplicationId( "com.distriqt.test", ApplicationRater.IMPLEMENTATION_ANDROID );
break;

}

Support

If you need further support integrating or using this extension please feel free to contact us.

We have been supporting developers for over 10 years and always happy to help.





- + \ No newline at end of file diff --git a/docs/applovinsdk/add-the-extension/index.html b/docs/applovinsdk/add-the-extension/index.html index a269ca0e420..e71b54ca410 100644 --- a/docs/applovinsdk/add-the-extension/index.html +++ b/docs/applovinsdk/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (AppLovinSDK.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/applovinsdk/changelog/index.html b/docs/applovinsdk/changelog/index.html index c3764e1fa0f..def3e09b010 100644 --- a/docs/applovinsdk/changelog/index.html +++ b/docs/applovinsdk/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.05.25 [v2.16.0]

feat(admob): implement admob mediator ios v10.5.0, android v22.1.0.2
feat(facebook): implement facebook audience mediator ios v6.14.0, android v6.12.0
feat(ironsource): implement ironsource mediator ios v7.3.0, android v7.3.0
feat(unityads): implement unityads mediator ios v4.7.1, android v4.7.1
feat(docs): update to new documentation format
feat(applovinsdk): add basic initialisation and privacy functionality for android

2020.07.02 [v1.0.028]

Beta release
- + \ No newline at end of file diff --git a/docs/applovinsdk/index.html b/docs/applovinsdk/index.html index d366e9d58e9..28571a42bdf 100644 --- a/docs/applovinsdk/index.html +++ b/docs/applovinsdk/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

AppLovinSDK

The AppLovinSDK extension gives you access to the AppLovin SDK in your AIR application.

Features:

  • Access to the AppLovin MAX SDK:

    • Banners
    • Interstitials
    • Rewarded Video
  • Single API interface - your code works across supported platforms with no modifications

  • Sample project code and ASDocs reference

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

var interstitial:MaxInterstitialAd = AppLovinSDK.instance.interstitials.createMaxInterstitialAd();
interstitial.setAdUnitId( "interstitial_adUnitId" );
interstitial.addEventListener( InterstitialAdEvent.LOADED, loadedHandler );
interstitial.load();

function loadedHandler( event:InterstitialAdEvent ):void
{
interstitial.show();
}

Native Extensions

The highest quality and widest range of Native Extensions for Adobe AIR

With many native extensions available, we are the largest provider of native extensions for AIR developers. Our mobile solutions allow developers to fast-forward development and focus on building great games and apps.

https://airnativeextensions.com

- + \ No newline at end of file diff --git a/docs/applovinsdk/initialise/index.html b/docs/applovinsdk/initialise/index.html index 476d789c38b..da245825e52 100644 --- a/docs/applovinsdk/initialise/index.html +++ b/docs/applovinsdk/initialise/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Initialisation

Initialising the extension

You should perform this once in your application near where you are going to initially display an advert. This initialises the AppLovin platform.

if (AppLovinSDK.isSupported)
{
AppLovinSDK.instance.initialise();
}

The initialisation process will dispatch the AppLovinSDKEvent.INITIALISE_COMPLETE when the SDK is ready to be used:

AppLovinSDK.instance.addEventListener( AppLovinSDKEvent.INITIALISE_COMPLETE, initialise_completeHandler );

AppLovinSDK.instance.initialise();


function initialise_completeHandler( event:AppLovinSDKEvent ):void
{
// SDK initialised and ready to use
}

Configuration

You can provide configuration options to the SDK by passing a AppLovinSDKConfig instance to the initialise() call:

var config:AppLovinSDKConfig = new AppLovinSDKConfig();

AppLovinSDK.instance.initialise( config );

This allows you to set optional configuration parameters such as the mediationProvider:

var config:AppLovinSDKConfig = new AppLovinSDKConfig();
config.mediationProvider = "max";

AppLovinSDK.instance.initialise( config );
- + \ No newline at end of file diff --git a/docs/applovinsdk/interstitials/index.html b/docs/applovinsdk/interstitials/index.html index 4f7011169a0..3e0d68bbdb2 100644 --- a/docs/applovinsdk/interstitials/index.html +++ b/docs/applovinsdk/interstitials/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Interstitials

The interstitials are fullscreen adverts that you can use to transition between scenes in your application, such as after a game level.

All of the interstitial functionality is provided through the AppLovinSDK.instance.interstitials singleton.

Creating an Interstitial

To create an MaxInterstitialAd use the createMaxInterstitialAd function:

var interstitial:MaxInterstitialAd = AppLovinSDK.instance.interstitials.createMaxInterstitialAd();

This will instanciate an instance of the MaxInterstitialAd class.

You must set the ad unit on this ad as soon as possible by using the setAdUnitId function:

interstitial.setAdUnitId( "interstitial_adUnitId" );

Without setting the ad unit id everything else regarding the interstitial will fail.

Loading

Interstitials should be preloaded in your application. This allows you to start the load at any time, and only display when your application is ready or when the advert has been loaded.

To load an advert you use the load function.

interstitial.load();

You can listen for events that will inform you on when an advert is available or if there were any errors in loading the advert. There are two events of interest here:

  • InterstitialAdEvent.LOADED: dispatched when an ad has finished loading;
  • InterstitialAdEvent.ERROR: dispatched if the ad failed to load

You can use the loaded event to delay displaying the ad until you are sure an ad is available.

interstitial.addEventListener( InterstitialAdEvent.LOADED, loadedHandler );
interstitial.addEventListener( InterstitialAdEvent.ERROR, errorHandler );


function loadedHandler( event:InterstitialAdEvent ):void
{
// interstitial loaded and ready to be displayed
}

function errorHandler( event:InterstitialAdEvent ):void
{
// Load error occurred. The errorCode will contain more information
trace( "Error" + event.errorCode );
}

If an error occurs you can use the errorCode on the event to determine what type of error occurred.

Checking Loaded

You can check whether the advert is loaded by waiting for the InterstitialEvent.LOADED or checking the isLoaded() flag. It is useful to use the flag to confirm that the ad is loaded before attempting to display the ad:

if (interstitial.isLoaded())
{
// Show the ad
}

Display

When you are ready to display your advert you call show() as below.

interstitial.show();

When showing an advert you should save any content in your application as the advert may take the user out of your application if they follow the presented action. The InterstitialAdEvent.CLOSED event is dispatched when the user closes the advert and control returns to your application and you can then resume operation.

As noted above you should check if the advert is loaded before calling show:

if (interstitial.isLoaded())
{
interstitial.show();
}

Events

There are several events dispatched by the advert as the user interacts with it:

  • InterstitialAdEvent.OPENED: dispatched when an ad opens an overlay that covers the screen;
  • InterstitialAdEvent.LEFT_APPLICATION: when a user click opens another app (such as Google Play), backgrounding the current app;
  • InterstitialAdEvent.CLOSED: dispatched when a user returns to the app, having closed the interstitial;

At the very least we suggest you should listen for the closed event to know when control returns to your application.

interstitial.addEventListener( InterstitialAdEvent.OPENED, openedHandler );
interstitial.addEventListener( InterstitialAdEvent.LEFT_APPLICATION, leftApplicationHandler );
interstitial.addEventListener( InterstitialAdEvent.CLOSED, closedHandler );

if (interstitial.isLoaded())
{
interstitial.show();
}


function openedHandler( event:InterstitialAdEvent ):void
{
// The interstitial has been opened and is now visible to the user
}

function leftApplicationHandler( event:InterstitialAdEvent ):void
{
// Control has left your application,
// you can deactivate any none important parts of your application
}

function closedHandler( event:InterstitialAdEvent ):void
{
// Control has returned to your application
// you should reactivate any paused / stopped parts of your application.
}

Refresh

Once you have displayed an interstitial a new ad needs to be loaded in order to display the interstitial again. This is a simple matter of starting a new ad request load:

interstitial.load();

The CLOSED event is generally a good place to trigger this load so that you ensure you always have a loaded ad available to display in your application, however you can handle this process as you see fit.

- + \ No newline at end of file diff --git a/docs/applovinsdk/mediation/admob/index.html b/docs/applovinsdk/mediation/admob/index.html index 32bb9026008..2e238b6fa65 100644 --- a/docs/applovinsdk/mediation/admob/index.html +++ b/docs/applovinsdk/mediation/admob/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Additional code required

There is no additional code required.

- + \ No newline at end of file diff --git a/docs/applovinsdk/mediation/facebook/index.html b/docs/applovinsdk/mediation/facebook/index.html index 88b2c7fea48..cc6d3c513d0 100644 --- a/docs/applovinsdk/mediation/facebook/index.html +++ b/docs/applovinsdk/mediation/facebook/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ This allows you to inform Facebook whether to use the data to deliver personalized ads. If the flag is set to false FAN will not be able to deliver personalized ads.

Please note that setting the setAdvertiserTrackingEnabled flag should be done before initializing the AppLovin SDK. Learn more about Advertising Tracking Enabled for Audience Network here.

Facebook.instance.adSettings.setAdvertiserTrackingEnabled( true );
- + \ No newline at end of file diff --git a/docs/applovinsdk/mediation/ironsource/index.html b/docs/applovinsdk/mediation/ironsource/index.html index e19d7bfe6ae..84c9f49ad9b 100644 --- a/docs/applovinsdk/mediation/ironsource/index.html +++ b/docs/applovinsdk/mediation/ironsource/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Additional code required

There is no additional code required.

- + \ No newline at end of file diff --git a/docs/applovinsdk/mediation/unityads/index.html b/docs/applovinsdk/mediation/unityads/index.html index 25a5a51fcbd..9a0ce28c0b1 100644 --- a/docs/applovinsdk/mediation/unityads/index.html +++ b/docs/applovinsdk/mediation/unityads/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Square ANEs

Due to several of our ANE's using the Square open source libraries the libraries have been separated into a separate ANEs allowing you to avoid conflicts and duplicate definitions. This means that you need to include the some of the square native extensions in your application along with this extension.

You will add these extensions as you do with any other ANE, and you need to ensure it is packaged with your application.

This ANE requires the following Square extensions:

You can access these extensions here: https://github.com/distriqt/ANE-SquareLibs.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Additional code required

There is no additional code required.

- + \ No newline at end of file diff --git a/docs/applovinsdk/rewarded-video/index.html b/docs/applovinsdk/rewarded-video/index.html index 12caf967779..a75d4500be8 100644 --- a/docs/applovinsdk/rewarded-video/index.html +++ b/docs/applovinsdk/rewarded-video/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Rewarded Video

Rewarded video ads are full-screen video ads that users have the option of watching in full in exchange for in-app rewards.

MAX Rewarded Video Ads are represented by the MaxRewardedAd class.

All of the rewarded video ads functionality is provided through the AppLovinSDK.instance.rewardedVideoAds singleton.

MaxRewardedAd

To create a MaxRewardedAd instance use the createMaxRewardedAd() function:

var rewardedVideoAd:MaxRewardedAd = AppLovinSDK.instance.rewardedVideoAds.createMaxRewardedAd();

This will instanciate an instance of the MaxRewardedAd class. You are required to destroy this instance when you are finished with it.

You are required to set the ad unit id by calling the setAdUnitId function before any loading is performed.

rewardedVideoAd.setAdUnitId( "REWARDED_AD_UNIT_ID" );

Loading

Rewarded Video Ads should be preloaded in your application. This allows you to start the load at any time, and only display when your application is ready and when the advert has been loaded. You cannot display a rewarded video ad until it is loaded and ready.

To load an advert you use the load function:

rewardedVideoAd.load();

You can listen for events that will inform you on when an advert is available or if there were any errors in loading the advert.

  • RewardedVideoAdEvent.LOADED: dispatched when an ad has finished loading;
  • RewardedVideoAdEvent.ERROR: dispatched if the ad failed to load
rewardedVideoAd.addEventListener( RewardedVideoAdEvent.LOADED, loadedHandler );
rewardedVideoAd.addEventListener( RewardedVideoAdEvent.ERROR, errorHandler );

function loadedHandler( event:RewardedVideoAdEvent ):void
{
// rewarded video ad loaded and ready to be displayed
}

function errorHandler( event:RewardedVideoAdEvent ):void
{
// Load error occurred. The errorCode will contain more information
trace( "Error" + event.errorCode );
}

If an error occurs you can use the errorCode on the event to determine what type of error occurred.

Checking Loaded

You can check whether the advert is loaded by waiting for the RewardedVideoAdEvent.LOADED or checking the isLoaded() flag. It is useful to use the flag to confirm that the ad is loaded before attempting to display the ad:

if (rewardedVideoAd.isLoaded())
{
// Show the ad
}

Display

When you are ready to display the rewarded video you call show() as below:

rewardedVideoAd.show();

You should check whether the ad is loaded before calling show to ensure that there is an ad available to display (as noted above). If there isn't this call will fail and return false.

if (rewardedVideoAd.isLoaded())
{
rewardedVideoAd.show();
}

Events

There are several events dispatched by the rewarded video ad as the user interacts with it (in addition to the loaded and error events already mentioned):

  • RewardedVideoAdEvent.OPENED: dispatched when an ad opens an overlay that covers the screen;
  • RewardedVideoAdEvent.CLOSED: dispatched when a user returns to the app, having closed the rewarded video ad;
  • RewardedVideoAdEvent.REWARD: See the ![](reward section|u.Rewarded Video Ads#rewards)
  • RewardedVideoAdEvent.ERROR: dispatched if there was an error presenting the ad
rewardedVideoAd.addEventListener( RewardedVideoAdEvent.OPENED, openedHandler );
rewardedVideoAd.addEventListener( RewardedVideoAdEvent.CLOSED, closedHandler );

function openedHandler( event:RewardedVideoAdEvent ):void
{
// The rewarded video ad has been opened and is now visible to the user
}

function closedHandler( event:RewardedVideoAdEvent ):void
{
// Control has returned to your application
// you should reactivate any paused / stopped parts of your application.
}

Rewards

Rewarding your user should take place after the RewardedVideoAdEvent.REWARD event is dispatched. This is the important event that is dispatched after the user has finished watching the video ad and is when you should give the reward associated with this event to your user.

rewardedVideoAd.addEventListener( RewardedVideoAdEvent.REWARD, rewardHandler );

function rewardHandler( event:RewardedVideoAdEvent ):void
{
// Here you should reward your user

// event.rewardAmount contains the amount that should be awarded to your user
// event.rewardType contains the type of this reward
}

Refresh

Once you have displayed a rewarded video ad a new ad needs to be loaded in order to display the rewarded video ad again. This is a simple matter of starting a new ad request load:

rewardedVideoAd.load();

The CLOSED event is generally a good place to trigger this load so that you ensure you always have a loaded ad available to display in your application, however you can handle this process as you see fit.

- + \ No newline at end of file diff --git a/docs/audiorecorder/add-the-extension/index.html b/docs/audiorecorder/add-the-extension/index.html index 5fe9da4b125..77eee0060f8 100644 --- a/docs/audiorecorder/add-the-extension/index.html +++ b/docs/audiorecorder/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ the RECORD_AUDIO which is required to access to users microphone and the AuthorisationActivity which is required on recent versions of Android to request permissions at runtime.

<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application>

<activity android:name="com.distriqt.core.auth.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:exported="false" />

</application>

</manifest>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (AudioRecorder.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/audiorecorder/changelog/index.html b/docs/audiorecorder/changelog/index.html index eb3ac06c6ee..6e14523049e 100644 --- a/docs/audiorecorder/changelog/index.html +++ b/docs/audiorecorder/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.13 [v3.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2022.02.02 [v3.0.9]

Add air package
Update docs to use apm

2020.03.23 [v3.0.006]

Android X migration (resolves #9)

2019.08.16 [v2.0.002]

Android 64bit support (resolves #7)
Fixed optional permission requests
Updated minimum iOS version to 9.0

2017.11.29 [v1.2.044]

iOS implementation (#1)

2017.09.27 [v1.0.018]

Initial release

- + \ No newline at end of file diff --git a/docs/audiorecorder/index.html b/docs/audiorecorder/index.html index eb7c15fff06..13b93618a89 100644 --- a/docs/audiorecorder/index.html +++ b/docs/audiorecorder/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Audio Recorder

AudioRecorder is an AIR Native Extension to record audio from the user's microphone to a file.

The simple API allows you to quickly integrate audio recording in your AIR application in just a few lines of code.

Features

  • Record from the device microphone to a native format
  • Start, progress and end events
  • Single API interface - your code works across supported platforms with no modifications
  • Sample project code and ASDocs reference

Documentation

Latest documentation can be found in the documentation site

Quick Example:

var file:File = File.applicationStorageDirectory.resolvePath( "recording.m4a" );

var options:AudioRecorderOptions = new AudioRecorderOptions();
options.filename = file.nativePath;
options.audioEncoding = AudioEncoder.AAC;

AudioRecorder.service.start( options );

More information here:

com.distriqt.AudioRecorder

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/audiorecorder/migrating-to-androidx/index.html b/docs/audiorecorder/migrating-to-androidx/index.html index d642af2e803..4b574ac74c1 100644 --- a/docs/audiorecorder/migrating-to-androidx/index.html +++ b/docs/audiorecorder/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/audiorecorder/migrating-to-v3.1/index.html b/docs/audiorecorder/migrating-to-v3.1/index.html index 249e2894045..2e2fe1ad7d8 100644 --- a/docs/audiorecorder/migrating-to-v3.1/index.html +++ b/docs/audiorecorder/migrating-to-v3.1/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v3.1

v3.1 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/audiorecorder/playback/index.html b/docs/audiorecorder/playback/index.html index 9d316a6c868..91380da7ee4 100644 --- a/docs/audiorecorder/playback/index.html +++ b/docs/audiorecorder/playback/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Playback

Playback Recorded Audio

Once recorded you should be able to playback the recording using the standard AIR NetStream class:

var file:File = ...; // The file reference for the recording

var _nc:NetConnection = null;
var _ns:NetStream = null;

function play( file:File ):void
{
if (file.exists)
{
if (_nc == null)
{
_nc = new NetConnection();
_nc.connect(null);
}
_ns = new NetStream( _nc );
_ns.client = new Object();
_ns.play( "file://"+ file.nativePath );
}
else
{
trace( "ERROR: file doesn't exist" );
}
}
- + \ No newline at end of file diff --git a/docs/audiorecorder/recording-audio/index.html b/docs/audiorecorder/recording-audio/index.html index 4fb69a14d0d..bd4631fa2e4 100644 --- a/docs/audiorecorder/recording-audio/index.html +++ b/docs/audiorecorder/recording-audio/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Recording Audio

Start

To start recording audio you create an instance of the AudioRecorderOptions and call start.

The options allow you to specify the output file along with audio formats and other recording settings.

var file:File = File.applicationStorageDirectory.resolvePath( "recording.m4a" );

var options:AudioRecorderOptions = new AudioRecorderOptions();
options.filename = file.nativePath;
options.audioEncoding = AudioEncoder.AAC;

AudioRecorder.service.start( options );

Stop

Once you have finished recording you call the stop function to complete the recording.

AudioRecorder.service.stop();

Events

There are several events that are dispatched at various points through the recording defined by the AudioRecorderEvent class.

  • AudioRecorderEvent.START : Dispatched when recording starts
  • AudioRecorderEvent.COMPLETE : Dispatched when recording completes
  • AudioRecorderEvent.PROGRESS : Dispatched at periodic intervals while recording

You listen for these events as below:

AudioRecorder.service.addEventListener( AudioRecorderEvent.START, audioRecorderEventHandler );
AudioRecorder.service.addEventListener( AudioRecorderEvent.COMPLETE, audioRecorderEventHandler );
AudioRecorder.service.addEventListener( AudioRecorderEvent.PROGRESS, audioRecorderEventHandler );

Example event handler:

private function audioRecorderEventHandler( event:AudioRecorderEvent ):void
{
trace( event.type );
}
- + \ No newline at end of file diff --git a/docs/audiorecorder/requesting-authorisation/index.html b/docs/audiorecorder/requesting-authorisation/index.html index d626cc52a69..8a0bf705284 100644 --- a/docs/audiorecorder/requesting-authorisation/index.html +++ b/docs/audiorecorder/requesting-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ On older versions of Android these permissions are accepted when the user installs the application. More modern versions (Marshmallow 6 [v23]+) require that you request the permissions similar to iOS. You will still need to list them in your manifest and then follow the same code below as for iOS, except that on Android you will be able to ask multiple times.

You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

AudioRecorder.service.addEventListener( AuthorisationEvent.CHANGED, authorisationStatus_changedHandler );

switch (AudioRecorder.service.authorisationStatus())
{
case AuthorisationStatus.SHOULD_EXPLAIN:
case AuthorisationStatus.NOT_DETERMINED:
// REQUEST ACCESS: This will display the permission dialog
AudioRecorder.service.requestAuthorisation();
return;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
case AuthorisationStatus.RESTRICTED:
// ACCESS DENIED: You should inform your user appropriately
return;

case AuthorisationStatus.AUTHORISED:
// AUTHORISED: Microphone will be available
break;
}

function authorisationStatus_changedHandler( event:AuthorisationEvent ):void
{
trace( "authorisationStatus_changedHandler: "+event.status );
}
- + \ No newline at end of file diff --git a/docs/battery/add-the-extension/index.html b/docs/battery/add-the-extension/index.html index 04ddb3d7940..b90365b751c 100644 --- a/docs/battery/add-the-extension/index.html +++ b/docs/battery/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.Battery

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.Battery.ane # Battery extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Battery.isSupported)
{
// Functionality here
}

Desktop implementation

The desktop implementations for macOS and Windows use a NativeProcess to connect to execute a script that determines the current state of the battery. In order for this to work you must be using extendedDesktop profile.

The NativeProcess class and its capabilities are only available to AIR applications installed with a native installer (extended desktop profile applications). When debugging, you can pass the -profile extendedDesktop argument to ADL to enable the NativeProcess functionality.

Please note that the desktop (macOS and Windows) implementation may give you a warning about using the default implementation. This is expected as those platforms are completely handled by the default library.

- + \ No newline at end of file diff --git a/docs/battery/battery-info/index.html b/docs/battery/battery-info/index.html index 810287b6286..cdad4260b37 100644 --- a/docs/battery/battery-info/index.html +++ b/docs/battery/battery-info/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ The battery information retrieval is an asynchronous process so you must listen for the BatteryEvent.BATTERY_INFO event to get the response.

Battery.service.addEventListener( BatteryEvent.BATTERY_INFO, battery_infoHandler );

Battery.service.getBatteryInfo();

Then when the battery information is available:

private function battery_infoHandler( event:BatteryEvent ):void
{
// event contains information about the battery
}

The BatteryEvent contains 2 pieces of information:

The batteryLevel represents the current charge level of the battery. It ranges from 1 (full) to 0 (empty).

The batteryState indicates the current state of the battery and will be one of the values defined in the BatteryState class, which includes states like: full, charging, not charging.

Example:

private function battery_infoHandler( event:BatteryEvent ):void
{
switch( int(event.batteryState) )
{
case BatteryState.CHARGING:
trace("Battery state: CHARGING");
break;
case BatteryState.FULL:
trace("Battery state: FULL");
break;
case BatteryState.NOT_CHARGING:
trace("Battery state: NOT CHARGING");
break;
case BatteryState.NOT_SUPPORTED:
trace("Battery state: NOT SUPPORTED");
break;
case BatteryState.UNKNOWN:
default:
trace("Battery state: UNKNOWN");
break;
}

trace("Battery level: " + event.batteryLevel );
}
- + \ No newline at end of file diff --git a/docs/battery/changelog/index.html b/docs/battery/changelog/index.html index 3a54a923334..c56a005e329 100644 --- a/docs/battery/changelog/index.html +++ b/docs/battery/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.05.18 [v4.1.1]

fix(android): remove unused encryption code

2023.01.13 [v4.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2021.09.23 [v4.0.9]

Added air package
Removed ios minimum version flag

2020.03.23 [v4.0.008]

Android X migration (resolves #8)

2019.08.16 [v3.0.003]

Android 64bit support (resolves #7)
Added macOS implementation
Added Windows implementation
Updated minimum iOS version to 9.0

2018.10.22 [v2.0.004]

Removed application key requirement

2017.07.10 [v2.0.002]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2016.12.22 [v2.0.001]

Updating documentation

2016.12.22 [v2.0.001]

Updates for iOS 10 and Android 7.0
Updating documentation

2015.06.09

Android: Windows: Fix for bug in AIR packager resulting in missing resources (resolves #3)

2015.06.03

Android: x86 Support
Android: Added checks to avoid exception (#2)
Updated internal event formatting

2015.02.27

Changed class structure to support FlashBuilder 4.6

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.11.27

New application based key check, removing server checks

2014.10.22

iOS Update for iOS 8
- + \ No newline at end of file diff --git a/docs/battery/index.html b/docs/battery/index.html index 914c5c40d98..9c2c2cb0f08 100644 --- a/docs/battery/index.html +++ b/docs/battery/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ you access to a device's battery status.

The simple API allows you to quickly retrieve the battery information including charging status and battery level.

Features:

This Wiki forms the best source of detailed documentation for the extension along with the asdocs.

- + \ No newline at end of file diff --git a/docs/beacon/add-the-extension/index.html b/docs/beacon/add-the-extension/index.html index 772c4989750..81eda24e303 100644 --- a/docs/beacon/add-the-extension/index.html +++ b/docs/beacon/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ however if you are only building an iOS application feel free to remove the Google Play Services ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Beacon.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/beacon/broadcasting/index.html b/docs/beacon/broadcasting/index.html index 2d59976cd7a..2eb9dfdb201 100644 --- a/docs/beacon/broadcasting/index.html +++ b/docs/beacon/broadcasting/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Broadcasting

Broadcasting will make the device act as a beacon so that other devices can detect the device as if it were a beacon.

Availability

To check if broadcasting is available on the current device check the isBroadcastAvailable() flag.

if (Beacon.service.isBroadcastAvailable())
{
// Broadcasting is available on this device
}

Check if broadcasting

You can also check if the current device is already broadcasting as a beacon. This

if (Beacon.service.isBroadcasting())
{
// Device is broadcasting
}

Start broadcasting

To start broadcasting call the startBroadcast() function passing in the configuration for the beacon broadcast. The configuration is set by creating an instance of the BroadcastConfig class and setting the properties appropriate for your situation.

The details provided in the configuration identify the device. Of particular importance is the UUID provided to the constructor along with the major and minor values.

For example:

var config:BroadcastConfig = new BroadcastConfig( "7b44b47b-52a1-5381-90c2-f09b6838c5d4" );
config.major = 1;
config.minor = 5;

var success:Boolean = Beacon.service.startBroadcast( config );

success will be true if the broadcast was started successfully.

Stop broadcasting

To stop broadcasting call the stopBroadcast() function.

var success:Boolean = Beacon.service.stopBroadcast();

success will be true if the broadcast was stopped successfully. It may be false if the device was not broadcasting.

It's often good to wrap the stop call in the isBroadcasting() check, to ensure the device is broadcasting before attempting to stop:

if (Beacon.service.isBroadcasting())
{
Beacon.service.stopBroadcast();
}

Events

There are 3 events that will be dispatched during broadcasting:

  • BroadcastEvent.BROADCAST_START: Dispatched when the broadcasting starts successfully
  • BroadcastEvent.BROADCAST_ERROR: Dispatched if there was an error when starting broadcasting
  • BroadcastEvent.BROADCAST_STOP: Dispatched when broadcasting stops

The events are dispatched by the main Beacon.service instance, for example:

Beacon.service.addEventListener( BroadcastEvent.BROADCAST_START, startHandler );
Beacon.service.addEventListener( BroadcastEvent.BROADCAST_ERROR, errorHandler );
Beacon.service.addEventListener( BroadcastEvent.BROADCAST_STOP, stopHandler );


function startHandler( event:BroadcastEvent ):void
{
// broadcast started
}

function errorHandler( event:BroadcastEvent ):void
{
}

function stopHandler( event:BroadcastEvent ):void
{
// broadcast stopped
}
- + \ No newline at end of file diff --git a/docs/beacon/changelog/index.html b/docs/beacon/changelog/index.html index c62eb4ed3a7..2336c0c5197 100644 --- a/docs/beacon/changelog/index.html +++ b/docs/beacon/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.13 [v5.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2023.01.13 [v5.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.02.02 [v5.0.19]

Update for Android 31
Update docs to use apm
Update air package descriptions

2021.12.15 [v5.0.18]

Update air package parameter descriptions

2021.09.24 [v5.0.17]

Updated documentation links

2021.09.24 [v5.0.17]

Added air package
Added Android x64
Removed iOS minimum version linker option
Updated iOS builds

2020.03.23 [v5.0.014]

Android X migration (resolves #57)

2019.11.25 [v4.1.009]

Removed CoreBluetooth usage for applications not using the broadcast functionality (resolves #56)

2019.08.16 [v4.0.003]

Android 64bit support (resolves #55)
Updated minimum iOS version to 9.0

2019.04.04 [v3.2.023]

Updated minimum iOS version to 8.0
Embedded iOS bitcode
Removed application keys

2018.05.10 [v3.1.021]

Updated docs for iOS 11 and updated Android build to latest SDK

2017.07.10 [v3.1.018]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.05.20 [v3.1.017]

Android: Corrected offline operation (#48)

2017.04.12 [v3.1.011]

Android: Major update to Android implementation (#35, resolves #39, #41, #47)

2016.12.22 [v3.0.003]

Corrected corrupt build

2016.12.22 [v3.0.002]

Updating documentation

2016.07.02

Android: Version 3.0 - Complete rewrite brings better beacon monitoring and ranging (#35)

2016.06.24

iOS: Corrected request ALWAYS authorisation (resolves #36)

2016.06.10

Added check for location permission for Android v6.0+ (resolves #34)

2015.10.22

iOS: Added code to silently check bluetooth state (resolves #21)

2015.06.15

Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support
Removed debug code from AS lib

2015.03.09

iOS: Added broadcasting ability to turn a supported device into a beacon

2015.02.27

iOS: Added ability to request authorisation on iOS 8+ and to get status of authorisation (resolves #3)

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.11.27

New application based key check, removing server checks

03-11-14

Added ability to check if Bluetooth is turned on and monitor for changes

2014.10.22

Added the isBluetoothEnabled flag to detect current bluetooth state
- Added 2 events BLUETOOTH_STATE_ENABLED and BLUETOOTH_STATE_DISABLED
- iOS: Added a check for incorrect UUID (resolves #246)

2014.10.20

iOS Update for iOS 8 + Performance increase
- iOS: Checked and updated for iOS 8
- Android+iOS: Improved update event parsing performance (resolves #241)
- + \ No newline at end of file diff --git a/docs/beacon/events/index.html b/docs/beacon/events/index.html index 7e09062d187..13b5bb0c42d 100644 --- a/docs/beacon/events/index.html +++ b/docs/beacon/events/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Region exit events can take up to a minute, however an entry event should be quick (~1 second).

The application will also receive region and ranging events when in the background as long as:

If the device has been put to sleep the entry events may take a little longer but they will still be received. The ranging events will also not neccessarily be as consistent as when the application is running in the foreground.

- + \ No newline at end of file diff --git a/docs/beacon/index.html b/docs/beacon/index.html index a0ca87638a1..572f9f495c9 100644 --- a/docs/beacon/index.html +++ b/docs/beacon/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ in monitoring and detecting beacons. This helps you get up and running with iBeacons quickly.

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Features:

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

- + \ No newline at end of file diff --git a/docs/beacon/migrating-to-androidx/index.html b/docs/beacon/migrating-to-androidx/index.html index 3c73dd91d42..f73e3756f79 100644 --- a/docs/beacon/migrating-to-androidx/index.html +++ b/docs/beacon/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/beacon/migrating-to-v5.1/index.html b/docs/beacon/migrating-to-v5.1/index.html index e46a43a2565..c62490e9770 100644 --- a/docs/beacon/migrating-to-v5.1/index.html +++ b/docs/beacon/migrating-to-v5.1/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v5.1

v5.1 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/beacon/monitoring-a-region/index.html b/docs/beacon/monitoring-a-region/index.html index d505ea3ae7f..0133dd65de1 100644 --- a/docs/beacon/monitoring-a-region/index.html +++ b/docs/beacon/monitoring-a-region/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ is unique for each region as well as the uuid! If you do not you will only receive updates for the last region you started monitoring. The iOS SDK uses the identifier to determine if the region is unique, and replaces any existing region monitoring if it is the same.

Stop Monitoring

Similarly to stop monitoring call the stopMonitoringRegionWithUUID function:

if (Beacon.service.isMonitoringRegionWithUUID( uuid ))
{
var stopped:Boolean = Beacon.service.stopMonitoringRegionWithUUID( uuid, identifier );
trace( "Bluetooth monitoring stopped: "+stopped );
}
- + \ No newline at end of file diff --git a/docs/beacon/requesting-authorisation/index.html b/docs/beacon/requesting-authorisation/index.html index fce92ed4900..db47a684c62 100644 --- a/docs/beacon/requesting-authorisation/index.html +++ b/docs/beacon/requesting-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ user about why you require this functionality.

On iOS the user must be asked at runtime, which you only get one chance to ask, after which you must direct the user to manually change the permissions in the settings.

The following code will work across both platforms

Beacon.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );

switch (Beacon.service.authorisationStatus())
{
case AuthorisationStatus.AUTHORISED:
case AuthorisationStatus.ALWAYS:
case AuthorisationStatus.IN_USE:
// This device has been authorised for the particular use case
break;

case AuthorisationStatus.NOT_DETERMINED:
case AuthorisationStatus.SHOULD_EXPLAIN:
// You are yet to ask for authorisation
// At this point you should consider your strategy to get your
// user to authorise by explaining your need for the permissions

Beacon.service.requestAuthorisation();
break;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
case AuthorisationStatus.RESTRICTED:
// The user has disabled the permissions
// Advise your user of the lack of permissions as you see fit
break;
}

function authorisationChangedHandler( event:AuthorisationEvent ):void
{
// You should check the authorisation status again
}

Without authorisation none of the beacon functionality will work, so make sure you have been through this process and gotten a positive response from hasAuthorisation().

Usage Description

You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

- + \ No newline at end of file diff --git a/docs/beacon/tools-and-resources/index.html b/docs/beacon/tools-and-resources/index.html index b8e9b92dbf0..39e06351622 100644 --- a/docs/beacon/tools-and-resources/index.html +++ b/docs/beacon/tools-and-resources/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/bluetooth/add-the-extension/index.html b/docs/bluetooth/add-the-extension/index.html index 0e7161dbc84..8c0eb92a080 100644 --- a/docs/bluetooth/add-the-extension/index.html +++ b/docs/bluetooth/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

You can access this extension here: https://github.com/distriqt/ANE-Core.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Bluetooth.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/bluetooth/changelog/index.html b/docs/bluetooth/changelog/index.html index 595bac764c6..dda54d272c7 100644 --- a/docs/bluetooth/changelog/index.html +++ b/docs/bluetooth/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.13 [v3.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2021.12.15 [v3.0.10]

Update air package parameter descriptions

2021.09.24 [v3.0.9]

Added air package 
Updated build to latest

2020.03.23 [v3.0.008]

Android X migration (resolves #22)

2019.08.16 [v2.0.004]

Updated documentation

2019.08.16 [v2.0.004]

Android 64bit support
Updated minimum iOS version to 9.0
Embedded iOS bitcode
Removed application keys

2017.10.03 [v1.6.017]

Updated for Core ANE compatibility

2017.07.10 [v1.5.007]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2016.12.22 [v1.5.006]

Updating documentation

2016.10.24 [v1.5.004]

Removed excessive trace outputs (resolves #17)

2015.10.29

Resolved issue with incorrectly handling uuid case (resolves #9)

2015.06.15

Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support
Removed debug code from AS lib

2015.06.09

Android: Windows: Fix for bug in AIR packager resulting in missing resources (resolves #4)

2015.05.13

Android: Added check to ensure bluetooth is on before attempting to connect or listen (resolves #5)

2015.04.09

Moved to new structure to support FlashBuilder 4.6 (resolves #3)
Android: x86 Support

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all c function calls

2014.11.27

New application based key check, removing server checks

2014.10.16

Fixed string formatting bug on close function (resolves #223)
- + \ No newline at end of file diff --git a/docs/bluetooth/connecting/index.html b/docs/bluetooth/connecting/index.html index 8e224e0c585..7207d7c6bf5 100644 --- a/docs/bluetooth/connecting/index.html +++ b/docs/bluetooth/connecting/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ must connect to this device.

Each connection has a unique uuid that you should share between your application. A listener and a client must have the same uuid in order to initiate a connection.

The simplest way to handle this is to create a listener on both devices and only connect from the device initiating the connection.

- + \ No newline at end of file diff --git a/docs/bluetooth/index.html b/docs/bluetooth/index.html index c2f97ab1e56..332d273b633 100644 --- a/docs/bluetooth/index.html +++ b/docs/bluetooth/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ the limited External Accessory Framework.

Using the Bluetooth APIs, an application can perform the following:

We provide a complete getting started guide to walk you through the processes involved in using Bluetooth.

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Features:

Support

This extension is supported on the following platforms:

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.Bluetooth

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/bluetooth/ios/index.html b/docs/bluetooth/ios/index.html index 7fb9886af71..ad53e527e58 100644 --- a/docs/bluetooth/ios/index.html +++ b/docs/bluetooth/ios/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

iOS

iOS support

iOS is not possible to support to the level of connectivity we have created in this extension. The iOS SDK is simply too limiting and the required Bluetooth functionality is hidden in a private framework which will cause an application to be rejected if we used it.

The only option for Bluetooth on iOS is to use Bluetooth LE.

- + \ No newline at end of file diff --git a/docs/bluetoothle/adapter-state/index.html b/docs/bluetoothle/adapter-state/index.html index a885fe53c60..3c0fa1783ef 100644 --- a/docs/bluetoothle/adapter-state/index.html +++ b/docs/bluetoothle/adapter-state/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ you should listen for the STATE_CHANGED event and react accordingly. Any scanning will be stopped and you'll have to restart this once the adapter state changes again.

The values of the state property are defined in the BluetoothLEState class.

On iOS we cannot turn the adapter through code, instead you have to prompt the user, requesting they turn on Bluetooth.

BluetoothLE.service.addEventListener( BluetoothLEEvent.STATE_CHANGED, stateChangedHandler );

switch (BluetoothLE.service.state)
{
case BluetoothLEState.STATE_ON:
// We can use the Bluetooth LE functions
break;

case BluetoothLEState.STATE_OFF:
case BluetoothLEState.STATE_RESETTING:
case BluetoothLEState.STATE_UNAUTHORISED:
case BluetoothLEState.STATE_UNSUPPORTED:
case BluetoothLEState.STATE_UNKNOWN:
// All of these indicate the Bluetooth LE is not available
}


function stateChangedHandler( event:BluetoothLEEvent ):void
{
trace( "stateChangedHandler(): "+BluetoothLE.service.state );
}
- + \ No newline at end of file diff --git a/docs/bluetoothle/add-the-extension/index.html b/docs/bluetoothle/add-the-extension/index.html index 333cbfe2bbe..b4c83644795 100644 --- a/docs/bluetoothle/add-the-extension/index.html +++ b/docs/bluetoothle/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ Include the NSBluetoothPeripheralUsageDescription key in your app's Info.plist file and provide a purpose string for this key. If your app attempts to access the Bluetooth interface without a corresponding purpose string, your app exits.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (BluetoothLE.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/bluetoothle/central-manager/index.html b/docs/bluetoothle/central-manager/index.html index 93e0617a4e2..d4c3dabd3ca 100644 --- a/docs/bluetoothle/central-manager/index.html +++ b/docs/bluetoothle/central-manager/index.html @@ -13,7 +13,7 @@ - + @@ -63,7 +63,7 @@ To determine which types of writes are permitted to a characteristic's value, you access the relevant properties of the Characteristic.properties array. The possible values are defined in the Characteristic class PROPERTY_* definitions.

- + \ No newline at end of file diff --git a/docs/bluetoothle/centrals-and-peripherals/index.html b/docs/bluetoothle/centrals-and-peripherals/index.html index 6524aaea0dd..bc0b6984f3c 100644 --- a/docs/bluetoothle/centrals-and-peripherals/index.html +++ b/docs/bluetoothle/centrals-and-peripherals/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ When a central discovers such a peripheral, the central can request to connect with the peripheral and begin exploring and interacting with the peripheral's data. The peripheral is then responsible for responding to the central in appropriate ways.

Corresponding funtionality is grouped into the two managers accessible through the native extension:

- + \ No newline at end of file diff --git a/docs/bluetoothle/changelog/index.html b/docs/bluetoothle/changelog/index.html index b514d19af03..c4baaafdcec 100644 --- a/docs/bluetoothle/changelog/index.html +++ b/docs/bluetoothle/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.13 [v4.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.02.02 [v4.1.25]

Update for Android 31
Update docs for using apm
Update air package for Android 31

2021.12.15 [v4.1.24]

Update air package parameter descriptions

2021.10.13 [v4.1.23]

iOS authorisation process update (resolves #59)

2021.09.24 [v4.1.21]

Added air package

2021.06.08 [v4.1.020]

Updated build to correct swc definitions

2021.03.22 [v4.1.019]

Removed ios_version_min

2021.03.22 [v4.1.017]

Updated documentation and Android x64 build

2020.03.23 [v4.0.010]

Android X migration (resolves #54)

2019.08.16 [v3.0.004]

Android 64bit support (resolves #51)
Updated minimum iOS version to 9.0

2019.03.07 [v2.2.015]

Updated minimum iOS version to 8.0 (#49)
Embedded iOS bitcode
Removed application keys

2017.07.14 [v2.1.013]

iOS: Corrected dispatching of Authorisation Event (resolves #16)

2017.07.10 [v2.1.003]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.05.17 [v2.1.002]

Android: Updates for issues with subscribing to characteristics on some bluetooth devices (resolves #25)

2017.04.18 [v2.0.007]

iOS: Corrected authorisation status when not using background peripheral mode (#30)

2016.12.23 [v2.0.005]

Updating documentation

2016.07.17

Android: Release v1.0

2016.02.22

iOS: Corrected characteristic properties (#2)

2016.02.15

iOS: First release

2015.12.03

Beta Release
- + \ No newline at end of file diff --git a/docs/bluetoothle/index.html b/docs/bluetoothle/index.html index 2d1e2bacc8e..303369c51c8 100644 --- a/docs/bluetoothle/index.html +++ b/docs/bluetoothle/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ Other Central devices can the find your device and you can:

You can also use the API to act as both a Central and a Peripheral to enable 2 way communication between devices.

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Features:

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.Bluetooth

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/bluetoothle/migrating-to-androidx/index.html b/docs/bluetoothle/migrating-to-androidx/index.html index f8d2ecafed8..09e7b55e797 100644 --- a/docs/bluetoothle/migrating-to-androidx/index.html +++ b/docs/bluetoothle/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/bluetoothle/migrating-to-v4.2/index.html b/docs/bluetoothle/migrating-to-v4.2/index.html index 7e5e28c4681..48a788c982a 100644 --- a/docs/bluetoothle/migrating-to-v4.2/index.html +++ b/docs/bluetoothle/migrating-to-v4.2/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v4.2

v4.2 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/bluetoothle/peripheral-manager/index.html b/docs/bluetoothle/peripheral-manager/index.html index a6115eb8f54..81f915cfc0a 100644 --- a/docs/bluetoothle/peripheral-manager/index.html +++ b/docs/bluetoothle/peripheral-manager/index.html @@ -13,7 +13,7 @@ - + @@ -84,7 +84,7 @@ the update was successfully sent to the subscribed centrals. If the underlying queue that is used to transmit the updated value is full, the method returns false and you should wait and try again later.

- + \ No newline at end of file diff --git a/docs/bluetoothle/request-authorisation/index.html b/docs/bluetoothle/request-authorisation/index.html index 100c9112843..7631dd27ff3 100644 --- a/docs/bluetoothle/request-authorisation/index.html +++ b/docs/bluetoothle/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ as for iOS, except that on Android you will be able to ask multiple times. You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

BluetoothLE.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );

switch (BluetoothLE.service.authorisationStatus())
{
case AuthorisationStatus.AUTHORISED:
// The user has granted access to Bluetooth LE
break;

case AuthorisationStatus.NOT_DETERMINED:
case AuthorisationStatus.SHOULD_EXPLAIN:
// The user has not yet been asked or
// has denied once and you should explain
BluetoothLE.service.requestAuthorisation();
break;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.RESTRICTED:
case AuthorisationStatus.UNKNOWN:
// The user has denied access or has restricted access to Bluetooth LE
break;
}


function authorisationChangedHandler( event:AuthorisationEvent ):void
{
// Authorisation status has now changed
}

Usage Description

You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

- + \ No newline at end of file diff --git a/docs/bolts/changelog/index.html b/docs/bolts/changelog/index.html index adbe5eb29e3..225cd989993 100644 --- a/docs/bolts/changelog/index.html +++ b/docs/bolts/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2021.08.20 [v4.2.1]
AIR package release
2020.05.13 [v4.1.033]
iOS: UIWebView -> WKWebView
2020.03.20 [v4.0.029]
Android X migration (resolves #2)
2019.08.12 [v3.0.025]
Android 64bit support (resolves #1)
Updated minimum iOS version to 9.0
2019.02.26 [v2.2.018]
Updated minimum iOS version to 8.0
2018.11.02 [v2.1.017]
Updated iOS Bolts SDK
2018.02.20 [v2.1.015]
Updated iOS lib to v1.8.4
2017.11.16 [v2.0.012]
Updated iOS framework for Facebook v4.28+
2017.09.08 [v2.0.011]
Latest update to match Facebook SDK v4.26.0
2017.03.27 [v2.0.006]
Updated SDK
2017.03.27 [v2.0.006]
Updated SDK
2017.01.06 [v2.0.004]
Added additional bolts dependencies
2016.02.05
Updated SDK - iOS: v1.5.1 Android: v1.4.0
2015.08.25
Android: Updated Bolts lib to version 1.2.1
2015.06.18
Release of the ANE (Android v1.2 iOS v1.1.5)
- + \ No newline at end of file diff --git a/docs/branch/add-the-extension/index.html b/docs/branch/add-the-extension/index.html index cd8de85d2a7..b6ea3edb4f7 100644 --- a/docs/branch/add-the-extension/index.html +++ b/docs/branch/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ will avoid conflicts, allowing you to use multiple ANEs in the one application.

If you wish to use the expanded functionality add the following Google Play Services:

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There is no problem packaging these ANEs with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (BluetoothLE.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/branch/branch-universal-objects/index.html b/docs/branch/branch-universal-objects/index.html index 16067df1814..a5533358659 100644 --- a/docs/branch/branch-universal-objects/index.html +++ b/docs/branch/branch-universal-objects/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Branch Universal Objects

This is the BranchUniversalObject (or BUO for short). Think of it like an empty box.

The BUO is used to tell Branch about a piece of content within your application, whether it’s a pair of shoes for sale, a hotel room in Prague, a recipe for veal picatta, or tonight’s Earthquakes game. Branch uses the BUO to send data from one user who wants to share a piece of content within your app to another users who wants to view it.

Create BranchUniversalObject

The Branch Universal Object encapsulates the thing you want to share (content or user). You create an instance of a BranchUniversalObject by calling the createUniversalObject() function. At a minimum it should have a unique identifier and a title:

var buo:BranchUniversalObject = Branch.instance.createUniversalObject()
.setCanonicalIdentifier( "content/12345" )
.setTitle( "My Content Title" )
;

There are many other common properties and extended metadata that you can set on this object:

var buo:BranchUniversalObject = Branch.instance.createUniversalObject()
.setCanonicalIdentifier( "content/12345" )
.setTitle( "My Content Title" )
.setContentDescription( "My Content Description")
.setContentImageUrl("https://lorempixel.com/400/400")
.setContentIndexingMode("public")
.setLocalIndexMode("public")
.setContentMetadata( new ContentMetadata()
.addCustomMetadata("key1", "value1" )
)
;

Properties

There are a series of properties that you can set on a BUO within your app integration. You can see them all listed in the Branch documatation:

Once you have created the BUO identifying your content, you can generate a link to the content using the generateShortUrl() function. This function can take a series of link properties defined in a LinkProperties instance passed to the generateShortUrl() function.

When complete the function will execute the callback function passed as the second parameter to the generateShortUrl() with 2 parameters, the first is the url representing the generated link and the second is an error (BranchError) and will be null if no error occurred.

var properties:LinkProperties = new LinkProperties()
.setChannel( "facebook" )
.setFeature( "sharing" )
.setCampaign( "content 123 launch" )
.setStage( "new user" )
.addControlParameter( "$desktop_url", "http://example.com/home" )
.addControlParameter( "custom", "data" )
;

buo.generateShortUrl(
properties,
function ( url:String, error:BranchError ):void
{
trace( "short url: " + url );
}
);
- + \ No newline at end of file diff --git a/docs/branch/changelog/index.html b/docs/branch/changelog/index.html index 0b673f7c4e1..4303566def2 100644 --- a/docs/branch/changelog/index.html +++ b/docs/branch/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.05.08 [v5.4.0]

feat(android): sdk update v5.4.0

2023.02.02 [v5.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2021.12.07 [v5.0.68]

Add airpackage

2021.03.12 [v5.0.067]

SDK Update
- iOS v0.35.0
- Android v5.0.3

Added Branch Universal Objects

2020.03.25 [v4.0.040]

Android X migration (resolves #9)

2020.02.14 [v3.2.032]

SDK Update
- iOS v0.31.4
- Android v3.2.0

Updates:
- Corrected issue with launch link parameters (resolves #7)

2019.09.30 [v3.1.023]

SDK Update
- iOS v0.28.1
- Android v3.2.0
Improved link handling
Removed dynamic framework dependency (no resigning now required) (resolves #2)

2019.07.04 [v3.0.003]

Android 64bit support (resolves #5)

2018.08.05 [v2.0.054]

v2.0 release

v1.1.2

- work in progress
- iOS SDK v0.12.2

v1.1.1

- iOS SDK v0.10.4
- added userCompletedAction method.

v1.1.0

- iOS SDK v0.10.3
- Android SDK v1.8.0
- init method accept a bool param to use live or test branch.
- added alias and type to the getShortUrl function.
- added getCredits method.
- added redeemRewards method.
- added getCreditsHistory method.
- added getReferralCode, createReferralCode, validateReferralCode, applyReferralCode methods.

v1.0.1

- the Branch activity is finished once the init function is called.
- iOS SDK v0.6.3
- Android SDK v1.5.5

v1.0.0

- initial release
- iOS SDK v0.6.0
- Android SDK v1.5.3
- + \ No newline at end of file diff --git a/docs/branch/deep-links/index.html b/docs/branch/deep-links/index.html index fbc1388217a..25e8b652f8d 100644 --- a/docs/branch/deep-links/index.html +++ b/docs/branch/deep-links/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Deep Links

If your application is launched from a branch link you will receive an event with the branch parameters associated with that link.

When this occurs the BranchEvent.INIT_SUCCESS will be dispatched with the params exactly the same as after the initial initSession call.

So in order to process deep links it is important that your BranchEvent.INIT_SUCCESS handler is not removed and that you can handle this event being dispatched at any time in your application.

We recommend using the clicked_branch_link and match_guaranteed params to be able to determine how the link was used and whether it is a guaranteed link click.

For example:

function init_successHandler( event:BranchEvent ):void
{
trace( event.type + "::" + event.data );
try
{
var sessionParams:Object = JSON.parse(event.data);

var clicked_branch_link:Boolean = false;
if (sessionParams.hasOwnProperty("+clicked_branch_link"))
clicked_branch_link = sessionParams["+clicked_branch_link"];

var match_guaranteed:Boolean = = false;
if (sessionParams.hasOwnProperty("+match_guaranteed"))
match_guaranteed = sessionParams["+match_guaranteed"];


if (clicked_branch_link && match_guaranteed)
{
trace( "CLICKED BRANCH LINK" );
}
}
catch (e:Error)
{
}
}
- + \ No newline at end of file diff --git a/docs/branch/event-tracking/index.html b/docs/branch/event-tracking/index.html index d176c686a4e..d50022276a1 100644 --- a/docs/branch/event-tracking/index.html +++ b/docs/branch/event-tracking/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Event Tracking

To track user events you will use the BranchEventBuilder to construct an event and then pass the output from this to the logEvent function. The builder has a range of helper functions to allow you to correctly construct the event data.

var builder:BrancEventBuilder = new BranchEventBuilder( eventName );

// build your event and then pass to logEvent

Branch.instance.logEvent( builder.build() );

Standard Event

You construct a "standard" event by using one of the predefined constant event names in the BranchEventBuilder class: STANDARD_EVENT_*. These names are matched to standard events in the Branch dashboard.

For example:

Branch.instance.logEvent(
new BranchEventBuilder( BranchEventBuilder.STANDARD_EVENT_PURCHASE )
.setRevenue( 1.23 )
.setTax( 0.12 )
.setTransactionID( "XXDDCCFFDD" )
.setCurrency("USD")
.setShipping(0)
.build()
);

Custom Event

To construct a custom event you can use your own event name when creating your builder. Events named open, close, install, and referred session are Branch restricted along with the standard event names.

For example:

Branch.instance.logEvent(
new BranchEventBuilder( "your_custom_event" )
.addCustomDataProperty("your_custom_key", "your_custom_value")
.build()
);
- + \ No newline at end of file diff --git a/docs/branch/get-short-url/index.html b/docs/branch/get-short-url/index.html index 49e14939248..c1326cb96b6 100644 --- a/docs/branch/get-short-url/index.html +++ b/docs/branch/get-short-url/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Get Short URL

Note: This functionality has been deprecated. It is to be considered legacy functionality and has been replaced by Branch Universal Objects

There are a bunch of options for creating these links. You can tag them for analytics in the dashboard, or you can even pass data to the new installs or opens that come from the link click.

You need to pass a callback for when your link is prepared (which should return very quickly, ~ 50 ms to process).

For more details on how to create links, see the Branch link creation guide.

Branch.instance.addEventListener( BranchEvent.GET_SHORT_URL_FAILED, getShortUrlFailed );
Branch.instance.addEventListener( BranchEvent.GET_SHORT_URL_SUCCESS, getShortUrlSuccess );

function getShortUrlSuccess( event:BranchEvent ):void
{
trace( "short url: " + event.data );
}

function getShortUrlFailed( event:BranchEvent ):void
{
trace( "ERROR:" + event.data);
}

var dataToInclude:Object =
{
user:"Joe",
profile_pic:"https://avatars3.githubusercontent.com/u/7772941?v=3&s=200",
description:"Joe likes long walks on the beach...",

// customize the display of the Branch link
"$og_title":"Joe's My App Referral",
"$og_image_url":"https://branch.io/img/logo_white.png",
"$og_description":"Join Joe in My App - it's awesome"
};

var tags:Array = ["version1", "trial6"];

Branch.instance.getShortUrl( tags, "text_message", BranchConst.FEATURE_TAG_SHARE, "level_3", JSON.stringify(dataToInclude) );

There are other methods which exclude tag and data if you don't want to pass those.

Note You can customize the Facebook OG tags of each URL if you want to dynamically share content by using the following optional keys in the data dictionary:

KeyValue
"$og_title"The title you'd like to appear for the link in social media
"$og_description"The description you'd like to appear for the link in social media
"$og_image_url"The URL for the image you'd like to appear for the link in social media
"$og_video"The URL for the video
"$og_url"The URL you'd like to appear
"$og_app_id"Your OG app ID. Optional and rarely used.

Also, you do custom redirection by inserting the following optional keys in the dictionary:

KeyValue
"$desktop_url"Where to send the user on a desktop or laptop. By default it is the Branch-hosted text-me service
"$android_url"The replacement URL for the Play Store to send the user if they don't have the app. Only necessary if you want a mobile web splash
"$ios_url"The replacement URL for the App Store to send the user if they don't have the app. Only necessary if you want a mobile web splash
"$ipad_url"Same as above but for iPad Store
"$fire_url"Same as above but for Amazon Fire Store
"$blackberry_url"Same as above but for Blackberry Store
"$windows_phone_url"Same as above but for Windows Store

You have the ability to control the direct deep linking of each link by inserting the following optional keys in the dictionary:

KeyValue
"$deeplink_path"The value of the deep link path that you'd like us to append to your URI. For example, you could specify "$deeplink_path": "radio/station/456" and we'll open the app with the URI "yourapp://radio/station/456?link_click_id=branch-identifier". This is primarily for supporting legacy deep linking infrastructure.
"$always_deeplink"true or false. (default is not to deep link first) This key can be specified to have our linking service force try to open the app, even if we're not sure the user has the app installed. If the app is not installed, we fall back to the respective app store or $platform_url key. By default, we only open the app if we've seen a user initiate a session in your app from a Branch link (has been cookied and deep linked by Branch).
- + \ No newline at end of file diff --git a/docs/branch/index.html b/docs/branch/index.html index 28580d4e5ca..f9106153f87 100644 --- a/docs/branch/index.html +++ b/docs/branch/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Branch

Branch IO Adobe AIR Native Extension for iOS and Android gives you access to the Branch SDK in your Adobe AIR application.

Branch provides powerful links and solutions that help you acquire, engage, and measure across all devices, channels, and platforms.

Bring users to the correct page in your app even through install.

Deep links point directly to your in-app content from sources across channels and platforms, delivering a high quality user experience. Our deep links go a step further, linking fresh users from install directly to the correct pages. Our links also handle every edge case, routing through every channel, platform, OS, and deep linking standard that exists.

Attribution and Analytics

Capture every customer touch point across any platform, any channel, and every OS.

Say goodbye to mobile fragmentation across web and app channels, and the wasted spend that results. Branch weaves it back together, providing an enhanced understanding of your users that leads to clearer, more accurate attribution and measurement.

Seamless Integrations

The missing piece of your marketing stack.

Branch integrates into all of your marketing tools, from media execution and marketing automation to data warehouses and analytics. With a one-time sync of the Branch platform and your organic and paid channels, all of your data will be sent where you want it to go.

More information on the Branch website

Features:

  • Session management
  • Link parameters
  • Credits
  • Event Tracking (standard and custom)

The Wiki forms the best source of detailed documentation for the extension along with the asdocs.

- + \ No newline at end of file diff --git a/docs/branch/initialisation/index.html b/docs/branch/initialisation/index.html index e3a5a04fe2a..8c7950be757 100644 --- a/docs/branch/initialisation/index.html +++ b/docs/branch/initialisation/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Initialisation

Initialise the Branch SDK

To initialise the Branch SDK you will need to call the initSession function.

Branch.instance.initSession();

This process will dispatch one of two events:

  • BranchEvent.INIT_FAILED: Dispatched when initialisation failed
  • BranchEvent.INIT_SUCCESS: Dispatched when initialisation succeeded
Branch.instance.addEventListener( BranchEvent.INIT_FAILED, init_failedHandler );
Branch.instance.addEventListener( BranchEvent.INIT_SUCCESS, init_successHandler );

function init_successHandler( event:BranchEvent ):void
{
trace( event.type + "::" + event.data );

// params are the deep linked params associated with the link that the user clicked before showing up
// params will be empty if no data found
}

function init_failedHandler( event:BranchEvent ):void
{
trace( event.type + "::" + event.data );
}

Options

You can specify options for the SDK and session by using an instance of the BranchOptions class as the first parameter to the initSession function.

For example, to force the SDK to use your test key:

Branch.instance.initSession(
new BranchOptions()
.setUseTestKey()
);

You can also set the option to delay init to check for search ads:

Branch.instance.initSession(
new BranchOptions()
.setDelayInitToCheckForSearchAds()
);

The BranchOptions functionality is designed to be chained so you can set multiple parameters simply:

Branch.instance.initSession(
new BranchOptions()
.setUseTestKey()
.setDelayInitToCheckForSearchAds()
);

Imports

If you manually manage imports you will need to add the following:

import io.branch.nativeExtensions.branch.Branch;
import io.branch.nativeExtensions.branch.BranchOptions;
import io.branch.nativeExtensions.branch.events.BranchEvent;
- + \ No newline at end of file diff --git a/docs/branch/link-parameters/index.html b/docs/branch/link-parameters/index.html index 4140d84014d..7b8fb1e0067 100644 --- a/docs/branch/link-parameters/index.html +++ b/docs/branch/link-parameters/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Link Parameters

Latest Referring Parameters

The session parameters refer to the latest available parameters that were used to open the application. They will be available at any point later on with this command.

If no params, the dictionary will be empty. This refreshes with every new session (app installs AND app opens).

These parameters are retrieved by using the getLatestReferringParams() function.

var sessionParams:String = Branch.instance.getLatestReferringParams();
var sessionParamsObj:Object = JSON.parse(sessionParams);

Install Parameters

Install parameters refer to the original session parameters used to first install / launch the application.

If you ever want to access the original session params (the parameters passed in for the first install event only), you can use this line.

This is useful if you only want to reward users who newly installed the app from a referral link.

These parameters are retrieved by using the getFirstReferringParams() function.

var installParams:String = Branch.instance.getFirstReferringParams();
var installParamsObj:Object = JSON.parse(installParams);
- + \ No newline at end of file diff --git a/docs/branch/migrating-to-androidx/index.html b/docs/branch/migrating-to-androidx/index.html index dfdce686287..22957f78b07 100644 --- a/docs/branch/migrating-to-androidx/index.html +++ b/docs/branch/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/branch/referral-credits/index.html b/docs/branch/referral-credits/index.html index 133efa8dbee..1e6256362b2 100644 --- a/docs/branch/referral-credits/index.html +++ b/docs/branch/referral-credits/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ : The id of the referring user for this credit transaction. Returns null if no referrer is involved. Note this id is the user id in developer's own system that's previously passed to Branch's identify user API call.

referree : The id of the user who was referred for this credit transaction. Returns null if no referree is involved. Note this id is the user id in developer's own system that's previously passed to Branch's identify user API call.

type : This is the type of credit transaction

  1. 0 - A reward that was added automatically by the user completing an action or referral
  2. 1 - A reward that was added manually
  3. 2 - A redemption of credits that occurred through our API or SDKs
  4. 3 - This is a very unique case where we will subtract credits automatically when we detect fraud
- + \ No newline at end of file diff --git a/docs/branch/testing/index.html b/docs/branch/testing/index.html index cfbded20a64..410b490ca75 100644 --- a/docs/branch/testing/index.html +++ b/docs/branch/testing/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Testing

If you're going to test, I'd say testing the following should be a minimum:

  • Deferred deep linking
  • Regular deep linking
  • Event tracking
  • Link creation

Here's a sample guide to test deep linking. I'd say manual tests are OK in handling this. Let me know if you need more clarification!

https://docs.branch.io/pages/apps/ios/#test-deep-link

- + \ No newline at end of file diff --git a/docs/branch/user-identity/index.html b/docs/branch/user-identity/index.html index c5588d3617b..46ec53dfec0 100644 --- a/docs/branch/user-identity/index.html +++ b/docs/branch/user-identity/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

User Identity

Set Identity

Often, you might have your own user IDs, or want referral and event data to persist across platforms or uninstall/reinstall. It's helpful if you know your users access your service from different devices. This where we introduce the concept of an 'identity'.

To identify a user, just call:

Branch.instance.setIdentity("your user id");

This can be used to set the identity of a user (email, ID, UUID, etc) for events, deep links, and referrals.

Logout

If you provide the functionality to logout or disconnect a user you can call logout to clear any identity information you may have set.

Branch.instance.logout();

Warning this call will clear the referral credits and attribution on the device.

- + \ No newline at end of file diff --git a/docs/braze/add-the-extension/index.html b/docs/braze/add-the-extension/index.html index 67d1f524c76..504826b5921 100644 --- a/docs/braze/add-the-extension/index.html +++ b/docs/braze/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

You can access this extension here: https://github.com/distriqt/ANE-Core.

Android Support

The Android Support libraries encompass the Android Support, Android X and common Google libraries.

These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

This extension requires the following extensions:

You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Braze.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/braze/analytics/index.html b/docs/braze/analytics/index.html index d46fd798893..ead5e0ca740 100644 --- a/docs/braze/analytics/index.html +++ b/docs/braze/analytics/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Analytics

Tracking Sessions

Session lifecycle

If you have integrated Braze using BrazeConfig.setSessionHandlingEnabled(true), openSession() and closeSession() will be called automatically for your app.

Android

By default, sessions on Android are opened upon the first call to openSession() and are closed after an app has been out of the foreground for longer than 10 seconds. Note that calling closeSession() does not close a session immediately. Rather, it closes a session in 10 seconds if the user doesn’t call openSession() (e.g., by navigating to another activity) in the interim.

An Android session times out after 10 seconds without any communication from the host application. This means if a user backgrounds the app and returns 9 seconds later, the same session will be continued. Note that if a session closes while the user has the app backgrounded, that data may not be flushed to the server until the app is opened again.

note

If you need to force a new session, you can do so by changing users.

Customizing session timeout

To customize the session timeout, call setSessionTimeout() with the number of seconds on your BrazeConfig instance.

var options:BrazeConfig = new BrazeConfig()
...
.setSessionTimeout(100)
;

Subscribing to session updates

To listen for session open and close updates add a listener for the BrazeSessionEvent.SESSION_STARTED and BrazeSessionEvent.SESSION_ENDED events:

Braze.instance.addEventListener( BrazeSessionEvent.SESSION_STARTED, session_startedHandler );
Braze.instance.addEventListener( BrazeSessionEvent.SESSION_ENDED, session_endedHandler );

function session_startedHandler( event:BrazeSessionEvent ):void
{
trace( "session_startedHandler: " + event.sessionId );
}

function session_endedHandler( event:BrazeSessionEvent ):void
{
trace( "session_endedHandler: " + event.sessionId );
}

Setting User IDs

User IDs should be set for each of your users. These should be unchanging and accessible when a user opens the app. Naming your user IDs correctly from the start is one of the most crucial steps when setting up user IDs. We strongly suggest using the Braze standard of UUIDs and GUIDs (detailed below). We also strongly recommend providing this identifier as it will allow you to:

  • Track your users across devices and platforms, improving the quality of your behavioral and demographic data.
  • Import data about your users using our user data API.
  • Target specific users with our messaging API for both general and transactional messages.

Assigning a user ID

You should make the following call as soon as the user is identified (generally after logging in) in order to set the user ID:

Braze.instance.changeUser( YOUR_USER_ID_STRING );
caution

Do not call changeUser() when a user logs out. changeUser() should only be called when the user logs into the application. Setting changeUser() to a static default value will associate ALL user activity with that default "user" until the user logs in again.

Additionally, we recommend against changing the user ID when a user logs out, as it makes you unable to target the previously logged-in user with reengagement campaigns. If you anticipate multiple users on the same device, but only want to target one of them when your app is in a logged-out state, we recommend separately keeping track of the user ID you want to target while logged out and switching back to that user ID as part of your app’s logout process.

Aliasing users

A user alias serves as an alternative unique user identifier. Use aliases to identify users along different dimensions than your core user ID:

  • Set a consistent identifier for analytics that will follow a given user both before and after they have logged in to a mobile app or website.
  • Add the identifiers used by a third-party vendor to your Braze users in order to more easily reconcile your data externally.

Each alias consists of two parts: a name for the identifier itself, and a label indicating the type of alias. Users can have multiple aliases with different labels, but only one name per label.

Braze.instance.getCurrentUser().addAlias( ALIAS_NAME, ALIAS_LABEL );

Assigning User Attributes

To assign attributes to your users, call the `getCurrentUser()`` method on your Braze instance to get a reference to the current user of your app. Once you have a reference to the current user, you can call methods to set predefined or custom attributes.

Standard user attributes

Braze provides predefined methods for setting the following user attributes within the BrazeUser instance .

  • First name
  • Last name
  • Country
  • Language
  • Date of birth
  • Email
  • Gender
  • Home city
  • Phone number

All string values such as first name, last name, country, and home city are limited to 255 characters.

For example:

with (Braze.instance.getCurrentUser())
{
setFirstName( "John" );
setLastName( "Smith" );
setLanguage( "en" );
setCountry( "COUNTRY" );
setEmail( "EMAIL@ADDRESS.COM" );
setGender( Gender.PREFER_NOT_TO_SAY );
addAlias( "ALIAS_NAME", "ALIAS_LABEL" );
}

Setting custom attribute values

Braze.instance.getCurrentUser().setCustomUserAttribute( "your_attribute_key", "your_attribute_value" );

Unsetting a custom attribute

Custom attributes can also be unset using the following method:

Braze.instance.getCurrentUser().unsetCustomUserAttribute( "your_attribute_key" );

Setting up user subscriptions

To set up a subscription for your users (either email or push), call the functions setEmailNotificationSubscriptionType() or setPushNotificationSubscriptionType(), respectively. Both of these functions take the enum type NotificationSubscriptionType as arguments. This type has three different states:

SUBSCRIPTION STATUSDEFINITION
NotificationSubscriptionType.OPTED_INSubscribed, and explicitly opted in
NotificationSubscriptionType.SUBSCRIBEDSubscribed, but not explicitly opted in
NotificationSubscriptionType.UNSUBSCRIBEDUnsubscribed and/or explicitly opted out
Important

No explicit opt-in is required by Android to send users push notifications. When a user is registered for push, they are set to SUBSCRIBED rather than OPTED_IN by default. Refer to managing user subscriptions for more information on implementing subscriptions and explicit opt-ins.

Setting email subscriptions
Braze.instance.getCurrentUser().setEmailNotificationSubscriptionType( NotificationSubscriptionType.SUBSCRIBED );
Setting push notification subscriptions
Braze.instance.getCurrentUser().setPushNotificationSubscriptionType( NotificationSubscriptionType.SUBSCRIBED );

Tracking custom events

Before implementation, be sure to review examples of the segmentation options afforded by custom events, custom attributes, and purchase events in the analytics overview, as well as the notes on event naming conventions.

Adding a custom event

Braze.instance.logCustomEvent( YOUR_EVENT_NAME );

Adding properties

You can add metadata about custom events by passing a BrazeProperties object with your custom event.

Properties are defined as key-value pairs.

Braze.instance.logCustomEvent(
YOUR_EVENT_NAME,
new BrazeProperties()
.addProperty( "test", "true" )
.addProperty( "source", "distriqt-test-app" )
);

Reserved keys

The following keys are reserved and cannot be used as custom event properties:

  • time
  • event_name

Logging Purchases

Record in-app purchases so that you can track your revenue over time and across revenue sources, as well as segment your users by their lifetime value. This reference article shows how to track in-app purchases and revenue and assign purchase properties in your Android or FireOS application.

Braze supports purchases in multiple currencies. Purchases that you report in a currency other than USD will be shown in the dashboard in USD based on the exchange rate at the date they were reported.

Before implementation, be sure to review examples of the segmentation options afforded by custom events, custom attributes, and purchase events in the analytics overview.

To use this feature, call logPurchase() after a successful purchase in your app. If the product Identifier is empty, the purchase will not be logged to Braze.

Braze.instance.logPurchase(
"productId",
"currencyCode",
1.23, // price
1 // quantity
);
Tip

If you pass in a value of 10 USD and a quantity of 3, that will log to the user’s profile as three purchases of 10 dollars for a total of 30 dollars. Quantities must be less than or equal to 100. Values of purchases can be negative.

Adding properties

You can add metadata about purchases by either passing a BrazeProperties object with your purchase information.

Properties are defined as key-value pairs.

Braze.instance.logPurchase(
"productId",
"currencyCode",
1.23, // price
1, // quantity
new BrazeProperties()
.addProperty( "key", "value" )
);

Reserved keys

The following keys are reserved and cannot be used as purchase properties:

  • time
  • product_id
  • quantity
  • event_name
  • price
  • currency

Disabling SDK Tracking

In order to comply with data privacy regulations, data tracking activity on the SDK can be stopped entirely using the method disableSDK() . This method will cause all network connections to be canceled, and the Braze SDK will not pass any data to Braze’s servers. If you wish to resume data collection at a later point in time, you can use the enableSDK() method in the future to resume data collection.

Additionally, you can use the method wipeData() to fully clear all client-side data stored on the device.

- + \ No newline at end of file diff --git a/docs/braze/changelog/index.html b/docs/braze/changelog/index.html index 7e7a8fd76b8..8f65997aac3 100644 --- a/docs/braze/changelog/index.html +++ b/docs/braze/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.10.09 [v0.1.6]

fix(ios): correct crash on open from url via another app

2023.09.08 [v0.1.4]

fix(ios): add swift core link options
feat(docs): add docs for deep linking and in-app messages
- + \ No newline at end of file diff --git a/docs/braze/content-cards/index.html b/docs/braze/content-cards/index.html index f8343295286..4f7fac7ab75 100644 --- a/docs/braze/content-cards/index.html +++ b/docs/braze/content-cards/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Content Cards

- + \ No newline at end of file diff --git a/docs/braze/deep-linking/index.html b/docs/braze/deep-linking/index.html index 0af8657dc5a..08bb37c39e9 100644 --- a/docs/braze/deep-linking/index.html +++ b/docs/braze/deep-linking/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Deep Linking

Enabling

Deep links are enabled automatically however you will need to add a few additions to your application descriptor in order to receive them correctly.

iOS

On iOS add your custom url scheme to the CFBundleURLTypes array in your info additions. Replace CUSTOM_URL_SCHEME in the below with your scheme:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>CUSTOM_URL_SCHEME</string>
</array>
</dict>
</array>

Android

Add the following activity within the application node of your manifest additions. Replace CUSTOM_URL_SCHEME and CUSTOM_URL_PATH with your values:

<activity>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="CUSTOM_URL_SCHEME" android:host="CUSTOM_URL_PATH"/>
</intent-filter>
</activity>

This would open a url link of the form CUSTOM_URL_SCHEME://CUSTOM_URL_PATH, eg: distriqt://app

Events

When a deep link is received and determined to be from Braze the extension will dispatch a BrazeDeeplinkEvent.RECEIVED event:

Braze.instance.addEventListener( BrazeDeeplinkEvent.RECEIVED, deeplink_receivedHandler );

function deeplink_receivedHandler( event:BrazeDeeplinkEvent ):void
{
trace( "deeplink received" );
}

This event will contain a property uriAction which is an instance of the UriAction class and contains information relevant to the deep link, such as url, channel and any extras.

- + \ No newline at end of file diff --git a/docs/braze/in-app-messaging/index.html b/docs/braze/in-app-messaging/index.html index 195ac4ddd23..bc500d7b5ca 100644 --- a/docs/braze/in-app-messaging/index.html +++ b/docs/braze/in-app-messaging/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

In-App Messaging

In-app messages help you get content to your users without interrupting their day with a push notification. Customized and tailored in-app messages enhance the user experience and help your audience get the most value from your app. With various layouts and customization tools to choose from, in-app messages engage your users more than ever before.

Register

In order to receive in-app messages you must call register() in order to register the extension for the current application activity. This will now listen for in-app messages from Braze and automatically display them when they meet the conditions specified on the message.

Braze.instance.inAppMessaging.register();

If at any point you wish to stop receiving messages you can unregister by calling:

Braze.instance.inAppMessaging.unregister();

Creating Messages

Messages are created completely through the dashboard. Follow the guides and documentation in the Braze documentation.

Events

There are several events dispatched when an in-app message is received by your application:

  • BrazeInAppMessageEvent.BEFORE_DISPLAYED: Dispatched when a message is received but before it is displayed
  • BrazeInAppMessageEvent.OPENED: Dispatched when a message is opened and displayed to the user
  • BrazeInAppMessageEvent.BUTTON_CLICKED: Dispatched when a button in the message is clicked
  • BrazeInAppMessageEvent.DISMISSED: Dispatched when a message is dismissed

In your BrazeInAppMessageEvent.BEFORE_DISPLAYED event handler you must make a decision as to whether to display the message or not. You can also modify the content of the InAppMessage in this event handler as required.

Note:

  • if you don't add a BrazeInAppMessageEvent.BEFORE_DISPLAYED listener then the message will be displayed automatically;
  • if you add a listener you must call displayInAppMessage() to display the message.

For example:

function beforeDisplayedHandler( event:BrazeInAppMessageEvent ):void
{
var iam:InAppMessage = event.message;

// Modify message as required
iam.message = iam.message
.replace( "USERNAME", "John" );

// Display the message
Braze.instance.inAppMessaging.displayInAppMessage( iam );
}
- + \ No newline at end of file diff --git a/docs/braze/index.html b/docs/braze/index.html index c67e5854d70..de7c2ec17af 100644 --- a/docs/braze/index.html +++ b/docs/braze/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ gives access to the Braze SDK.

We provide complete guides to get you up and running with sharing quickly and easily.

Features:

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:


More information here:

com.braze

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/braze/integration/index.html b/docs/braze/integration/index.html index e60791a2dbf..1c39f8745c0 100644 --- a/docs/braze/integration/index.html +++ b/docs/braze/integration/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Integration

Configure your application

This extension requires you call the Core.init() function at some point early in your application, generally at the same time as the initialisation of this extension. If you are using other extensions that also require the Core extension, you only need to initialise it once, before initialising any of our extensions.

Core.init();

To configure the Braze SDK you will call configure() passing an instance of the BrazeConfig class which contains all the configuration information for your application.

Importantly you must set the apiKey and endpoint from the settings of your application in the Braze console:

var options:BrazeConfig = new BrazeConfig()
.setApiKey( "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" )
.setCustomEndpoint( "sdk.XXX-01.braze.eu" );

Braze.instance.configure( options );

The BrazeConfig class also contains a range of other configuration options.

Tracking user sessions

The sessions and in-app messaging subscriptions can optionally be handled be automatically.

To enable automatic handling call setSessionHandlingEnabled( true ), and setInAppMessagingRegistrationEnabled(true):

var options:BrazeConfig = new BrazeConfig()
...
.setSessionHandlingEnabled(true)
.setInAppMessagingRegistrationEnabled(true)
;

The first argument instructs the listener to handle openSession() and closeSession() calls. The second argument instructs the listener to handle inAppMessaging.register() and inAppMessaging.unregister() calls.

If you set these to false, ensure you call the appropriate session open and close calls in your application.

Test the integration

At this point, you should have session tracking working in your Braze integration. To test this, go to Overview, select your application from the selected app name dropdown (defaulted to “All Apps”), and set Display Data For to “Today”. Then open your app and refresh the page - your main metrics should all have increased by 1.

Logging

If you need to debug the Braze SDK calls you can control the log level using the setLogLevel() method:

Braze.instance.setLogLevel( BrazeLogLevel.VERBOSE );

Logging statements can be observed through the native logs (logcat for Android and the Console for iOS).

Advertising Identifier (Optional)

The Advertising ID is not automatically collected by the Braze SDK and must be set manually via the setAdvertisingId() method.

Braze.instance.setAdvertisingId( advertisingId, isLimitAdTrackingEnabled );

You can use the IDFA extension to retrieve these values if you require them.

- + \ No newline at end of file diff --git a/docs/braze/push-notifications/index.html b/docs/braze/push-notifications/index.html index 15bdc461f08..618035a5236 100644 --- a/docs/braze/push-notifications/index.html +++ b/docs/braze/push-notifications/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Push Notifications

Braze.instance.setRegisteredPushToken( token );
- + \ No newline at end of file diff --git a/docs/braze/unity/index.html b/docs/braze/unity/index.html index 49ec8a0e804..932cbffa79e 100644 --- a/docs/braze/unity/index.html +++ b/docs/braze/unity/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Unity

Contents

Overview

The Braze plugin gives you access

TODO

Features

TODO

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Add the Plugin

First step is always to add the plugin to your development environment.

Asset Store

Open the Asset Store in your browser and add the Braze plugin to your assets.

Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the Braze plugin, and click Import in the bottom right.

Manual Installation

In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.Braze.unitypackage.

You can manually download the extension from our repository:

Import the Plugin

This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

The plugin will be added to your project and you can now use the plugins functionality in your application.

Resolve Android Dependencies

This plugin depends on some common Android libraries, particularly the AndroidX support library.

You can get these dependencies using one of the following methods.

Unity Jar Resolver

This is the suggested method.

Use the Unity Jar Resolver plugin to download and manage the Android dependencies.

Importing

If you already use the Unity Jar Resolver in your project you can skip this step.

  • Download the latest version of the Unity Jar Resolver
  • Import the plugin by selecting Assets / Import Package / Custom Package ... and locate the plugin you downloaded. The plugin will be in the zip named: external-dependency-manager-latest.unitypackage
  • In the Import Unity Package window, click Import
Resolving

By default, the resolver should run automatically and will add the dependencies required by this plugin.

If you have need to resolve the dependencies manually then you will need to:

  • Open the menu under: Assets / External Dependency Manager / Android Resolver
  • Select Resolve or Force Resolve

More information on the Unity Jar Resolver can be found here

Custom Gradle Braze

Unity's in-built gradle build support and exporting to android studio does not support per plugin gradle script. Therefore, this plugin cannot add the dependencies by itself.

The mainBraze.gradle is generated when you enable the Custom Gradle Braze property on the Player window.

The build.gradle exists in generated Gradle project when you enable the Export Project property on the Player window and Build the project.

Update the dependencies section in your mainBraze.gradle or build.gradle as below:

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}

Usage

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Braze.isSupported)
{
// Functionality here
}

Support

If you need further support integrating or using this extension please feel free to contact us.

We have been supporting developers for over 10 years and always happy to help.





- + \ No newline at end of file diff --git a/docs/calendar/add-events/index.html b/docs/calendar/add-events/index.html index 57b247130ca..30914265567 100644 --- a/docs/calendar/add-events/index.html +++ b/docs/calendar/add-events/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add Events

Adding an event can be done silently or with a UI allowing the user to fill in additional information.

The following example creates an EventObject and sets the dates, associated alarm and recurrence settings, and then adds the event to the users calendar.

//  CREATE THE EVENT
var e:EventObject = new EventObject();
e.title = "Test title now";
e.startDate = new Date() ;
e.endDate = new Date();
e.startDate.minutes = e.startDate.minutes + 6;
e.endDate.hours = e.endDate.hours+1;

var a:EventAlarmObject = new EventAlarmObject();
a.offset = -1;
e.alarms.push( a );

var r:Recurrence = new Recurrence();
r.endCount = 5;
r.interval = 1;
r.frequency = Recurrence.FREQUENCY_DAILY;

e.recurrenceRules.push( r );

//
// ADD THE EVENT
Calendar.service.addEvent( e );
- + \ No newline at end of file diff --git a/docs/calendar/add-the-extension/index.html b/docs/calendar/add-the-extension/index.html index fe283fac13a..4298fdbc65d 100644 --- a/docs/calendar/add-the-extension/index.html +++ b/docs/calendar/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

You can access this extension here: https://github.com/distriqt/ANE-Core.

Android Support

The Android Support libraries encompass the Android Support, Android X and common Google libraries.

These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

This extension requires the following extensions:

You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

Note: if you have been using the older com.distriqt.androidsupport.* (Android Support) extensions you should remove these extensions and replace it with the androidx extensions listed above. This is the new version of the android support libraries and moving forward all our extensions will require AndroidX.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Calendar.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/calendar/changelog/index.html b/docs/calendar/changelog/index.html index 3a10b0d1682..cc8c2f8c760 100644 --- a/docs/calendar/changelog/index.html +++ b/docs/calendar/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.16 [v5.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.02.04 [v5.0.15]

Updates for Android 31
Update docs to use apm

2021.12.16 [v5.0.13]

Add air package parameter descriptions

2021.09.24 [v5.0.12]

Added air package 
Updated build to latest
Removed ios minimum version flag

2020.03.23 [v5.0.010]

Android X migration (resolves #29)

2019.08.16 [v4.0.005]

Android 64bit support (resolves #28)
Updated minimum iOS version to 9.0

2019.03.11 [v3.3.040]

Updated minimum iOS version to 8.0 (resolves #27)
Removed application keys

2019.02.11 [v3.2.038]

Embedded bitcode (resolves #26)

2017.07.10 [v3.1.032]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.02.20 [v3.1.031]

Updated documentation

2017.02.20 [v3.1.031]

Corrected handling of null attendee names (#21)

2016.12.21 [v3.1.021]

Updating documentation

2016.11.17 [v3.1.020]

iOS: Corrected iOS 10 issue with edit event (resolves #20)

2016.09.20 [v3.1.011]

Added retrieval of event participants (resolves #17)

2016.08.03

Updated Core library compatibility

2016.07.16

iOS: Corrected issue that caused UI events not to fire (resolves #15)

2016.07.16

iOS: Corrected issue that caused UI events not to fire (resolves #15)

2016.06.04

v2.0 Authorisation status update to support new Android runtime permissions (resolves #14)

2015.06.15

Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support
Removed debug code from AS lib

2015.06.09

Android: Windows: Fix for bug in AIR packager resulting in missing resources (#11)

2015.06.02

Removed Adobe classes. Repackaged to test #10

2015.04.22

Removed inclusion of Adobe date utils (resolves #9)

2015.04.02

Android: Fixed issue when no recurrence end date specified (resolves #7)
iOS: Moved to new shared utils framework

2015.02.27

Fixed issue when attempting to delete a recurring event (resolves #6)

2015.02.11

Android: Fixed issue with recurrence when no end date is specified (resolves #4)

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented ARC
iOS: Implemented autoreleasepools for all c function calls

2014.11.27

Updated README

2014.11.27

New application based key check, removing server checks

2014.11.03

iOS Update for iOS8
- iOS: Implemented new SDK functions and definitions
- + \ No newline at end of file diff --git a/docs/calendar/get-events/index.html b/docs/calendar/get-events/index.html index 4f59b2c6a4a..9dd4198b244 100644 --- a/docs/calendar/get-events/index.html +++ b/docs/calendar/get-events/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Get Events

The example below shows retrieving the list of events from yesterday until 2 days in the future.

//
// GET EVENTS
var startDate:Date = new Date();
startDate.date -= 1;
var endDate:Date = new Date();
endDate.date += 2;

var events:Array = Calendar.service.getEvents( startDate, endDate );
- + \ No newline at end of file diff --git a/docs/calendar/index.html b/docs/calendar/index.html index 71f77de2f93..60d7358b879 100644 --- a/docs/calendar/index.html +++ b/docs/calendar/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

We provide complete guides to get you up and running with asset selection quickly and easily.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the ASDocs.

Quick Example:

var e:EventObject = new EventObject();
e.title = "Test title now";
e.startDate = new Date() ;
e.endDate = new Date();
e.startDate.minutes = e.startDate.minutes + 6;
e.endDate.hours = e.endDate.hours+1;

Calendar.service.addEventWithUI( e );

More information here:

com.distriqt.Calendar

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/calendar/migrating-to-androidx/index.html b/docs/calendar/migrating-to-androidx/index.html index 5dd2aa3467e..fd16f87df8c 100644 --- a/docs/calendar/migrating-to-androidx/index.html +++ b/docs/calendar/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/calendar/migrating-to-v5.1/index.html b/docs/calendar/migrating-to-v5.1/index.html index bed9ab122d2..42a9a245488 100644 --- a/docs/calendar/migrating-to-v5.1/index.html +++ b/docs/calendar/migrating-to-v5.1/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v5.1

v5.1 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/calendar/request-authorisation/index.html b/docs/calendar/request-authorisation/index.html index bd9e8d6950f..b4e71d9796c 100644 --- a/docs/calendar/request-authorisation/index.html +++ b/docs/calendar/request-authorisation/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Request Authorisation

When you are going to be accessing the user's calendars you must check that your application has been allowed access. To this end the extension provides several helpers to check and request access to the contact list. Normal permission rules apply here.

On Android these permissions are listed through the manifest additions. On older versions of Android these permissions are accepted when the user installs the application. More modern versions (Marshmallow 6 [v23]+) require that you request the permissions similar to iOS. You will still need to list them in your manifest and then follow the same code below as for iOS, except that on Android you will be able to ask multiple times. You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

On iOS the user must be asked at runtime, which you only get one chance to ask, after which you must direct the user to manually change the permissions in the settings.

The following code will work across both platforms

Calendar.service.addEventListener( AuthorisationEvent.CHANGED, calendar_authorisationChangedHandler );

switch (Calendar.service.authorisationStatus())
{
case AuthorisationStatus.SHOULD_EXPLAIN:
case AuthorisationStatus.NOT_DETERMINED:
// REQUEST ACCESS: This will display the permission dialog
Calendar.service.requestAccess();
return;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
case AuthorisationStatus.RESTRICTED:
// ACCESS DENIED: You should inform your user appropriately
return;

case AuthorisationStatus.AUTHORISED:
// AUTHORISED: Calendars will be available
break;
}


function calendar_authorisationChangedHandler( event:AuthorisationEvent ):void
{
// Check event.status
}

Usage Description

You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

- + \ No newline at end of file diff --git a/docs/camera/add-the-extension/index.html b/docs/camera/add-the-extension/index.html index 21a3efdb079..18f9412b213 100644 --- a/docs/camera/add-the-extension/index.html +++ b/docs/camera/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Camera.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/camera/camera-modes/index.html b/docs/camera/camera-modes/index.html index 9fdf4b88443..252f84754d5 100644 --- a/docs/camera/camera-modes/index.html +++ b/docs/camera/camera-modes/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ as the camera mode, this way the mode won't be changed just before capture and the preview frame will be the same as the captured image. This has the side effect of reducing the preview frame rate as much more data needs to be captured and transferred.

- + \ No newline at end of file diff --git a/docs/camera/capturing-images/index.html b/docs/camera/capturing-images/index.html index e626be7a821..e665586c481 100644 --- a/docs/camera/capturing-images/index.html +++ b/docs/camera/capturing-images/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ relevant information.

private function captureComplete_Handler( event:CameraCaptureEvent ):void 
{
var result:CaptureImageResult = device.captureImageResult();
if (result != null && result.data != null)
{
// result.data will contain the BitmapData object captured
}
}

Note: The capture image result will be cleared as soon as it is retrieved or another request is made so you should hold onto the reference if you wish to use it in other places.

- + \ No newline at end of file diff --git a/docs/camera/changelog/index.html b/docs/camera/changelog/index.html index b920d92db34..4ef1fe42199 100644 --- a/docs/camera/changelog/index.html +++ b/docs/camera/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.09.04 [v6.2.0]

feat(android): update permission process and image saving to support latest android api changes (resolves #159)

2023.01.16 [v6.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.02.04 [v6.0.28]

Updates for Android 31
Update docs to use apm

2021.12.16 [v6.0.27]

Add air package parameter descriptions

2021.09.24 [v6.0.26]

Added air package
Added android x64 support
Removed ios minimum version flag
Updated build

2020.03.23 [v6.0.022]

Android X migration (resolves #147)
Android: Added additional camera connection error handling (resolves #146)

2019.10.17 [v5.0.011]

Android: Corrected renderscript issue with Android 64bit builds (resolves #144)

2019.08.16 [v5.0.007]

Android 64bit support (resolves #141)
Updated minimum iOS version to 9.0

2019.02.22 [v4.4.081]

Updated minimum iOS version to 8.0 (#137)

2019.01.25 [v4.3.076]

Android: Corrected camera mode connect issue on legacy hardware (resolves #134)

2018.09.13 [v4.3.071]

iOS: Fix for iPhone 5/5s front camera where focus modes not supported (resolves #126)

2018.03.16 [v4.2.033]

Corrected iOS video recording orientation issues (resolves #119)

2017.07.14 [v4.1.008]

Added ability to open device settings (resolves #103)

2017.07.10 [v4.0.128]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.06.21 [v4.0.127]

Updated documentation and examples for Starling 2.x

2017.02.06 [v4.0.127]

Updated docs:

2017.02.06 [v4.0.127]

Added field of view (resolves #95)
Android: Corrected some issues with focus adjustments (#94)

2017.01.18 [v4.0.125]

Updated documentation

2017.01.18 [v4.0.125]

Updated default lib to v4.0

2017.01.18 [v4.0.124]

Major Release - Version 4.0

2016.06.15

Removed unused packaged libs to reduce filesize

2016.06.15

Added permissions check and requests for microphone and cameraroll (resolves #69)

2016.03.08

Android: Implemented the auth status for Android M permissions (resolves #60)

2016.02.20

Corrected file size (#58)

2016.02.19

Updated documentation

2016.02.19

Added authorisation status to check for camera permission (resolves #55, resolves #53)

2015.10.26

Android: Added code to reinitialise camera if it gets into an invalid state (#27)

2015.10.01

Android: Huge speed increase for processing BitmapData from captureImage (#27)
Android: Fix for auto focus not completing causing functionality loss when waiting for adjustments (#27)
Android: Potential fix for camera falling into invalid state after captureImage (#40)
Android: Autofocus events update should now receive correct events in continous focus mode (#28)

2015.09.11

Android: isSupported update to correct for SDK < 17
Android: Corrected orientation exif data on captured images (#37)

2015.09.11

Updated example

2015.09.11

Android: Corrected issue with accessing parameters and modes after initialisation (#40)

2015.06.17

Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources (resolves #21)

2015.06.04

Android: Fixed issue with using 'default' device (resolves #19)

2015.06.03

iOS: Video recording functionality including start/stop
Android: x86 Support
Android: Fixed image shearing on some devices (resolves #13)
Android: Moved to SurfaceTexture rendering to solve small preview window appearance on some devices
Android: Corrected isSupported flag on devices with only a front facing camera
Android: Corrected event JSON parse error (resolves #14)
iOS: Performance improvements
Moved to new structure to support FlashBuilder 4.6

2015.04.15

Moved to new structure to support FlashBuilder 4.6 (resolves #9)

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #2) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.01

Updated documentation

2014.12.01

Updating README

2014.12.01

New application based key check, removing server checks

30-10-14

iOS Update for iOS 8
- iOS: Project and type updates for iOS 8
- iOS: Fixes #226 when adjustments weren't correctly being waited for before first image
- iOS: Updated documentation to provide information about focus and exposure points (#227)
- + \ No newline at end of file diff --git a/docs/camera/connecting/index.html b/docs/camera/connecting/index.html index 2168bfca300..2e8fb8ba6de 100644 --- a/docs/camera/connecting/index.html +++ b/docs/camera/connecting/index.html @@ -13,7 +13,7 @@ - + @@ -32,7 +32,7 @@ be a good app citizen and allow other applications to connect when your application isn't in focus.

To disconnect we call the disconnect function on the CameraDevice instance:

var success:Boolean = device.disconnect();

We suggest you also remove any preview frame listeners and have completed any operations before calling this function.

- + \ No newline at end of file diff --git a/docs/camera/index.html b/docs/camera/index.html index f83d00e60e8..10955e4f596 100644 --- a/docs/camera/index.html +++ b/docs/camera/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Camera

The Camera extension provides access to advanced features of the camera not available through the AIR SDK.

This includes access to the flash modes, exposure, white balance, and focus point control.

Additionally this extension allows you to take a photo using the camera while simultaneously saving it to the camera roll and accessing it in your AIR application as BitmapData.

Please note this is not a replacement for the flash.media.CameraUI class but gives you the ability to build your own.

If you are looking for a Camera UI replacement see the CameraUI extension.

Identical code base can be used across all supported platforms allowing you to concentrate on your application and not device specifics.

Features

  • Allows control of the camera's functionality on iOS and Android including: flash, exposure, white balance, focus, focus point and others;
  • Raw access to the camera preview frames;
  • Capture an image and access BitmapData;
  • Compatible with most Android devices and iOS 5+ devices which include a flash;
  • Sample project code and ASDocs reference

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.Camera

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/camera/migrating-to-androidx/index.html b/docs/camera/migrating-to-androidx/index.html index b02e65830b3..b0134d99740 100644 --- a/docs/camera/migrating-to-androidx/index.html +++ b/docs/camera/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/camera/migrating-to-v6.1/index.html b/docs/camera/migrating-to-v6.1/index.html index 8fa7865c97e..c8383d6d1b1 100644 --- a/docs/camera/migrating-to-v6.1/index.html +++ b/docs/camera/migrating-to-v6.1/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v6.1

v6.1 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/camera/parameters-exposure/index.html b/docs/camera/parameters-exposure/index.html index 2d5c3e9848a..77713e4f496 100644 --- a/docs/camera/parameters-exposure/index.html +++ b/docs/camera/parameters-exposure/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ in landscape mode with the home button on the right—this applies even if the device is in portrait mode.

To set this point call the setExposurePointOfInterest() function with the point of interest required. For example to set the middle of the capture area:

device.setExposurePointOfInterest( new Point( 0.5, 0.5 ) );
- + \ No newline at end of file diff --git a/docs/camera/parameters-flash/index.html b/docs/camera/parameters-flash/index.html index 062528a2cd8..b92f10ae63d 100644 --- a/docs/camera/parameters-flash/index.html +++ b/docs/camera/parameters-flash/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ will use when capturing.

Availability

There are two availability checks associated with the flash,

These two are provided as some devices will contain a flash but not support the torch mode, and some devices may not contain a flash at all.

Torch mode is a mode where the flash is turned on permanently.

Changing Modes

You can control the mode the flash will use when capturing photos by calling the setFlashMode function on a device.

The available flash modes are defined in the CameraParameters class:

For example to turn the flash on permanently:

if (device.isTorchSupported())
{
device.setFlashMode( CameraParameters.FLASH_MODE_TORCH );
}
- + \ No newline at end of file diff --git a/docs/camera/parameters-focus/index.html b/docs/camera/parameters-focus/index.html index 15b4ac3930f..f533f02fd33 100644 --- a/docs/camera/parameters-focus/index.html +++ b/docs/camera/parameters-focus/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ in landscape mode with the home button on the right—this applies even if the device is in portrait mode.

To set this point call the setFocusPointOfInterest() function with the point of interest required. For example to set the middle of the capture area:

device.setFocusPointOfInterest( new Point( 0.5, 0.5 ) );
- + \ No newline at end of file diff --git a/docs/camera/parameters-white-balance/index.html b/docs/camera/parameters-white-balance/index.html index c7f50092787..4abcab63d9a 100644 --- a/docs/camera/parameters-white-balance/index.html +++ b/docs/camera/parameters-white-balance/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Parameters-White Balance

White Balance

The white balance modes can be controlled using this extension.

The available white balance modes are defined in the CameraParameters class:

  • CameraParameters.WHITE_BALANCE_MODE_LOCKED: The white balance setting is locked
  • CameraParameters.WHITE_BALANCE_MODE_AUTO: The device performs an auto white balance operation now
  • CameraParameters.WHITE_BALANCE_MODE_CONTINUOUS: The device continuously monitors white balance and adjusts when necessary

Availability

White balance modes aren't available on all devices so it's important that you check whether the device supports the mode before attempting to set it.

if (device.isWhiteBalanceSupported( CameraParameters.WHITE_BALANCE_MODE_CONTINUOUS ))
{
// Continuous exposure mode is supported
}

Changing Modes

To set the white balance mode simply call setWhiteBalanceMode with the required mode

if (device.isWhiteBalanceSupported( CameraParameters.WHITE_BALANCE_MODE_CONTINUOUS ))
{
device.setWhiteBalanceMode( CameraParameters.WHITE_BALANCE_MODE_CONTINUOUS );
}
- + \ No newline at end of file diff --git a/docs/camera/preview-frames/index.html b/docs/camera/preview-frames/index.html index d5dc8e19842..e2b8b7525ad 100644 --- a/docs/camera/preview-frames/index.html +++ b/docs/camera/preview-frames/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ quickly, attempting to keep the frame rate of your preview frame as high as possible.

To render the data you should create an appropriately sized BitmapData object and use the setPixels to update the bitmap data from the ByteArray.

Firstly lets create the bitmap data:

var _previewBitmapData:BitmapData = new BitmapData( 1, 1, false );
var _previewBitmapRect:Rectangle = new Rectangle( 0, 0, 1, 1 );

//
// Check we have an appropriately sized bitmapdata and texture
// Recreate if not
if (_previewBitmapData.width != device.width || _previewBitmapData.height != device.height)
{
trace( "resizing to: (" + device.width +", "+ device.height +")" );
_previewBitmapData.dispose();

_previewBitmapData = new BitmapData( device.width, device.height, false );

_previewBitmapRect = new Rectangle( 0, 0, _previewBitmapData.width, _previewBitmapData.height );
}

Then in our event handler we update from the frame buffer.

private function camera_videoFrameHandler( event:CameraEvent ):void 
{
if (-1 != device.getFrameBuffer( _previewData ))
{
try
{
//
// Update the bitmapdata and texture
_previewBitmapData.setPixels( _previewBitmapRect, _previewData );

// For Starling 1.x
// flash.display3D.textures.Texture(_previewTexture.base).uploadFromBitmapData( _previewBitmapData );

// For Starling 2.x
flash.display3D.textures.RectangleTexture(_previewTexture.base).uploadFromBitmapData( _previewBitmapData );
}
catch (e:Error)
{
trace( e );
}
finally
{
_previewData.clear();
_lastFrameProcessed = frame;
}
}
}

We also suggest you rotate the container of your bitmap data to match the orientation of the camera device. You should use the device.info.orientation value to rotate appropriately.

See the example applications for demonstrations of this, and the following gists:

- + \ No newline at end of file diff --git a/docs/camera/requesting-authorisation/index.html b/docs/camera/requesting-authorisation/index.html index e97a6e5d60a..9da294167ed 100644 --- a/docs/camera/requesting-authorisation/index.html +++ b/docs/camera/requesting-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ and then redirect them to your application device settings, which will allow your user to change the setting.

This is especially important on iOS where you only get one attempt to ask your user for permission.

To redirect your user simply call the openDeviceSettings() function. You can use the canOpenDeviceSettings flag to check if the current device supports this functionality.

if (Camera.instance.canOpenDeviceSettings)
{
Camera.instance.openDeviceSettings();
}
- + \ No newline at end of file diff --git a/docs/camera/selecting-a-device/index.html b/docs/camera/selecting-a-device/index.html index 380f203fabe..599d7def05e 100644 --- a/docs/camera/selecting-a-device/index.html +++ b/docs/camera/selecting-a-device/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Most devices have several cameras, generally a lower spec front camera and high spec back camera.

To get a list of the available devices you can use the getAvailableDevices function:

var devices:Array = Camera.instance.getAvailableDevices();
for each (var deviceInfo:CameraDeviceInfo in devices)
{
if (deviceInfo.position == CameraDeviceInfo.POSITION_BACK)
{
// This is the back camera
}
}

This function returns an array of CameraDeviceInfo objects each describing a camera device.

The CameraDeviceInfo class not only contains the position of the camera, (front, back etc) but the available modes of the camera, for both previewing and capturing images, and information about additional hardware, such as a flash.

- + \ No newline at end of file diff --git a/docs/camerarollextended/add-the-extension/index.html b/docs/camerarollextended/add-the-extension/index.html index 552cf37be08..17b83348328 100644 --- a/docs/camerarollextended/add-the-extension/index.html +++ b/docs/camerarollextended/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ when certain permissions are requested. If you are sharing images then there is a chance the user may select to save to their camera roll in which case a dialog is displayed the first time your user attempts to access the camera roll.

There are 2 keys required here that control the text in this dialog:

<key>NSPhotoLibraryUsageDescription</key>
<string>Access to photo library is required to save images.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Access to photo library is required to save images.</string>

The second key was added in iOS 11.2. You should add both keys to your info additions.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (CameraRollExtended.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/camerarollextended/adding-files/index.html b/docs/camerarollextended/adding-files/index.html index 4c66c4e8c7f..dcf7f7b224a 100644 --- a/docs/camerarollextended/adding-files/index.html +++ b/docs/camerarollextended/adding-files/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Adding Images and Video

Adding BitmapData

With the standard CameraRoll implementation you can easily add a BitmapData reference to the camera roll, using the addBitmapData function.

This functionality is also duplicated in this extension:

var bd:BitmapData = ...;

CameraRollExtended.service.addBitmapData( bd );

We have added some additional options around this function that allow you to control the format, quality and filename.

CameraRollExtended.service.addBitmapData( bd, "png", 1, "plane.png" );

The format can either be "png" or "jpg" and the quality should be a number between 0 (lowest quality) and 1 (highest quality). The default is "jpg" at 0.8

The filename is used as the name of the file on Android.

Adding files

You may have image files that you wish to add to the camera roll without have to load the bitmap data into memory, and you may also have video content that you want to add to the camera roll.

To achieve this you can use the addFile() function, passing the File reference to the file you wish to add to the camera roll.

var video:File = File.applicationDirectory.resolvePath("assets/video.mp4");

var success:Boolean = CameraRollExtended.service.addFile( video, Asset.VIDEO );

If the functionality is not supported or there was an error initiating the transfer to the camera roll then this function may return false. If it returns true, the process was started successfully and you can expect one of the following events:

  • CameraRollExtendedEvent.ADD_FILE_COMPLETE: When the file was successfully transferred to the camera roll;
  • CameraRollExtendedEvent.ADD_FILE_ERROR: If there was an error.
CameraRollExtended.service.addEventListener( CameraRollExtendedEvent.ADD_FILE_COMPLETE, addFile_completeHandler );
CameraRollExtended.service.addEventListener( CameraRollExtendedEvent.ADD_FILE_ERROR, addFile_errorHandler );

CameraRollExtended.service.addFile( video, Asset.VIDEO );

function addFile_completeHandler( event:CameraRollExtendedEvent ):void
{
trace( "addFile_completeHandler()" );
}

function addFile_errorHandler( event:CameraRollExtendedEvent ):void
{
trace( "addFile_errorHandler(): ["+event.errorCode+"] :: " + event.message );
}

Android

If you are supporting Android < API v28 then you will need to ensure you add the WRITE_EXTERNAL_FILES permission to your application.

If you are using apm all you can generate a custom configuration manifest and then add the additional permission to that.

apm generate config android 

Open the file generated at config/android/AndroidManfiest.xml and ensure you add the following line:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

Then regenerate your application descriptor:

apm generate app-descriptor src/MyApp-app.xml

If you are manually managing your application descriptor (and manifest additions) then you will need to add the following line to the <manifestAdditions> tag in your application descriptor:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
- + \ No newline at end of file diff --git a/docs/camerarollextended/browse-for-an-asset/index.html b/docs/camerarollextended/browse-for-an-asset/index.html index 329943f4a89..1735045217a 100644 --- a/docs/camerarollextended/browse-for-an-asset/index.html +++ b/docs/camerarollextended/browse-for-an-asset/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Browse for an Asset

To ask the user to select an asset (or multiple assets) you will need to call the browseForAsset() function. This will present the user interface and allow the user to select an asset from their device. In the following events you will get information about the selected items as Asset objects which you can use to load the asset as you require.

You can limit what the user is presented with and allowed to select by changing the options in the CameraRollExtendedBrowseOptions.

The extension will dispatch one of two events to determine the result of the browse,

  • CameraRollExtendedEvent.CANCEL: Indicates the user cancelled the browsing operation and no assets where selected
  • CameraRollExtendedEvent.SELECT: Indicates the user selected an asset(s) and the details of the assets will be attached to the event

The following example shows selection of up to 5 images:

CameraRollExtended.service.addEventListener( CameraRollExtendedEvent.CANCEL, cancelHandler );
CameraRollExtended.service.addEventListener( CameraRollExtendedEvent.SELECT, selectHandler );

var options:CameraRollExtendedBrowseOptions = new CameraRollExtendedBrowseOptions();

options.maximumCount = 5;
options.type = Asset.IMAGE;

CameraRollExtended.service.browseForAsset( options );



function cancelHandler( event:CameraRollExtendedEvent ):void
{
trace( "camera roll cancelled" );
}

function selectHandler( event:CameraRollExtendedEvent ):void
{
trace( "camera roll select" );
for each (var asset:Asset in event.assets)
{
trace( asset.toString() );
}
}

iOS

From iOS 14, Apple provides a very functional native picker (PHPickerViewController) which will now be used when available.

Previous versions of iOS will use a custom UI asset picker.

The functionality in the native implementation is slightly different in that the "auto close on count reached" feature will only work when only one asset is being selected and cannot be disabled in this case.

Limited Authorisation

When presenting the photo picker unfortunately iOS does not apply this limitation to the assets the user can select. So your user may select assets that you don't have access to.

In order to identify this situation you can access a limited property on the SELECT event that informs you that the user selected some assets that your application cannot access.

CameraRollExtended.service.addEventListener( CameraRollExtendedEvent.SELECT, selectHandler );

function selectHandler( event:CameraRollExtendedEvent ):void
{
if (event.limited)
{
// User selected assets that cannot be accessed
}
}

You then can inform your user of the situation and if allow them to change their limitation by changing the selection of the limited assets or by changing the permissions.

To present a dialog to change the selection of limited assets you can call requestAuthorisation(). When the authorisation status is "limited" this method will display the selection dialog:

You will receive an authorisation changed event on completion and can use that to proceed to browse for an asset again.

Alternatively you may ask the user to change the permission level through the device settings.

Android

With Android there are a two distinct implementations, a custom UI built to provide similar functionality as on iOS, and the native implementation.

The native implementation has the advantage of being closely integrated with the system allowing a user to select an image from a range of media. However this varies betweens versions of Android and does not support most of the browse options.

The custom implementation is a little more limited in that it can only select from media that the application can access through the system content provider. However this implementation allows you to control the number of images and other options more easily.

To switch between these methods you set the useNativePicker option on the CameraRollExtendedBrowseOptions instance:

var options:CameraRollExtendedBrowseOptions = new CameraRollExtendedBrowseOptions();

options.useNativePicker = true;

CameraRollExtended.service.browseForAsset( options );

We highly recommend using the native picker however feel free to try the custom implementation and see if it suits your needs.

- + \ No newline at end of file diff --git a/docs/camerarollextended/changelog/index.html b/docs/camerarollextended/changelog/index.html index 4212d0c1e4a..011d4e55089 100644 --- a/docs/camerarollextended/changelog/index.html +++ b/docs/camerarollextended/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.09.16 [v7.0.2]

fix(android): correct issue with load asset using best fit when image required rotation (resolves #146)

2023.06.12 [v7.0.1]

fix(android): update authorisation process for Android 33+ (resolves #141)
feat(android,ios): add native addBitmapData and improve addFile functionality to support latest Android implementations

2023.01.16 [v6.4.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #140)
feat(android): Move to new permissions request process

2022.03.29 [v6.3.0]

Add support for limited authorisation on iOS where a user selects a subset of photos for access 
Add ability to display limited selection change dialog

2022.02.04 [v6.2.2]

Updates for Android 31
Update docs to use apm

2021.12.15 [v6.2.1]

Update air package parameter descriptions

2021.11.09 [v6.2.0]

Implement iOS native browse view controller on iOS 14+ (resolves #138)
Update iOS load asset resizing process for iOS 15 changes (resolves #135)

2021.09.24 [v6.1.10]

Added air package 
Updated build to latest
Removed ios minimum version flag

2021.06.29 [v6.1.9]

Updated iOS modal presentation style to correctly dispatch cancel event (resolves #134)

2021.06.15 [v6.1.007]

Android: Corrected issue with parcelable extra with mutliple select browse on certain devices (resolves #133)

2020.09.01 [v6.0.001]

Updated Picasso library usage to latest release including latest androidx usages (for compatibility with Firebase In App Messaging)

2020.05.15 [v5.1.069]

Fixed compatibility issue with other ANEs containing dynamic frameworks

2020.03.24 [v5.0.058]

Android X migration (resolves #128)

2020.03.12 [v4.1.045]

iOS: Removed usage of available flags (resolves #127)

2020.01.20 [v4.1.044]

Dark mode support (resolves #124)

2019.10.01 [v4.0.033]

Android 64bit support (resolves #122)
Android: Implemented Assets functionality (resolves #114, resolves #113, resolves 3)
Added open setting functionality
Android: Fixed crash with legacy loadAssetByURL (resolves #115, resolves #120)
Added ability to add file directly (resolves #112)

2019.03.12 [v3.6.071]

Updated minimum iOS version to 8.0
Embedded iOS bitcode
Removed application keys

2018.09.20 [v3.4.043]

Extracted square open source library to resolve conflict (resolves #110)

2018.02.01 [v3.4.040]

Correctly returned ASSET_ERROR when image is too large for a BitmapData (resolves #107)
iOS: Fixed issues with videos in iCloud (resolves #73)

2017.08.28 [v3.4.030]

iOS library updates for range of bug fixes (#99)

2017.07.10 [v3.3.025]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.06.13 [v3.3.024]

Android: Updated dependent libraries (#98)
Added minimum count (resolves #82)

2017.05.23 [v3.2.012]

Android: Added correct loading from content provider sources (resolves #97)

2017.01.09 [v3.1.009]

iOS: Corrected iOS 7 build (resolves #83)

2016.12.23 [v3.1.007]

Updating documentation

2016.11.28 [v3.1.002]

Updated documentation

2016.11.28 [v3.1.002]

Updated documentation

2016.11.28 [v3.1.002]

Android: Removed max count of selection to bring custom picker inline with native (resolves #67) 
iOS: Fix for cancel with no assets (resolves #71)

2016.10.31 [v3.0.011]

Complete rewrite for asset browser
iOS: iCloud corrupted images fix (resolves #56)

2016.06.22

iOS: Rebuild for iOS 8+ for display issues (resolves #64)
Android: Added retrieval of video orientation (resolves #65)

2016.05.27

Android: Added retrieval of video dimensions (resolves #62)

2016.05.03

iOS: Added new iOS 9 method of retrieving asset filename (resolves #60)
Android: Corrected thumbnail generation in custom picker (resolves #31)

2016.04.07

Added getFileForAssetAsync to handle iOS API change (resolves #54)

2016.03.08

Android: Implemented the auth status for Android M permissions (resolves #48)

2016.03.03

iOS: Corrected issue with autoCloseOnCountReached (resolves #50)

2016.02.19

Added some additional checks when disposing the extension (resolves #46)

2016.02.12

Android: Fixed some issues with asset loading and permissions (#42)

2016.02.03

iOS: Fix for language definition error (#40)

2016.02.02

iOS: Fixed issue with iOS 8 causing crash on load

2016.02.01

Android: Memory optimisations for large images (#38)

2016.01.28

iOS: Resolved issue with loading images from My Photo Stream (resolves #39)
Android: Improved memory handling
Android: Resolved issue with multiple fast sequential asset loads (#38)

2016.01.15

Fixed issue with loading a deleted asset (resolves #37)

2015.12.09

Updated examples

2015.12.09

Android support (resolves #1)
Added getFileForAsset function to retrieve a File instance for an Asset (resolves #16, resolves #32)
Android: Fixed back button interaction on non native picker (resolves #30)
Android: Implemented hasAccess + authorisationStatus functions (resolves #35)
Android: Fixed browsing of both VIDEO and IMAGE (resolves #33)
Android: Improved asset loading procedure (resolves #36)
iOS: Moved to the new Photos Framework for iOS > 8 (resolves #20)
iOS: Corrected whitespace in newer screen resolutions (resolves #17)
iOS: Memory improvements (#34, #19, #22, #15)
iOS: Added indicators to videos to separate from images (resolves #11)
iOS: Allowed selection from different albums (iOS > 8) (resolves #9)

2015.10.20

Updated default lib with new authorisation functions

2015.10.20

iOS: Added ability to check whether the user has granted access to photos (resolves #28)

2015.09.02

Android: Corrected loading of thumbnails, added video browsing, general improvements

2015.08.31

Android Beta Version (#1)

2015.06.15

iOS: Updated to latest common lib
Removed debug code from AS lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources

2015.02.27

Changed class structure to support FlashBuilder 4.6 (#10)

2015.02.02

Added check for .debug suffix in application id

2015.01.22

iOS: Implemented reading of the asset Exif and GPS data, added 'metadata' and 'location' variables to the Asset class to hold this information (resolves #3)

2015.01.22

iOS: Implemented reading of the asset Exif and GPS data, added 'metadata' and 'location' variables to the Asset class to hold this information (resolves #3)

2014.12.18

iOS: Included arm64 support (resolves #2) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.01

Updated README

2014.10.29

iOS Update for iOS 8
- iOS: Added new iOS8 process for loading images from Photo Stream (fixes #254, fixes #247)
- + \ No newline at end of file diff --git a/docs/camerarollextended/file-access/index.html b/docs/camerarollextended/file-access/index.html index c28ec417ec5..9ff0f03bf62 100644 --- a/docs/camerarollextended/file-access/index.html +++ b/docs/camerarollextended/file-access/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

File Access

Asynchronous Access

If you wish to access the bytes of the asset directly, or access a video file you will most likely want to get a File object access to the Asset.

This is not as simple as it would seem as both operating systems restrict access to certain media assets on the device, so commonly the extension will copy the asset to your application and give you access to that file.

You must be aware that after calling the getFileForAssetAsync function you may have a copy of the asset contained in your application storage.

var asset:Asset = ... ; // Asset retrieved via user selection (browseForAsset)

CameraRollExtended.service.addEventListener( AssetFileEvent.FILE_FOR_ASSET_COMPLETE, assetFile_completeHandler );
CameraRollExtended.service.addEventListener( AssetFileEvent.FILE_FOR_ASSET_ERROR, assetFile_errorHandler );

CameraRollExtended.service.getFileForAssetAsync( asset );


function assetFile_completeHandler( event:AssetFileEvent ):void
{
var f:File = event.file;
if (f.exists) message( "ASSET FILE:: "+ f.nativePath + "("+f.size+")");
else message( "ASSET FILE:: "+ f.nativePath + " (ERROR:doesn't exist!) " );
}

function assetFile_errorHandler( event:AssetFileEvent ):void
{
trace( "FAILED TO GET FILE" );
}

Direct Access

This method using direct access is not as reliable and will fail in more recent versions of iOS.

We don't recommend using this method. It has been deprecated and most likely remove it in a future release.

var asset:Asset = ... ; // Asset retrieved via user selection (browseForAsset)

var f:File = CameraRollExtended.service.getFileForAsset( asset );
if (f != null && f.exists)
{
trace( "ASSET FILE: "+f.nativePath );
// Use File as you require
}
- + \ No newline at end of file diff --git a/docs/camerarollextended/index.html b/docs/camerarollextended/index.html index b990a4ebf65..e22e7df1425 100644 --- a/docs/camerarollextended/index.html +++ b/docs/camerarollextended/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics. You can select multiple assets, including images and videos and access them either as BitmapData or through File access.

We provide complete guides to get you up and running with asset selection quickly and easily.

Features:

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

var options:CameraRollExtendedBrowseOptions = new CameraRollExtendedBrowseOptions();
options.autoCloseOnCountReached = true;
options.autoLoadBitmapData = true;
options.autoLoadType = AssetRepresentation.THUMBNAIL;

CameraRollExtended.service.browseForImage( options );

More information here:

com.distriqt.Application

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/camerarollextended/loading-an-asset/index.html b/docs/camerarollextended/loading-an-asset/index.html index 5522c5638aa..9e2911acdb6 100644 --- a/docs/camerarollextended/loading-an-asset/index.html +++ b/docs/camerarollextended/loading-an-asset/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Loading an Asset

To load an image asset use the loadAsset() function passing an Asset reference and a constructed AssetRequest.

To load an asset you firstly need to have retrieved an Asset reference from the extension.

Once you have a reference to the asset you wish to load, you will construct an AssetRequest to specify the version of the asset to retrieve. This allows you to load a version of the asset that suits your usage specifying the width and height of the loaded data. This is so you don't have to allocate memory to accomodate the entire image and additionally this ensures that the loading and resizing of the image data is done as quickly as possible, reducing the load on the cpu of the device.

To construct an AssetRequest use the properties on the AssetRequest class. You must at least set a width and height to be used.

var request:AssetRequest = new AssetRequest()
.setResizeMethod( AssetRequest.RESIZE_FILL )
.setWidth( 400 )
.setHeight( 400 );

or

var request:AssetRequest = new AssetRequest( 400, 400, AssetRequest.RESIZE_FILL );
note

The width and height requested may not exactly be the size of the image returned. The native system may opimise the request and provide a slightly smaller image in order to improve the speed of the request. You should make sure to correctly handle the size of the returned image and not rely on the request size.

Once you have your Asset and AssetRequest you can initiate the load:

var success:Boolean = CameraRollExtended.service.assets.loadAsset( asset, request );

The loadAsset() call when initiated successfully will dispatch an event when complete:

  • AssetEvent.ASSET_LOADED: If the load was successfully completed;
  • AssetEvent.ASSET_ERROR: If an error occurred during the load
CameraRollExtended.service.assets.addEventListener( AssetEvent.ASSET_LOADED, assetLoadedHandler );
CameraRollExtended.service.assets.addEventListener( AssetEvent.ASSET_ERROR, assetErrorHandler );

CameraRollExtended.service.assets.loadAsset( asset, request );


function assetLoadedHandler( event:AssetEvent ):void
{
// event.image will contain the bitmap data loaded
updateImage( event.image );
}


function assetErrorHandler( event:AssetEvent ):void
{
trace( "load asset error: " + event.message );
}

Preset Requests

To simplify creating requests there are some common preset requests that you may wish to use.

  • THUMBNAIL: Returns a thumbnail representation of the asset. The size of the thumbnail is the appropriate size for the platform, and in the correct orientation.
  • ASPECT_RATIO_THUMBNAIL: This representation contains an image with an aspect ratio thumbnail of the asset. The size of the thumbnail is the appropriate size for the platform, and in the correct orientation.
  • FULL_RESOLUTION: This representation contains the biggest, best representation available. Use this mode sparingly as it will require a significant amount of memory.
  • DISPLAY_RESOLUTION: This request will load an image that is big enough to cover the entire device screen.

To use these presets simply pass the preset to the loadAsset() function instead of a constructed request:

CameraRollExtended.service.assets.loadAsset( 
asset,
AssetRequest.ASPECT_RATIO_THUMBNAIL
);

Resize Methods

When constructing your AssetRequest you can pass several different values to the setResizeMethod() which controls how the asset will be resized to the specified width and height.

  • RESIZE_NONE: The image will not be resized and the original image data returned
  • RESIZE_BEST_FIT: This method will best fit the image to inside the specified width and height dimensions. The result will be smaller than or equal to the specified dimensions. No cropping will occur
  • RESIZE_FILL_NO_CROP: This method takes the smallest size of the image (either width or height) and makes it equal to the specified width or height value. This is very similar to the RESIZE_BEST_FIT method except that rather than fitting inside the width and height, the result will fill the width and height specified.
  • RESIZE_FILL: This method fills the specified size, scaling content to fill the entire area and cropping any content falling outside.

Example:

var request:AssetRequest = new AssetRequest()
.setResizeMethod( AssetRequest.RESIZE_FILL_NO_CROP )
.setWidth( 400 )
.setHeight( 400 );
- + \ No newline at end of file diff --git a/docs/camerarollextended/loading-as-asset---deprecated/index.html b/docs/camerarollextended/loading-as-asset---deprecated/index.html index 4e30283c606..0dd32e63a7d 100644 --- a/docs/camerarollextended/loading-as-asset---deprecated/index.html +++ b/docs/camerarollextended/loading-as-asset---deprecated/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Loading as Asset - Deprecated

Deprecated API

This API is no longer recommended and is only here for historical reference until we remove the API

Once your user has selected an asset you can then load the asset from the device. Image assets can be loaded into a BitmapData structure using the loadAssetByURL function.

The example below shows loading an image Asset using this method:

var asset:Asset = ... ; // Asset retrieved via user selection (browseForAsset)

if (asset.type == Asset.IMAGE)
{
CameraRollExtended.service.addEventListener( CameraRollExtendedEvent.ASSET_LOADED, assetLoadedHandler );
CameraRollExtended.service.loadAssetByURL( asset.url, AssetRepresentation.THUMBNAIL );
}


function assetLoadedHandler( event:CameraRollExtendedEvent ):void
{
var asset:Asset = event.assets[0];
var bitmap:Bitmap = new Bitmap( asset.bitmapData );
addChild( bitmap );
}
- + \ No newline at end of file diff --git a/docs/camerarollextended/migrating-to-androidx/index.html b/docs/camerarollextended/migrating-to-androidx/index.html index ffb58782a4b..3769e648d7b 100644 --- a/docs/camerarollextended/migrating-to-androidx/index.html +++ b/docs/camerarollextended/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/camerarollextended/migrating-to-v6.4/index.html b/docs/camerarollextended/migrating-to-v6.4/index.html index 4341e703841..8c4fac30560 100644 --- a/docs/camerarollextended/migrating-to-v6.4/index.html +++ b/docs/camerarollextended/migrating-to-v6.4/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v6.4

v6.4 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/camerarollextended/migrating-to-v7.0/index.html b/docs/camerarollextended/migrating-to-v7.0/index.html index 671cdc599a0..fe0a8a26c24 100644 --- a/docs/camerarollextended/migrating-to-v7.0/index.html +++ b/docs/camerarollextended/migrating-to-v7.0/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v7.0

v7.0 brings a complete rewrite of the authorisation process for Android. The API remains the same however there is a change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/camerarollextended/request-authorisation/index.html b/docs/camerarollextended/request-authorisation/index.html index f2d2c8ce333..4581664a7dc 100644 --- a/docs/camerarollextended/request-authorisation/index.html +++ b/docs/camerarollextended/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

On iOS the user must be asked at runtime, which you only get one chance to ask, after which you must direct the user to manually change the permissions in the settings.

The following code will work across both platforms:

CameraRollExtended.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );

switch (CameraRollExtended.service.authorisationStatus())
{
case AuthorisationStatus.SHOULD_EXPLAIN:
case AuthorisationStatus.NOT_DETERMINED:
// REQUEST AUTHORISATION: This will display the permission dialog
CameraRollExtended.service.requestAuthorisation();
return;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
case AuthorisationStatus.RESTRICTED:
// ACCESS DENIED: You should inform your user appropriately
return;

case AuthorisationStatus.AUTHORISED:
case AuthorisationStatus.LIMITED:
// AUTHORISED: Media access is available
// LIMITED: Media access is available for a subset of the library
break;
}


function authorisationChangedHandler( event:AuthorisationEvent ):void
{
switch (event.status)
{
case AuthorisationStatus.SHOULD_EXPLAIN:
// Should display a reason you need this feature
break;

case AuthorisationStatus.AUTHORISED:
case AuthorisationStatus.LIMITED:
// AUTHORISED: Media access is available
// LIMITED: Media access is available for a subset of the library
break;

case AuthorisationStatus.RESTRICTED:
case AuthorisationStatus.DENIED:
// ACCESS DENIED: You should inform your user appropriately
break;
}
}

Limited Authorisation

With iOS 14+ users' can now select a range of assets that your application has access to. This results in an authorisation status of LIMITED. This still allows you to access photo data, however only for a subset of the users' entire library.

When the user selects "Select Photos..." they are presented with a dialog that allows them to select the assets your application can access:

When your application has this LIMITED authorisation you can present the above selection dialog by calling requestAuthorisation(). This gives your user the opportunity to change their selection giving you access to different assets.

Usage Description

You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

The text is controlled via the NSPhotoLibraryUsageDescription and NSPhotoLibraryAddUsageDescription keys or their equivalent apm config parameters.

Device Settings

If your user has denied permission you can direct them to the device application settings to change them, particularly in the iOS case where you cannot force the request dialog to appear again.

To do this you use the openDeviceSettings() function.

if (CameraRollExtended.service.canOpenDeviceSettings)
{
CameraRollExtended.service.openDeviceSettings();
}

The canOpenDeviceSettings property allows you to ensure the device and platform supports opening the settings and inform your user appropriately.

- + \ No newline at end of file diff --git a/docs/cameraui/add-the-extension/index.html b/docs/cameraui/add-the-extension/index.html index 57d190bc83c..1327d58583c 100644 --- a/docs/cameraui/add-the-extension/index.html +++ b/docs/cameraui/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ when certain permissions are requested.

The most important string is the camera usage description which will get displayed during the request authorisation process (later). The key that controls the text in this dialog is:

<key>NSCameraUsageDescription</key>
<string>Require camera usage description</string>

To be able to record audio along with your video you will need to add the microphone usage description:

<key>NSMicrophoneUsageDescription</key>
<string>Require record audio description</string>

If you are saving images to the camera roll a dialog will be displayed the first time you attempt to save a captured image to the camera roll. There are 2 keys required here that control the text in this dialog:

<key>NSPhotoLibraryUsageDescription</key>
<string>Access to photo library is required to save images.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Access to photo library is required to save images.</string>

The second key was added in iOS 11.2. You should add both keys to your info additions.

For more information see requesting authorisation.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (CameraUI.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/cameraui/camera-ui-options/index.html b/docs/cameraui/camera-ui-options/index.html index 89c73f15598..c40acde7af7 100644 --- a/docs/cameraui/camera-ui-options/index.html +++ b/docs/cameraui/camera-ui-options/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Depending on the OS this will change the storage location of the file to a location that is not scanned by the device media scanner and hence won't appear in the users available media.

To change this option set the saveToCameraRoll option in the options:

var options:CameraUIOptions = new CameraUIOptions();

options.saveToCameraRoll = false;

CameraUI.service.launch( MediaType.IMAGE, options );

Save file in cache

If you don't save the image to the camera roll then by default the extension will save the captured images to the application cache directory. This means that the files may be removed by the OS at certain points.

However if you set saveFilesInCache to false the files will be saved into the applications documents directory, making the files permanent. You can delete them manually (using File) if you require.

var options:CameraUIOptions = new CameraUIOptions();

options.saveToCameraRoll = false;
options.saveFilesInCache = false;

CameraUI.service.launch( MediaType.IMAGE, options );

Android Camera App Selection

Android 11 (API 30) has introduced some very strict control over the launching of other applications which impacts the usage of the Camera UI extension. It forces the usage of the pre-installed camera application and will by-pass any user settings (if they have installed another camera application and selected it as their default).

There is no way to completely get around this. However you can specify a list of applications that your user can select from if they are installed on their device.

This is a two step process. Firstly you have to add a list of application packages you want to "whitelist" into the queries node of your application descriptor.

<queries>
<package android:name="net.sourceforge.opencamera"/>
</queries>

This should sit outside the application node, alongside the permissions. eg:

<queries>
<package android:name="net.sourceforge.opencamera"/>
</queries>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application

...

info

If you get an error when packaging about the queries node not being supported by the Android SDK then you need to update your AIR SDK. Older versions of AIR "incorrectly" report this as an issue with the Android SDK.

Then secondly when you go to launch your application you set the useChooser property to be true and add the list of package names to the cameraPackageCandidates:

For example:

var options:CameraUIOptions = new CameraUIOptions();

options.useChooser = true;
options.cameraPackageCandidates = [
"net.sourceforge.opencamera"
];

CameraUI.service.launch( MediaType.IMAGE, options );

When the camera ui is shown, if the user has one of the specified applications installed then a chooser will be presented for the user to select their application. Otherwise if the user has none of the applicaitons you have sepecified installed then the default camera application will be launched directly.

Some common applications include:

- + \ No newline at end of file diff --git a/docs/cameraui/capture-media/index.html b/docs/cameraui/capture-media/index.html index 1c527f56eb7..e21dfec2fde 100644 --- a/docs/cameraui/capture-media/index.html +++ b/docs/cameraui/capture-media/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Capture Media

Capture an Image

To launch the native UI to capture an image (or a video) you use the CameraUI.service.launch function and specify the MediaType.IMAGE media type. This will present the appropriate UI to the user.

The result of the user interface will be given through one of the following events:

  • CameraUIEvent.COMPLETE: When the user completes capture and media data is available
  • CameraUIEvent.CANCEL: When the user cancels without capturing any image/video

The following code will work across both platforms

CameraUI.service.addEventListener( CameraUIEvent.COMPLETE, cameraUI_completeHandler );
CameraUI.service.addEventListener( CameraUIEvent.CANCEL, cameraUI_cancelHandler );

CameraUI.service.launch( MediaType.IMAGE );

function cameraUI_completeHandler( event:CameraUIEvent ):void
{
// Here you can use the event.path to access the media file as you require
// Display the captured image
var l:Loader = new Loader();
l.load( new URLRequest( event.path ));
addChild( l );
}

function cameraUI_cancelHandler( event:CameraUIEvent ):void
{
trace( "user cancel" );
}
note

The size of the image returned from most modern camera's is quite large so be aware when attempting to display it as a bitmap in your application. You may be best resizing the captured data.

Capture a Video

Capturing a video is very similar to capturing an image, except we use the MediaType.VIDEO media type. We also can specify some additional options to the video capture, such as video quality as shown in the following example:

CameraUI.service.addEventListener( CameraUIEvent.COMPLETE, cameraUI_completeHandler );
CameraUI.service.addEventListener( CameraUIEvent.CANCEL, cameraUI_cancelHandler );

var options:CameraUIOptions = new CameraUIOptions();
options.videoQuality = QualityType.TYPE_HIGH;

CameraUI.service.launch( MediaType.VIDEO, options );

function cameraUI_completeHandler( event:CameraUIEvent ):void
{
// Here you can use the event.path to access the media file as you require
// For example using the distriqt MediaPlayer:
MediaPlayer.service.createPlayer( event.path, 0, 0, 640, 480, true );
MediaPlayer.service.addEventListener( MediaPlayerEvent.COMPLETE, function(e:MediaPlayerEvent):void {
MediaPlayer.service.removeEventListener( MediaPlayerEvent.COMPLETE, arguments.callee );
MediaPlayer.service.removePlayer();
});
}

function cameraUI_cancelHandler( event:CameraUIEvent ):void
{
trace( "user cancel" );
}
- + \ No newline at end of file diff --git a/docs/cameraui/changelog/index.html b/docs/cameraui/changelog/index.html index 1c16b0f6b8f..42dac2d86ae 100644 --- a/docs/cameraui/changelog/index.html +++ b/docs/cameraui/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.02.27 [v3.6.0]

feat(android): update permission requirements for latest android versions (resolves #91)  

2023.02.15 [v3.5.1]

fix(android,auth): correct issue with fallback authorisation events being dispatched to wrong extension (resolves #90)

2023.01.17 [v3.5.0]

fix(docs): correct extension id reference in manual add extension docs (#88)
feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag
feat(android): Move to new permissions request process

2022.02.04 [v3.4.16]

Updates for Android 31
Update docs to use apm

2021.08.30 [v3.4.15]

Implemented new Android chooser for specifying alternative camera applications (resolves #80)

2021.08.23 [v3.4.14]

Added airpackage
Android chooser addition for specifying alternative camera applications (#80)
Android 30 updates around deleting files from camera roll (resolves #82)

2021.04.07 [v3.3.007]

Removed ios minimum version linker option
Corrected removal of media data from gallery on Android

2021.03.05 [v3.2.025]

Added video orientation to video capture event (resolves #78)

2021.03.01 [v3.1.022]

Added ability to request audio permission directly (resolves #77)

2020.03.23 [v3.0.009]

Android X migration (resolves #69)

2019.08.16 [v2.0.004]

Android 64bit support (resolves #64)
Updated minimum iOS version to 9.0
iOS: Added return value for the launch function (resolves #66)

2019.02.26 [v1.5.025]

Updated minimum iOS version to 8.0 
Removed application key requirement (#63)

2018.06.20 [v1.4.022]

Updated documentation on usage description strings (resolves #57, resolves #52)

2017.08.14 [v1.4.014]

Changed save location of temp images to cache directory (resolves #40)
iOS: Memory optimisations (#39)

2017.07.10 [v1.3.010]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.07.02 [v1.3.009]

Added checks for CAMERA permission to correctly request if added to manifest (resolves #36)

2017.03.31 [v1.3.007]

Updated documentation for iOS 10

2017.03.13 [v1.3.007]

Added ability to open device settings (resolves #22)

2017.01.13 [v1.2.004]

Added missing auth functions to default lib (resolves #14)

2017.01.12 [v1.2.003]

Added permission request functionality (#7, #12)

2016.12.21 [v1.0.009]

Updated documentation

2016.12.08 [v1.0.009]

Added option for saveToCameraRoll to control image save location 
Added orientation to complete event (resolves #6)

2016.11.01 [v1.0.005]

Android: Fixed issue with multiple FileProviders (resolves #2)

2016.09.07 [v1.0.002]

Initial release
- + \ No newline at end of file diff --git a/docs/cameraui/index.html b/docs/cameraui/index.html index 7b2784f8452..03353c5488d 100644 --- a/docs/cameraui/index.html +++ b/docs/cameraui/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Camera UI

The CameraUI extension provides a native user interface for capturing images and videos using the device camera. It extends the functionality of the AIR built in CameraUI providing better control and stability.

The simple API allows you to quickly integrate image and video capture in your AIR application in just a few lines of code. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

We provide complete guides to get you up and running with image capture quickly and easily.

Features

  • Record video or capture images using the native interface;
  • Specify capture request options, such as media type, and quality;
  • Read assets using File access for raw data on both platforms;
  • Native Camera UI interface for capturing images and videos;
  • Single API interface - your code works across supported platforms with no modifications;
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

CameraUI.service.launch( MediaType.VIDEO );

More information here:

https://airnativeextensions.com/extension/com.distriqt.CameraUI

License

You can purchase a license for using this extension:

https://airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/cameraui/migrating-to-androidx/index.html b/docs/cameraui/migrating-to-androidx/index.html index d67c5cab1be..04d997ac5d6 100644 --- a/docs/cameraui/migrating-to-androidx/index.html +++ b/docs/cameraui/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/cameraui/migrating-to-v3.5/index.html b/docs/cameraui/migrating-to-v3.5/index.html index f41463d35fc..e11a8b8bc1f 100644 --- a/docs/cameraui/migrating-to-v3.5/index.html +++ b/docs/cameraui/migrating-to-v3.5/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v3.5

v3.5 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/cameraui/requesting-authorisation/index.html b/docs/cameraui/requesting-authorisation/index.html index 968fb7c9358..993c17f48b7 100644 --- a/docs/cameraui/requesting-authorisation/index.html +++ b/docs/cameraui/requesting-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -37,7 +37,7 @@ and then redirect them to your application device settings, which will allow your user to change the setting.

This is especially important on iOS where you only get one attempt to ask your user for permission.

To redirect your user simply call the openDeviceSettings() function. You can use the canOpenDeviceSettings flag to check if the current device supports this functionality.

if (CameraUI.instance.canOpenDeviceSettings)
{
CameraUI.instance.openDeviceSettings();
}
- + \ No newline at end of file diff --git a/docs/chartboost/add-the-extension/index.html b/docs/chartboost/add-the-extension/index.html index f6a3d30d68f..9c18045105e 100644 --- a/docs/chartboost/add-the-extension/index.html +++ b/docs/chartboost/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Chartboost.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/chartboost/changelog/index.html b/docs/chartboost/changelog/index.html index 4d5c810e830..23a7bf85ce8 100644 --- a/docs/chartboost/changelog/index.html +++ b/docs/chartboost/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.11.03 [v1.0.1]

fix(android): correct required chartboost dependencies to include androidx.media and guava

2023.10.25 [v1.0.0]

initial release

2023.10.25 [v1.0.0]

initial release
- + \ No newline at end of file diff --git a/docs/chartboost/index.html b/docs/chartboost/index.html index 0b8b0131953..af62df229a5 100644 --- a/docs/chartboost/index.html +++ b/docs/chartboost/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Chartboost

The Chartboost extension gives access to the Chartboost SDK to monetise your application.

Features:

  • Chartboost SDK integration
  • Single API interface - your code works across supported platforms with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

var config:ChartboostConfig = new ChartboostConfig()
.setAppId( CHARTBOOST_APPID )
.setAppSignature( CHARTBOOST_APPSIGNATURE );

Chartboost.instance.addEventListener( ChartboostEvent.START_SUCCESS, startSuccessHandler );
Chartboost.instance.addEventListener( ChartboostEvent.START_ERROR, startErrorHandler );

Chartboost.instance.startWithConfig( config );

More information here:

com.distriqt.Chartboost

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/chartboost/initialise/index.html b/docs/chartboost/initialise/index.html index 03341f32414..83001276422 100644 --- a/docs/chartboost/initialise/index.html +++ b/docs/chartboost/initialise/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Initialise

To initialise the Chartboost SDK call the startWithConfig() method and provide your application configuration. The startWithConfig() method must always be called on bootup, regardless of any other actions your app takes. It will dispatch an event indicating the success or failure of the SDK initialisation.

You will need to firstly create an instance of the ChartboostConfig class and specify your Chartboost App identifier and signature.

var config:ChartboostConfig = new ChartboostConfig()
.setAppId( CHARTBOOST_APPID )
.setAppSignature( CHARTBOOST_APPSIGNATURE );

These values can be found in the dashboard, under "App information" for your application.

Then pass this configuration to the startWithConfig() method:

Chartboost.instance.addEventListener( ChartboostEvent.START_SUCCESS, startSuccessHandler );
Chartboost.instance.addEventListener( ChartboostEvent.START_ERROR, startErrorHandler );

Chartboost.instance.startWithConfig( config );

function startSuccessHandler( event:ChartboostEvent ):void
{
trace( "Chartboost initialised" );
}

function startErrorHandler( event:ChartboostEvent ):void
{
trace( "Chartboost error: " + event.errorCode + "::" + event.message );
}

If an error is dispatched you can check the result and act accordingly.

- + \ No newline at end of file diff --git a/docs/chartboost/setup/index.html b/docs/chartboost/setup/index.html index d0ed4189d3e..584dd098861 100644 --- a/docs/chartboost/setup/index.html +++ b/docs/chartboost/setup/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Account Setup

Create and set up your Chartboost account.

  • Sign up for a free Chartboost platform account.
  • Setup your account settings with additional users and notification settings.
  • Set up your payment details so we know where to send your earnings.

Setup your application

  • Add your app to the Chartboost platform and join the Chartboost network.
  • Wait for your app to get approved.
- + \ No newline at end of file diff --git a/docs/cloudstorage/add-the-extension/index.html b/docs/cloudstorage/add-the-extension/index.html index 3ab73b6c1b7..8c1f7e1a914 100644 --- a/docs/cloudstorage/add-the-extension/index.html +++ b/docs/cloudstorage/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Setup

You should first gather some information for your application.

The Bundle Seed Id or App ID Prefix is an identifier for your iOS application. If you look at your application identifier in your developer portal you will see the App ID Prefix listed. It is of the form XYZ1234WCJ (10 alpha-numeric characters).

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.CloudStorage

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.CloudStorage.ane # CloudStorage extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set the usage description strings for use in the authorisation dialogs. Call the following to step through the configuration values for this extension:
apm project config set com.distriqt.CloudStorage

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Document Storage

If you plan to use document storage then you will need to create an iCloud container in your application identifier through the developer portal.

Find your application identifier then select the iCloud option and add your container. Take a note of the "cloud identifier" for the container as you will need this when configuring your application.

note

Document storage is not supported on Apple tvOS. If you are supporting this platform you should not include the com.apple.developer.ubiquity-container-identifiers key in your entitlements.

If you are supporting both platforms then we suggest you create a separate project / application descriptor for each and only add the following to your iOS project.

If you plan on using document storage in an iCloud container then you need to add some additional configuration. Firstly add a custom iOS configuration file by running:

apm generate config ios

Edit the config/ios/Entitlements.xml file that was generated to resemble the following, adding the com.apple.developer.ubiquity-container-identifiers node:

<plist version="1.0">
<dict>

<!-- ICLOUD ENTITLEMENTS -->
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>${iCloudContainerId}</string>
</array>

</dict>
</plist>

The iCloudContainerId value will get inserted from your apm project configuration.

Once you have added this configuration run the steps above to update / generate your application descriptor.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (CloudStorage.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/cloudstorage/add-the-plugin/index.html b/docs/cloudstorage/add-the-plugin/index.html index 53a5c48dd70..c7f4dd0851d 100644 --- a/docs/cloudstorage/add-the-plugin/index.html +++ b/docs/cloudstorage/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Add the Plugin

First step is always to add the plugin to your development environment.

Asset Store

Open the Asset Store in your browser and add the plugin to your assets.

Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

Manual Installation

In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.CloudStorage.unitypackage.

You can manually download the extension from our repository:

Import the Plugin

This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

The plugin will be added to your project and you can now use the plugins functionality in your application.

iOS / tvOS

The Capabilities editor script should automatically enable iCloud key-value store for your Xcode project, which should add the appropriate value for the com.apple.developer.ubiquity-kvstore-identifier key in your entitlements.

We suggest you ensure the value is correct and that cloud kit has been enabled in the capabilities section of your Xcode project.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (CloudStorage.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/cloudstorage/android-testing/index.html b/docs/cloudstorage/android-testing/index.html index 32e495fa7ed..5386fe97637 100644 --- a/docs/cloudstorage/android-testing/index.html +++ b/docs/cloudstorage/android-testing/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Android Testing

The implemented backup manager works automatically without user interaction and saves and restores the registered shared preferences associated with the user. Simply change and save shared preferences under the file name which you registered your application with.

If you want to test the save and restore operation via the adb shell command you can use the following commands.

To schedule a backup and then run the backup process:

adb shell bmgr backup air.com.distriqt.test
adb shell bmgr run

To restore a backup:

adb shell bmgr restore air.com.distriqt.test
- + \ No newline at end of file diff --git a/docs/cloudstorage/changelog/index.html b/docs/cloudstorage/changelog/index.html index 14a4cb97271..8d77da1832a 100644 --- a/docs/cloudstorage/changelog/index.html +++ b/docs/cloudstorage/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.17 [v6.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2022.02.04 [v6.0.99]

Update air package descriptions
Update docs to use apm

2021.11.12 [v6.0.98]

Unity: Corrected getKeys method on Android implementation (not supported yet)

2021.09.24 [v6.0.97]

Added air package

2021.04.06 [v6.0.095]

Updated docs

2021.04.06 [v6.0.095]

Updated docs and reduced unity minimum version

2020.04.30 [v6.0.066]

Fixed crash in key value storage

2020.03.23 [v6.0.062]

Android X migration (resolves #12)

2020.01.22 [v5.0.056]

Unity Plugin release

2019.07.22 [v4.0.044]

Fixed issue with document deletion of an open document (resolves #8)
Android 64bit packaging support (resolves #11)
Removed application keys

2019.03.12 [v3.1.036]

Updated minimum iOS version to 8.0
Embedded iOS bitcode

2018.02.10 [v3.0.030]

Apple tvOS platform implementation

2017.11.10 [v2.1.020]

Updates for iOS 11

2017.07.10 [v2.0.015]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2016.12.23 [v2.0.014]

Updating documentation

2016.12.16 [v2.0.014]

Added document storage for synchronising files

2016.06.30

Release v1.0
- + \ No newline at end of file diff --git a/docs/cloudstorage/document-store/index.html b/docs/cloudstorage/document-store/index.html index 2264556d7cf..a166a4e22b4 100644 --- a/docs/cloudstorage/document-store/index.html +++ b/docs/cloudstorage/document-store/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ where appropriate and return the normal save success / error events.

var document:Document = new Document();
document.filename = "test.txt";
document.data = new ByteArray();
document.data.writeUTFBytes( "TEST SOME STRING WRITING" );

CloudStorage.service.documentStore.addEventListener( DocumentEvent.SAVE_COMPLETE, document_createCompleteHandler );
CloudStorage.service.documentStore.addEventListener( DocumentEvent.SAVE_ERROR, document_createErrorHandler );

CloudStorage.service.documentStore.saveDocument( document );

If you wish to create the document in a folder, you can add a folder name to the filename of the document.

document.filename = "folder/test.txt";

Delete a Document

To delete a document call deleteDocument with the filename of the document to delete.

CloudStorage.service.documentStore.addEventListener( DocumentEvent.DELETE_COMPLETE, document_deleteCompleteHandler );
CloudStorage.service.documentStore.addEventListener( DocumentEvent.DELETE_ERROR, document_deleteErrorHandler );

CloudStorage.service.documentStore.deleteDocument( _documents[0].filename );
private function document_deleteCompleteHandler( event:DocumentEvent ):void
{
trace( "document_deleteCompleteHandler" );

CloudStorage.service.documentStore.removeEventListener( DocumentEvent.DELETE_COMPLETE, document_deleteCompleteHandler );
CloudStorage.service.documentStore.removeEventListener( DocumentEvent.DELETE_ERROR, document_deleteErrorHandler );
}

private function document_deleteErrorHandler( event:DocumentEvent ):void
{
trace( "document_deleteErrorHandler" );

CloudStorage.service.documentStore.removeEventListener( DocumentEvent.DELETE_COMPLETE, document_deleteCompleteHandler );
CloudStorage.service.documentStore.removeEventListener( DocumentEvent.DELETE_ERROR, document_deleteErrorHandler );
}

Handling conflicts

Conflicts can (and will) occur when devices save to the same file simulataneously and cannot be resolved by iCloud.

You must listen for the conflict event and process each conflict. The event contains a list of documents that are in a conflicted state and you must use getConflictingVersionsForDocument to get the versions of the file and then decide which is the valid version and resolve the conflict with that version of the file, calling resolveConflictWithVersion.

The following iterates over the conflicts and blindly resolves the conflict with the first version of the file.

private function ds_conflictHandler( event:DocumentStoreEvent ):void
{
trace( "ds_conflictHandler" );
for each (var document:Document in event.documents)
{
trace( "conflict: "+document.filename );
var versions:Array = CloudStorage.service.documentStore.getConflictingVersionsForDocument( document );
CloudStorage.service.documentStore.resolveConflictWithVersion( document, versions[0] );
}
}

You should not use this in production! We just are using this to demonstrate the function calls.

- + \ No newline at end of file diff --git a/docs/cloudstorage/index.html b/docs/cloudstorage/index.html index ff40c42ad46..eff73fb6e36 100644 --- a/docs/cloudstorage/index.html +++ b/docs/cloudstorage/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ between devices. You'll be able to write your user's application to a file similar to a normal file and get notifications of changes when updates are received from the cloud.

We provide complete guides to get you up and running with cloud storage quickly and easily.

It supports both Unity and Adobe AIR frameworks on iOS, tvOS and macOS, allowing you to use the same functionality on all frameworks.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

Latest documentation can be found in the documentation site

More information here:

com.distriqt.CloudStorage

License

You can purchase a license for using this extension:

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/cloudstorage/key-value-storage/index.html b/docs/cloudstorage/key-value-storage/index.html index 4d6205d4e19..ab21c7737a0 100644 --- a/docs/cloudstorage/key-value-storage/index.html +++ b/docs/cloudstorage/key-value-storage/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ a parameter which will then return the value set previously.

For example:

AIR
var value:String = CloudStorage.service.keyValueStore.getString( "KEY_FOR_VALUE" );
Unity
var value = CloudStorage.Instance.GetString("KEY_FOR_VALUE");

Remove Value

To remove a value that you have previously set you can use the Remove function:

AIR
CloudStorage.service.keyValueStore.remove("KEY_FOR_VALUE");
Unity
CloudStorage.Instance.Remove("KEY_FOR_VALUE");

Events

The extension will dispatch events when the values are changed (on another device) and when other system events occur:

More information see the KeyValueStoreEvent class documentation.

Example

The following example shows the core concepts, setting then retrieving a value and listening to the KeyValueStoreEvent.CHANGED (OnChanged on Unity) event.

AIR
CloudStorage.service.keyValueStore.addEventListener( KeyValueStoreEvent.CHANGED, keyStore_changedHandler );
CloudStorage.service.keyValueStore.synchronise();

// Set a value
CloudStorage.service.keyValueStore.setString( "KEY_FOR_VALUE", newValue );

// Retrieve the value
var value:String = CloudStorage.service.keyValueStore.getString( "KEY_FOR_VALUE" );


function keyStore_changedHandler( event:KeyValueStoreEvent ):void
{
trace( "KeyStore CHANGED" );
// event.changedKeys contains an array of changed keys
}
Unity
CloudStorage.Instance.OnChanged += Instance_OnChanged;
CloudStorage.Instance.Synchronise();

// Set a value
CloudStorage.Instance.SetString( "KEY_FOR_VALUE", "some_value" );

// Retrieve the value
string value = CloudStorage.Instance.GetString( "KEY_FOR_VALUE" )



private void Instance_OnChanged(KeyValueStoreEvent e)
{
Debug.Log("OnChanged");
// e.changedKeys contains an array of changed keys
foreach (string key in e.changedKeys)
{
Debug.Log("OnChanged: " + key);
}
}
- + \ No newline at end of file diff --git a/docs/cloudstorage/unity/index.html b/docs/cloudstorage/unity/index.html index f50a3c66122..b19191ecc72 100644 --- a/docs/cloudstorage/unity/index.html +++ b/docs/cloudstorage/unity/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ a parameter which will then return the value set previously.

For example:

var userId = CloudStorage.Instance.GetString("userId");

Remove Value

To remove a value that you have previously set you can use the Remove function:

CloudStorage.Instance.Remove("userId");

Events

The extension will dispatch events when the values are changed (on another device) and when other system events occur:

Example

The following example shows the core concepts, setting then retrieving a value and listening to the OnChanged event.

CloudStorage.Instance.OnChanged += Instance_OnChanged;
CloudStorage.Instance.Synchronise();

// Set a value
CloudStorage.Instance.SetString( "KEY_FOR_VALUE", "some_value" );

// Retrieve the value
string value = CloudStorage.Instance.GetString( "KEY_FOR_VALUE" )


private void Instance_OnChanged(KeyValueStoreEvent e)
{
Debug.Log("OnChanged");
// e.changedKeys contains an array of changed keys
foreach (string key in e.changedKeys)
{
Debug.Log("OnChanged: " + key);
}
}

Support

If you need further support integrating or using this extension please feel free to contact us.

We have been supporting developers for over 10 years and always happy to help.





- + \ No newline at end of file diff --git a/docs/compass/add-the-extension/index.html b/docs/compass/add-the-extension/index.html index 29b78dcfc87..a7a33e3960f 100644 --- a/docs/compass/add-the-extension/index.html +++ b/docs/compass/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.Compass

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.Compass.ane # Compass extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set the usage description strings for use in the authorisation dialogs. Call the following to step through the configuration values for this extension:
apm project config set com.distriqt.Compass

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

True Heading

On iOS you can access the "true heading" rather than the magnetic heading.

If you are going to be accessing the "true heading" you must add some additional configuration values to your application.

If not, or you are only interested in Android, you can skip this section.

Firstly add a custom iOS configuration file by running:

apm generate config ios

Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following:

<plist version="1.0">
<dict>

<key>NSLocationUsageDescription</key>
<string>${locationUsageDescription}</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>${locationWhenInUseUsageDescription}</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>${locationAlwaysUsageDescription}</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>${locationAlwaysAndWhenInUseUsageDescription}</string>

</dict>
</plist>

The values, eg locationUsageDescription, will get inserted from your apm project configuration.

Once you have added this configuration run the steps above to update / generate your application descriptor.

You can adjust the usage description strings as you need. See request authorisation for more.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Compass.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/compass/changelog/index.html b/docs/compass/changelog/index.html index bd3160f3645..06284c46ca3 100644 --- a/docs/compass/changelog/index.html +++ b/docs/compass/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.17 [v4.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2022.02.04 [v4.0.9]

Update air package descriptions
Update docs to use apm

2021.12.16 [v4.0.8]

Add air package parameter descriptions

2021.09.24 [v4.0.7]

Added air package
Added android x64 support
Removed ios minimum version flag
Updated build

2020.03.23 [v4.0.006]

Android X migration (resolves #20)

2019.08.16 [v3.0.002]

Android 64bit support (resolves #19)
Updated minimum iOS version to 9.0

2019.04.02 [v2.3.012]

Updated minimum iOS version to 8.0
Embedded iOS bitcode

2018.10.22 [v2.2.009]

Removed application key requirement

2018.04.04 [v2.2.008]

Corrected magnetic heading issue on iOS and added location permission request for true heading (resolves #16)

2017.07.10 [v2.2.004]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2016.12.23 [v2.2.003]

Added images

2016.12.23 [v2.2.003]

Latest OS updates + updating documentation

2015.10.20

Updated documentation with units and events (resolves #8)

2015.06.12

iOS: Updated simulator version

2015.06.12

iOS: Updated build with latest compiler (#6)
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.02.24

Changed class structure to support FlashBuilder 4.6 (resolves #3)

2015.02.04

Documentation update

2015.02.04

Separated out the magnetic field from the heading updates
Added access to the uncalibrated magnetic field data along with the calibrated data (resolves #2)

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.01

New application based key check, removing server checks
- + \ No newline at end of file diff --git a/docs/compass/heading/index.html b/docs/compass/heading/index.html index 505bc7418da..75e9a120c49 100644 --- a/docs/compass/heading/index.html +++ b/docs/compass/heading/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ conserve battery life etc. This is important when your application goes into background operation. It's suggested that you use a mechanism to unregister the ANE when this occurs, by using something like the ACTIVATE/DEACTIVATE events.

if (Compass.isSupported && Compass.service.isRegistered)
{
Compass.service.unregister();
}

True Heading

On iOS you can access the true heading of the device, however this requires access to the device location so you will need to add some additional properties to your application and request permission to access the device location.

For more information on this see the section on request authorisation

Android

True Heading is not supported on Android

- + \ No newline at end of file diff --git a/docs/compass/index.html b/docs/compass/index.html index 6b1e6c8f85c..8e743b24acb 100644 --- a/docs/compass/index.html +++ b/docs/compass/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Compass

The Compass extension gives access to two important sensor readings, the heading of the device and the magnetometer sensor data

The Compass ANE is designed to give the magnetic-north heading values from the device calculated through a line from the bottom of the device to the top.

On iOS the location is used to calculate the offset from the magnetic heading to the true heading and both values are reported. (This may require the user to accept a permission for your application to access the device location).

The raw magnetic field values can be retrieved using this extension. You can listen for the MagneticFieldEvent for changes in the magnetic field. There are 2 important events, both indicating the magnetic field, one in the calibrated state and the other the raw uncalibrated data.

We provide complete guides to get you up and running with asset selection quickly and easily.

Features

  • Native Compass: Provides access to native device compass sensor
  • Heading: Provides compass reading information, i.e. true / magnetic heading
  • Single API interface: Works across iOS and Android with the same code
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

Compass.service.addEventListener( CompassEvent.HEADING_UPDATED, headingUpdatedHandler );
if (Compass.isSupported)
{
Compass.service.register( Compass.SENSOR_DELAY_NORMAL, 0.4 );
}

function headingUpdatedHandler( event:CompassEvent ):void
{
trace( event.magneticHeading +" ["+event.headingAccuracy+"]" );
}

More information here:

com.distriqt.Compass

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/compass/magnetic-field-sensor/index.html b/docs/compass/magnetic-field-sensor/index.html index d262d36c143..eb4717eb0ba 100644 --- a/docs/compass/magnetic-field-sensor/index.html +++ b/docs/compass/magnetic-field-sensor/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ This checks whether there is a magnetometer on the device and whether the particular data updates (calibrated or uncalibrated) are available. (Uncalibrated data was only introduced on Android v18).

if (Compass.service.magneticFieldSensor.isCalibratedDataAvailable)
{
Compass.service.magneticFieldSensor.addEventListener( MagneticFieldEvent.MAGNETIC_FIELD_UPDATED, magneticFieldUpdatedHandler );

// The true here indicates the request for calibrated data
Compass.service.magneticFieldSensor.register( SensorRate.SENSOR_DELAY_NORMAL, true );
}

Then you retrieve information in the update events:

private function magneticFieldUpdatedHandler( event:MagneticFieldEvent ):void
{
trace( "calibrated\nx:"+ event.fieldX + "\ny:"+event.fieldY +"\nz:"+ event.fieldZ +"\na:"+ event.accuracy; );
}

Similarly to stop the updates call the unregister function:

Compass.service.magneticFieldSensor.unregister();
- + \ No newline at end of file diff --git a/docs/compass/request-authorisation/index.html b/docs/compass/request-authorisation/index.html index 5da2d96a4a6..769e882a60f 100644 --- a/docs/compass/request-authorisation/index.html +++ b/docs/compass/request-authorisation/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Request Authorisation

If you are going to be using the "true heading" on iOS then you are going to be accessing the user's location.

When you are going to be accessing the user's location you must check that your application has been allowed access. To this end the extension provides several helpers to check and request access to the location services.

info

On iOS you will only be able to display the authorisation request dialog once! Hence it is very important that you inform your users why they should grant authorisation before requesting authorisation. To request authorisation you call requestAuthorisation(). This function will trigger the native dialog asking the user for authorisation.

You can check if you currently have permission using the hasAuthorisation() function:

if (Compass.service.hasAuthorisation())
{
// Application has permission to access trueHeading
}

If this returns false you should expect a -1 value for true heading.

To request authorisation at runtime, you call the requestAuthorisation() function. The following code will work across both platforms:

switch (Compass.service.authorisationStatus())
{
case AuthorisationStatus.ALWAYS:
case AuthorisationStatus.IN_USE:
trace( "User allowed access: " + Compass.service.authorisationStatus() );
break;

case AuthorisationStatus.NOT_DETERMINED:
case AuthorisationStatus.SHOULD_EXPLAIN:
Compass.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
Compass.service.requestAuthorisation( AuthorisationStatus.ALWAYS );
break;

case AuthorisationStatus.RESTRICTED:
case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
trace( "User denied access" );
break;
}

function authorisationChangedHandler( event:AuthorisationEvent ):void
{
//
}

Usage Description

You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

- + \ No newline at end of file diff --git a/docs/contacts/add-the-extension/index.html b/docs/contacts/add-the-extension/index.html index 259a28f0078..972ffee2620 100644 --- a/docs/contacts/add-the-extension/index.html +++ b/docs/contacts/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

note

If you plan to save contact images you will need to add the following permission using apm.

Firstly, generate a custom config for your project:

apm generate config android

Then edit the config/android/AndroidManifest.xml file and add the following line:

<!-- Optional: Needed if you are planning to save contact images -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Contacts.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/contacts/changelog/index.html b/docs/contacts/changelog/index.html index 1df34348ac8..03ed5d7035d 100644 --- a/docs/contacts/changelog/index.html +++ b/docs/contacts/changelog/index.html @@ -3,7 +3,7 @@ -changelog | air native extensions +changelog | air native extensions @@ -13,13 +13,13 @@ - +
-
Skip to main content

changelog

2023.09.06 [v5.1.1]

fix(android): correct android auth usage of write external storage (#82)

2023.01.17 [v5.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.02.04 [v5.0.12]

Update package descriptions 
Improve add the extension docs

2022.01.25 [v5.0.10]

Update for Android 11 queries and Android 12 exported requirements

2021.12.16 [v5.0.9]

Add air package parameter descriptions

2021.09.24 [v5.0.8]

Added air package
Added android x64 support
Removed ios minimum version flag
Updated build

2020.03.23 [v5.0.006]

Android X migration (resolves #76)

2019.08.16 [v4.0.002]

Android 64bit support (resolves #74)
Updated minimum iOS version to 9.0

2019.03.14 [v3.9.029]

Updated minimum iOS version to 8.0
Embedded iOS bitcode
Removed application keys

2018.03.11 [v3.8.027]

Corrected release build process (resolves #67)

2018.01.18 [v3.8.019]

Android: Made authorisation request dependent on manifest permissions (resolves #65)

2017.07.10 [v3.8.014]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.02.07 [v3.8.013]

Android: Correction for timestamp on devices pre API 18 (resolves #49)
Android: Added additional checks for activity availability (#47)

2016.12.21 [v3.8.012]

Updating documentation

2016.12.21 [v3.8.012]

Updating documentation

2016.12.21 [v3.8.012]

Updating documentation

2016.11.30 [v3.8.012]

Automatically load image from contact picker ui (resolves #44)
Memory optimisations for loading images (#41)

2016.11.21 [v3.8.006]

Added wiki documentation

2016.09.05 [v3.8.002]

Android: Corrected async operation interfering with other native processes (resolves #33)

2016.07.04

iOS: Corrected getContactDetails and showContactPicker returning limited set of data (resolves #29)

2016.07.02

iOS: Fixed issue when selecting contact on iOS 9 (resolves #28)
iOS: Fixed crash 'EXC_BAD_ACCESS DTCNABController' (resolves #25)

2016.06.15

Android: Corrected image loading on Android 6 (resolves #26)

2016.05.03

iOS: Fixed memory related issue which may cause an occasional crash

2016.04.07

Added permission checks for Android 6+ and updated iOS (resolves #20)
Android: Added check for intent in showContactPicker (resolves #22)

2016.02.22

Android: Corrected organisation field when not tagged as work (resolves #19)

2015.12.29

Retrieve JSON array of contact list
Retrieve contacts by modification date (resolves #14)
Additional fields (Prefix, Suffix, Nickname, SocialService's, Instant Message service, url, notes, related names)
Save contact images to directory
Bug fixes (resolves #12)
Fix for package names starting with numbers (resolves #15)
Fixed issue with missing contacts (resolves #11)
Documentation updates

2015.08.13

Corrected organisation field saving in addContact (resolves #9)

2015.06.15

Changed default behaviour of image retrieval
Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.06.05

Android: Corrected getContactDetails operation on Lollipop. Was incorrectly retrieving email addresses

2015.06.03

Implemented the ability to add a contact to the user's contacts
Added retrieval of contact images (thumbnails)
Android: Updated contacts query method for Lollipop
Corrected emailCount and phoneCount on basic contact list (resolves #5)

2015.03.18

iOS: Fixed crash on startup when user had denied access (resolves #4)

2015.03.10

iOS: Corrected crash when calling functions within a small interval

2015.03.10

iOS: Corrected crash when calling functions within a small interval

2015.03.10

iOS: Corrected contact picker on iOS 8 not correctly returning selection (resolves #2)
Added mailing address information to returned details (resolves #3)

2015.02.12

Final updates and checks for release

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.03

New application based key check, removing server checks
- +
Skip to main content

changelog

2023.11.23 [v6.0.1]

feat(ios): move to Apple's modern Contacts framework (resolves #81, resolves #71)
feat(android,ios): add ability to save notes, social services and websites when adding a contact (resolves #23)

2023.09.06 [v5.1.1]

fix(android): correct android auth usage of write external storage (#82)

2023.01.17 [v5.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.02.04 [v5.0.12]

Update package descriptions 
Improve add the extension docs

2022.01.25 [v5.0.10]

Update for Android 11 queries and Android 12 exported requirements

2021.12.16 [v5.0.9]

Add air package parameter descriptions

2021.09.24 [v5.0.8]

Added air package
Added android x64 support
Removed ios minimum version flag
Updated build

2020.03.23 [v5.0.006]

Android X migration (resolves #76)

2019.08.16 [v4.0.002]

Android 64bit support (resolves #74)
Updated minimum iOS version to 9.0

2019.03.14 [v3.9.029]

Updated minimum iOS version to 8.0
Embedded iOS bitcode
Removed application keys

2018.03.11 [v3.8.027]

Corrected release build process (resolves #67)

2018.01.18 [v3.8.019]

Android: Made authorisation request dependent on manifest permissions (resolves #65)

2017.07.10 [v3.8.014]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.02.07 [v3.8.013]

Android: Correction for timestamp on devices pre API 18 (resolves #49)
Android: Added additional checks for activity availability (#47)

2016.12.21 [v3.8.012]

Updating documentation

2016.12.21 [v3.8.012]

Updating documentation

2016.12.21 [v3.8.012]

Updating documentation

2016.11.30 [v3.8.012]

Automatically load image from contact picker ui (resolves #44)
Memory optimisations for loading images (#41)

2016.11.21 [v3.8.006]

Added wiki documentation

2016.09.05 [v3.8.002]

Android: Corrected async operation interfering with other native processes (resolves #33)

2016.07.04

iOS: Corrected getContactDetails and showContactPicker returning limited set of data (resolves #29)

2016.07.02

iOS: Fixed issue when selecting contact on iOS 9 (resolves #28)
iOS: Fixed crash 'EXC_BAD_ACCESS DTCNABController' (resolves #25)

2016.06.15

Android: Corrected image loading on Android 6 (resolves #26)

2016.05.03

iOS: Fixed memory related issue which may cause an occasional crash

2016.04.07

Added permission checks for Android 6+ and updated iOS (resolves #20)
Android: Added check for intent in showContactPicker (resolves #22)

2016.02.22

Android: Corrected organisation field when not tagged as work (resolves #19)

2015.12.29

Retrieve JSON array of contact list
Retrieve contacts by modification date (resolves #14)
Additional fields (Prefix, Suffix, Nickname, SocialService's, Instant Message service, url, notes, related names)
Save contact images to directory
Bug fixes (resolves #12)
Fix for package names starting with numbers (resolves #15)
Fixed issue with missing contacts (resolves #11)
Documentation updates

2015.08.13

Corrected organisation field saving in addContact (resolves #9)

2015.06.15

Changed default behaviour of image retrieval
Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.06.05

Android: Corrected getContactDetails operation on Lollipop. Was incorrectly retrieving email addresses

2015.06.03

Implemented the ability to add a contact to the user's contacts
Added retrieval of contact images (thumbnails)
Android: Updated contacts query method for Lollipop
Corrected emailCount and phoneCount on basic contact list (resolves #5)

2015.03.18

iOS: Fixed crash on startup when user had denied access (resolves #4)

2015.03.10

iOS: Corrected crash when calling functions within a small interval

2015.03.10

iOS: Corrected crash when calling functions within a small interval

2015.03.10

iOS: Corrected contact picker on iOS 8 not correctly returning selection (resolves #2)
Added mailing address information to returned details (resolves #3)

2015.02.12

Final updates and checks for release

2015.02.02

Added check for .debug suffix in application id

2014.12.18

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.03

New application based key check, removing server checks
+ \ No newline at end of file diff --git a/docs/contacts/contact-images/index.html b/docs/contacts/contact-images/index.html index 5a7a865019e..128726a9037 100644 --- a/docs/contacts/contact-images/index.html +++ b/docs/contacts/contact-images/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ use this method as it may lead to a very large memory load in your application.

To load all the contact images:

Contacts.service.getContactListAsync( true ); 

Instead we advise that you only load the images of the contacts you require, using the second paramter to the getContactDetails function to indicate you wish to load the image:

Contacts.service.getContactDetails( contactId, true );

Additionally you can use the getContactImage function to directly load the BitmapData image for the specified contact:

var image:BitmapData = Contacts.service.getContactImage( contactId );
- + \ No newline at end of file diff --git a/docs/contacts/contact-picker-ui/index.html b/docs/contacts/contact-picker-ui/index.html index 6a04d36bdfb..daabacb0819 100644 --- a/docs/contacts/contact-picker-ui/index.html +++ b/docs/contacts/contact-picker-ui/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Contact Picker UI

This functionality allows you to display a native contact picker UI to allow the user to select a contact. If you require a user selection of a contact then this is often the best, fastest and simplest solution.

You should listen for 4 potential events from the picker:

  • CONTACT_SELECTED: Dispatched when the user selected a contact
  • CONTACTPICKER_CANCEL: Dispatched if the user cancelled the picker
  • CONTACTPICKER_CLOSED: Dispatched after the picker is closed, this is dispatched after both a selected and a cancelled event
  • CONTACTPICKER_ERROR: Dispatched if there was an error showing the picker. The picker will not be displayed if this error event is dispatched.
Contacts.service.addEventListener( ContactsEvent.CONTACT_SELECTED,      contactSelectedHandler );
Contacts.service.addEventListener( ContactsEvent.CONTACTPICKER_CANCEL, contactPickerCancelHandler );
Contacts.service.addEventListener( ContactsEvent.CONTACTPICKER_CLOSED, contactPickerClosedHandler );
Contacts.service.addEventListener( ContactsEvent.CONTACTPICKER_ERROR, contactPickerErrorHandler );

if (!Contacts.service.showContactPicker())
{
trace( "Access to contacts list denied by user" );
}

Then you can respond to the selection in the event handlers:

private function contactSelectedHandler( event:ContactsEvent ):void
{
trace("Contact selected");
if (event.data)
{
var contact:Contact = event.data[0];

trace("Got contact: " + contact.contactId);
trace("Name: " + contact.fullName);
trace("FName: " + contact.firstName);
trace("Org: " + contact.organisation.name + " -- " + contact.organisation.title);
for each (var p:Object in contact.phoneNumbers)
{
trace(p.label + " -- " + p.value);
}
for each (var e:Object in contact.emailAddresses)
{
trace(e.label + " -- " + e.value);
}
}
}

private function contactPickerCancelHandler( event:ContactsEvent ):void
{
trace( "Picker cancelled" );
}

private function contactPickerClosedHandler( event:ContactsEvent ):void
{
trace( "Picker closed" );
}

private function contactPickerErrorHandler( event:ContactsEvent ):void
{
trace( "An error occurred with the picker: "+event.message );
}
- + \ No newline at end of file diff --git a/docs/contacts/index.html b/docs/contacts/index.html index faccd2182a8..e5e1892ee9f 100644 --- a/docs/contacts/index.html +++ b/docs/contacts/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Contacts

The Contacts gives you the ability to access the user's contact list. You can retrieve details on a particular contact, get a list of the entire contact list or display a native UI picker to get a user selection. Included in this functionality is all the ability to request the correct iOS permissions.

The simple API allows you to quickly integrate contact access in your AIR application in just a few lines of code. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

We provide complete guides to get you up and running with asset selection quickly and easily.

Features

  • Retrieve the entire contact list as JSON;
  • Save all available contact images to an application directory;
  • Display the native contact picker;
  • Access latest details of a contact including: IM details, Social networks, websites and contact events (birthday)

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.Contacts

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/contacts/migrating-to-androidx/index.html b/docs/contacts/migrating-to-androidx/index.html index 53d99f65f0f..d49fb4d9e63 100644 --- a/docs/contacts/migrating-to-androidx/index.html +++ b/docs/contacts/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/contacts/migrating-to-v5.1/index.html b/docs/contacts/migrating-to-v5.1/index.html index 217129b2752..f99465577aa 100644 --- a/docs/contacts/migrating-to-v5.1/index.html +++ b/docs/contacts/migrating-to-v5.1/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v5.1

v5.1 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/contacts/request-authorisation/index.html b/docs/contacts/request-authorisation/index.html index 023ea1bb302..f4c054c2ff3 100644 --- a/docs/contacts/request-authorisation/index.html +++ b/docs/contacts/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

On iOS the user must be asked at runtime, which you only get one chance to ask, after which you must direct the user to manually change the permissions in the settings.

The following code will work across both platforms:

Contacts.service.addEventListener( AuthorisationEvent.CHANGED, contacts_authorisationChangedHandler );


switch (Contacts.service.authorisationStatus())
{
case AuthorisationStatus.SHOULD_EXPLAIN:
case AuthorisationStatus.NOT_DETERMINED:
// REQUEST ACCESS: This will display the permission dialog
Contacts.service.requestAccess();
return;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
case AuthorisationStatus.RESTRICTED:
// ACCESS DENIED: You should inform your user appropriately
return;

case AuthorisationStatus.AUTHORISED:
// AUTHORISED: Contacts will be available
break;
}


function contacts_authorisationChangedHandler( event:AuthorisationEvent ):void
{
// Check event.status
}

Usage Description

You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

- + \ No newline at end of file diff --git a/docs/contacts/retrieving-the-contact-list/index.html b/docs/contacts/retrieving-the-contact-list/index.html index 8f43eb9b646..35660295fbf 100644 --- a/docs/contacts/retrieving-the-contact-list/index.html +++ b/docs/contacts/retrieving-the-contact-list/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ getContactListModifiedSince function, as below:

Contacts.service.addEventListener( ContactsEvent.GET_CONTACTS_MODIFIED, contacts_getContactsModifiedHandler );

var success:Boolean = Contacts.service.getContactListModifiedSince( new Date( 2015, 9, 1 ) );

...

private function contacts_getContactsModifiedHandler( event:ContactsEvent ):void
{
// event.data will contain an array of Contact objects that have been modified
}

JSON

Retrieving the contact list as JSON, this method retrieves the extended contact list again however it will be faster than getContactListExtendedAsync as we aren't creating a Contact object for each contact. Instead we are just returning a json formatted string.

Contacts.service.addEventListener( ContactsJSONEvent.GET_CONTACTS_JSON, contacts_getContactsJSONHandler );

Contacts.service.getContactListAsJSON();

...

private function contacts_getContactsJSONHandler( event:ContactsJSONEvent ):void
{
trace( event.json );
}

Modified Since as JSON

Similarly you can retrieve the modified since list as JSON

Contacts.service.addEventListener( ContactsJSONEvent.GET_CONTACTS_MODIFIED_JSON, contacts_getContactsModifiedJSONHandler );

var success:Boolean = Contacts.service.getContactListModifiedSinceAsJSON( new Date( 2015, 9, 1 ) );

...

private function contacts_getContactsModifiedJSONHandler( event:ContactsJSONEvent ):void
{
trace( event.json );
}
- + \ No newline at end of file diff --git a/docs/contentprovider/add-the-extension/index.html b/docs/contentprovider/add-the-extension/index.html index bbe7d4201e7..88e0f80927a 100644 --- a/docs/contentprovider/add-the-extension/index.html +++ b/docs/contentprovider/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

You can access this extension here: https://github.com/distriqt/ANE-Core.

Android Support

The Android Support libraries encompass the Android Support, Android X and common Google libraries.

These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

This extension requires the following extensions:

You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

Note: if you have been using the older com.distriqt.androidsupport.* (Android Support) extensions you should remove these extensions and replace it with the androidx extensions listed above. This is the new version of the android support libraries and moving forward all our extensions will require AndroidX.

Extension IDs

The following should be added to your extensions node in your application descriptor to identify all the required ANEs in your application:

<extensions>
<extensionID>com.distriqt.ContentProvider</extensionID>
<extensionID>com.distriqt.Core</extensionID>
<extensionID>androidx.core</extensionID>
</extensions>

Android

Manifest Additions

The ContentProvider extension requires a few additions to the manifest to be able to start certain activities. You will need to replace any occurances of APPLICATION_PACKAGE with your application package name (generally your application id prefixed by air.)

<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>

<application android:hardwareAccelerated="true">


</application>
</manifest>

iOS

Info Additions

The following additions are for the InfoAdditions node of the iPhone section in your application descriptor:

<iPhone>
<InfoAdditions><![CDATA[

HERE

]]></InfoAdditions>
</iPhone>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ContentProvider.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/contentprovider/add-the-plugin/index.html b/docs/contentprovider/add-the-plugin/index.html index c2eaef494e6..942bfc02832 100644 --- a/docs/contentprovider/add-the-plugin/index.html +++ b/docs/contentprovider/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Add the Plugin

First step is always to add the plugin to your development environment.

Asset Store

Open the Asset Store in your browser and add the plugin to your assets.

Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

Manual Installation

In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.ContentProvider.unitypackage.

You can manually download the extension from our repository:

Import the Plugin

This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

The plugin will be added to your project and you can now use the plugins functionality in your application.

Resolve Android Dependencies

This plugin depends on some common Android libraries, particularly the Google Play Core Library, which enables in-app reviews.

You can get these dependencies using one of the following methods.

Unity Jar Resolver

This is the suggested method.

Use the Unity Jar Resolver plugin to download and manage the Android dependencies.

Importing

If you already use the Unity Jar Resolver in your project you can skip this step.

  • Download the latest version of the Unity Jar Resolver
  • Import the plugin by selecting Assets / Import Package / Custom Package ... and locate the plugin you downloaded. The plugin will be in the zip named: external-dependency-manager-latest.unitypackage
  • In the Import Unity Package window, click Import

Resolving

By default, the resolver should run automatically and will add the dependencies required by this plugin.

If you have need to resolve the dependencies manually then you will need to:

  • Open the menu under: Assets / External Dependency Manager / Android Resolver
  • Select Resolve or Force Resolve

More information on the Unity Jar Resolver can be found here

Custom Gradle ContentProvider

Unity's in-built gradle build support and exporting to android studio does not support per plugin gradle script. Therefore, this plugin cannot add the dependencies by itself.

The mainContentProvider.gradle is generated when you enable the Custom Gradle ContentProvider property on the Player window.

The build.gradle exists in generated Gradle project when you enable the Export Project property on the Player window and Build the project.

Update the dependencies section in your mainContentProvider.gradle or build.gradle as below:

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

implementation 'com.google.android.play:core:1.9.1'
}

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ContentProvider.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/contentprovider/changelog/index.html b/docs/contentprovider/changelog/index.html index 5c5ba9feae2..4f233789c3c 100644 --- a/docs/contentprovider/changelog/index.html +++ b/docs/contentprovider/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2021.11.29 [v0.1.0]
Initial build
- + \ No newline at end of file diff --git a/docs/contentprovider/index.html b/docs/contentprovider/index.html index d092e9ff1d4..6d8ed8a9c1f 100644 --- a/docs/contentprovider/index.html +++ b/docs/contentprovider/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

ContentProvider

The ContentProvider extension gives you access to ...

TODO

We provide complete guides to get you up and running with sharing quickly and easily.

Features

  • ...
  • Single API interface - your code works across iOS and Android with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

AIR

More information here:

com.distriqt.ContentProvider

License

You can purchase a license for using this extension:

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/contentprovider/unity/index.html b/docs/contentprovider/unity/index.html index 7b006305831..32027100b56 100644 --- a/docs/contentprovider/unity/index.html +++ b/docs/contentprovider/unity/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Unity

Contents

Overview

The ContentProvider plugin gives you access

TODO

Features

TODO

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Add the Plugin

First step is always to add the plugin to your development environment.

Asset Store

Open the Asset Store in your browser and add the ContentProvider plugin to your assets.

Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the ContentProvider plugin, and click Import in the bottom right.

Manual Installation

In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.ContentProvider.unitypackage.

You can manually download the extension from our repository:

Import the Plugin

This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

The plugin will be added to your project and you can now use the plugins functionality in your application.

Resolve Android Dependencies

This plugin depends on some common Android libraries, particularly the AndroidX support library.

You can get these dependencies using one of the following methods.

Unity Jar Resolver

This is the suggested method.

Use the Unity Jar Resolver plugin to download and manage the Android dependencies.

Importing

If you already use the Unity Jar Resolver in your project you can skip this step.

  • Download the latest version of the Unity Jar Resolver
  • Import the plugin by selecting Assets / Import Package / Custom Package ... and locate the plugin you downloaded. The plugin will be in the zip named: external-dependency-manager-latest.unitypackage
  • In the Import Unity Package window, click Import
Resolving

By default, the resolver should run automatically and will add the dependencies required by this plugin.

If you have need to resolve the dependencies manually then you will need to:

  • Open the menu under: Assets / External Dependency Manager / Android Resolver
  • Select Resolve or Force Resolve

More information on the Unity Jar Resolver can be found here

Custom Gradle ContentProvider

Unity's in-built gradle build support and exporting to android studio does not support per plugin gradle script. Therefore, this plugin cannot add the dependencies by itself.

The mainContentProvider.gradle is generated when you enable the Custom Gradle ContentProvider property on the Player window.

The build.gradle exists in generated Gradle project when you enable the Export Project property on the Player window and Build the project.

Update the dependencies section in your mainContentProvider.gradle or build.gradle as below:

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}

Usage

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ContentProvider.isSupported)
{
// Functionality here
}

Support

If you need further support integrating or using this extension please feel free to contact us.

We have been supporting developers for over 10 years and always happy to help.





- + \ No newline at end of file diff --git a/docs/core/changelog/index.html b/docs/core/changelog/index.html index 52f2451a0ca..8e85b76413b 100644 --- a/docs/core/changelog/index.html +++ b/docs/core/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.09.22 [v7.5.1]

fix(android): correct operation of authorisation result callbacks and add a complete event

2023.08.08 [v7.5.0]

feat(android): add new IActivityResultExtensionContext to simplify handling startActivityForResult on various platforms

2023.07.06 [v7.4.0]

feat(android): new IExtensionContext implementation to automatically create an activity for handling activity results

2023.06.29 [v7.3.1]

feat(android): auth updates to ensure compatibility with unity and other frameworks

2023.06.13 [v7.3.0]

feat(ios,macos,tvos): add some json utilities

2023.02.15 [v7.2.0]

feat(macos): add support for apple silicon processors
fix(android,auth): correct issue with fallback authorisation implementation events being dispatched to wrong extension

2023.01.23 [v7.0.2]

feat(android): add additional authorisation types for services that distinguish between always and in use

2023.01.16 [v7.0.1]

feat(android): add additional authorisation type to return events for distinguishing request source

2023.01.10 [v7.0.0]

feat(ios): remove bitcode 
feat(ios): add no-objc-msgsend-selector-stubs compiler flag
feat(android): add centralised permissions/auth functionality using new AIR callbacks

2022.08.01 [v6.4.8]

fix(android): add some additional file provider utilities for handling cache files

2022.08.01 [v6.4.7]

fix(android): add some additional file provider utilities for handling cache files

2022.06.23 [v6.4.6]

fix(macos): correct format of frameworks included in macos build allowing symlinks
feat(integration): update public integration libraries

2021.08.20 [v6.4.3]

AIR package release

2021.05.18 [v6.4.001]

Added windows 64bit support

2021.03.16 [v6.3.023]

Removed ios_version_min (#26)

2020.12.07 [v6.3.022]

Corrected framework in macOS build which caused issues with signing

2020.09.22 [v6.2.015]

Added additional iOS helper utilities

2020.09.12 [v6.2.013]

Android x64 support

2020.09.01 [v6.1.009]

Updated Core iOS libraries - fixed some iOS 12.4 related issues

2020.08.19 [v6.0.006]

Updated macOS library

2020.08.14 [v6.0.001]

Added macOS Core implementation for macOS extensions

2020.06.02 [v5.1.346]

Fixed iOS issue with multiple dispatching of launch options (eg notification events)

2020.05.15 [v5.1.343]

Updated to new iOS core library xcframework
Updated windows extcontext base code

2020.04.23 [v5.0.338]

Windows bug fix for ADL crash and removed event log usage (resolves #19)

2020.03.20 [v5.0.327]

Android X (resolves #18)
Added windows platform for common dependencies

2019.11.25 [v4.0.280]

Updated iOS libraries

2019.08.12 [v4.0.268]

Android 64bit support (resolves #8) 
Increased iOS minimum version to 9

2019.02.22 [v3.3.252]

Updated minimum iOS version to 8.0

2018.12.06 [v3.2.243]

Corrected issue with shortcut actions when in background

2018.10.29 [v3.2.239]

Updated generic FileProvider asset utilities for Android

2018.10.27 [v3.2.230]

Updated generic FileProvider utilities for Android

2018.08.15 [v3.2.224]

Lowered minimum supported version to AIR 24

2018.07.21 [v3.2.215]

Updated core Android lib

2018.06.25 [v3.2.202]

Reduced swf-version to increase compatibility

2018.06.24 [v3.2.198]

Android: Updated image conversion library

2018.06.01 [v3.2.187]

Added functionality to help with @available usage in iOS frameworks

2018.04.13 [v3.1.174]

Fixed issue with Android extensions accessing AIR view

2018.04.11 [v3.1.170]

Additional Android helpers

2018.04.04 [v3.1.166]

Updated internal caching of asset files

2018.03.24 [v3.1.152]

Added additional Android support libs

2018.03.10 [v3.1.133]

Updated iOS lib

2018.02.22 [v3.1.129]

Latest updates to core libraries

2018.02.09 [v3.0.117]

Added AppleTV platform and some bug fixes

2017.11.21 [v2.6.084]

Updates for Android core libs

2017.09.29 [v2.5.075]

Updates to the iOS App Delegate overrides to work better with other ANEs

2017.09.29 [v2.5.073]

Updates to the iOS App Delegate overrides to work better with other ANEs

2017.08.08 [v2.4.047]

Updated framework signature

2017.07.10 [v2.3.006]

iOS 10: Centralisation of new notifications delegate

2017.06.29 [v2.2.011]

Updates for Firebase Dynamic Links

2017.04.13 [v2.1.020]

Updates to core libraries

2017.04.06 [v2.1.018]

Updated Android libraries

2017.01.12 [v2.1.010]

Android: removed some old permissions

2017.01.12 [v2.1.008]

Small addition of an Android class used by some extensions

2016.12.15 [v2.1.006]

Latest Core additions and added noair version for conflict resolutions

2016.11.14 [v2.0.010]

Added additional Android core class

2016.09.01 [v2.0.005]

Added some Android logging utilities

2016.08.11 [v2.0.001]

Android support library update and new version system

2016.08.01

Updated core Android tools

2016.07.16

Updated to be compatible with latest support ANEs

2016.07.03

Added new common Android dependencies

2016.06.28

Update to include common AIR extension classes

2016.04.01

Latest updates for new notifications and force touch features

2015.06.15

Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.06.09

Changed core symbol definitions

2015.05.22

iOS: Corrected InvokeEvent operation (resolves #2, resolves distriqt/ANE-PushNotifications/#32, resolves distriqt/ANE-FacebookAPI/#27)

2015.03.04

Initial release
- + \ No newline at end of file diff --git a/docs/debug/add-the-extension/index.html b/docs/debug/add-the-extension/index.html index dc1fdce578a..29e412b705f 100644 --- a/docs/debug/add-the-extension/index.html +++ b/docs/debug/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.Debug

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.Debug.ane # Debug extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Debug.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/debug/changelog/index.html b/docs/debug/changelog/index.html index ae97fc5c639..6fb8c3f3317 100644 --- a/docs/debug/changelog/index.html +++ b/docs/debug/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.03.31 [v3.2.1]

feat(macos): add apple silicon support

2023.01.17 [v3.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2022.10.21 [v3.1.0]

feat(macos): add macos implementation

2022.02.04 [v3.0.30]

Add documentation for new site + usage of apm

2021.11.19 [v3.0.29]

Add air package

2020.03.23 [v3.0.014]

Android X migration (resolves #2)

2019.08.16 [v2.0.003]

Android 64bit support (resolves #1)
Updated minimum iOS version to 9.0

2019.03.12 [v1.1.012]

Updated minimum iOS version to 8.0
Embedded iOS bitcode

2018.11.26 [v1.0.010]

Initial release
- + \ No newline at end of file diff --git a/docs/debug/index.html b/docs/debug/index.html index 714ef790099..db6ffd90e20 100644 --- a/docs/debug/index.html +++ b/docs/debug/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Debug

The Debug extension gives you some useful tools to debug your application.

This extension is useful during development to ensure your application can handle unexpected application behavioues, such as forcing a crash, and throwing an exception.

You can also use the native logging functionality to add custom logs into the system device logs.

Features:

  • Native logging;
  • Force a crash;
  • Throw an exception;
  • List packaged android resources;
  • Force app termination;
  • Single API interface - your code works across supported platforms with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

Debug.service.forceCrash();

- + \ No newline at end of file diff --git a/docs/debug/usage/index.html b/docs/debug/usage/index.html index 556600c924f..3d6c398a3e1 100644 --- a/docs/debug/usage/index.html +++ b/docs/debug/usage/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Usage

Native Logging

Logging to the native logs can be useful when debugging your application when in a live environment. Logs will be output along with other native logs and make it easier to determine the cause of an issue if interacting with other native processes.

To log an entry to the native log use the log() method:

Debug.service.log( "some message", "TAG (optional)" );
- + \ No newline at end of file diff --git a/docs/devicemotion/add-the-extension/index.html b/docs/devicemotion/add-the-extension/index.html index 7826fec29cc..68c766dc2e6 100644 --- a/docs/devicemotion/add-the-extension/index.html +++ b/docs/devicemotion/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.DeviceMotion

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.DeviceMotion.ane # DeviceMotion extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (DeviceMotion.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/devicemotion/algorithms-and-format/index.html b/docs/devicemotion/algorithms-and-format/index.html index fa530dc99ef..b1e007909bc 100644 --- a/docs/devicemotion/algorithms-and-format/index.html +++ b/docs/devicemotion/algorithms-and-format/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Algorithms and Format

Algorithm

The available algorithms are defined in the Algorithm class.

There are currently 2 algorithms however we highly recommend using the Algorithm.NATIVE algorithm. It is the native fusion algorithm and currently produces the most reliable results. This algorithm is implemented by the OS and in recent releases has become the fastest and best algorithm available on mobile devices.

The Algorithm.FUSION is an algorithm drawn together from suggested practices however doesn't seem to get as good results as the native algorithm. We don't recommend using this algorithm except on old devices when the native algorithm wasn't as reliable.

Reference Frame

The reference frame defines reference that is used as the "zero point" of the frame. The main difference between the reference frames is whether the magnetometer and location sensors are used to determine the direction of north for the device.

Generally the best response will be achieved by not using the sensors required to determine the north direction, as these sensors (in particular the magnetometer) can be greatly influenced by the environmental conditions.

The available reference frames are defined in the ReferenceFrame class.

  • ReferenceFrame.Y_ARBITRARY_Z_VERTICAL: Use this sensor in a game or VR application if you do not care about where north is. This does not use the magnetometer.
  • ReferenceFrame.Y_MAGNETICNORTH_Z_VERTICAL: Describes a reference frame in which the Z axis is vertical and the Y axis points toward the geomagnetic North Pole.

Output Format

The available formats are defined in the OutputFormat class.

We highly suggest you use the quaternion format (OutputFormat.QUATERNION) to position the device. This format is the most stable and easiest to use. It is widely supported by 3D engines including Away3D which is used in the example code.

Euler angles are the traditional roll, pitch and yaw angles. However these angles are susceptible to what is known as Gimbal lock, and should be avoided wherever possible. This becomes more evident in device motion where the gimbal lock conditions can be reached quite easily as part of everyday usage. If you do decide to use this format be prepared to deal with some unusual values around the Gimbal lock condition.

For more information : http://en.wikipedia.org/wiki/Gimbal_lock

Support

You can check if a particular algorithm and format combination is supported on the current device. This allows you to dynamically react to particular devices and choose the most appropriate algorithm and format for your needs.

To check support, call the isAlgorithmSupported function with the algorithm and format of interest:

if (DeviceMotion.service.isAlgorithmSupported( algorithm, format ))
{
// Algorithm and format are available on the current device
}
- + \ No newline at end of file diff --git a/docs/devicemotion/changelog/index.html b/docs/devicemotion/changelog/index.html index 10592f4f46e..994ea6ca05e 100644 --- a/docs/devicemotion/changelog/index.html +++ b/docs/devicemotion/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.17 [v4.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2022.02.04 [v4.1.2]

Update docs to use apm

2021.12.16 [v4.1.1]

Add air package parameter descriptions

2021.10.05 [v4.1.0]

Added air package
Removed ios minimum version flag
Added Android x64 support

2020.03.23 [v4.0.006]

Android X migration (resolves #27)

2019.08.16 [v3.0.003]

Android 64bit support (resolves #26)
Updated minimum iOS version to 9.0
Embedded iOS bitcode
Removed application keys

2017.10.09 [v2.0.047]

Added 'Reference Frames' to allow removal of the magnetometer from the fusion algorithms (resolves #18, resolves #17, #24)

2017.07.10 [v1.7.003]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2016.12.23 [v1.7.002]

Update to latest Android and iOS versions + documentation update

2015.06.15

Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.06.15

Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.02.22

Changed class structure to support FlashBuilder 4.6 (resolves #10)

2015.01.31

Updated Euler outputs so angles are continuous through the vertical position (resolves #8)
iOS: Added check for .debug suffix in application id
iOS: Corrected isAlgorithmSupported return value

2014.12.19

iOS: Included arm64 support (resolves #1) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.01

New application based key check, removing server checks

2014.10.24

iOS Update for iOS 8 + Android device default orientation fix
- iOS: Update for iOS 8
- Android: Corrected errors with devices with landscape default orientation (resolves #138)
- Android+iOS: Added autoOrient option to handle coordinate system with orientation changes
- + \ No newline at end of file diff --git a/docs/devicemotion/index.html b/docs/devicemotion/index.html index 881476835b6..50ea2fa3e03 100644 --- a/docs/devicemotion/index.html +++ b/docs/devicemotion/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ which combine the available sensors into orientation and rotational information. The quality of this information depends mainly on the hardware contained in the current device. Generally we require 3 sensors for these calculations: an accelerometer, a magnetometer and a gyroscope.

The extension works by registering for notifications of device motion. When you register for updates you specify a series of options about the updates which the extension use to determine the algorithm that is used to calculate the device orientation, and also the information format that is returned.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

DeviceMotion.service.addEventListener( DeviceMotionEvent.UPDATE_QUATERNION, deviceMotion_updateHandler );

var options:DeviceMotionOptions = new DeviceMotionOptions();
options.rate = SensorRate.SENSOR_DELAY_NORMAL;
options.algorithm = DeviceMotionOptions.ALGORITHM_NATIVE;
options.format = DeviceMotionOptions.FORMAT_QUATERNION;

DeviceMotion.service.register( options );

private function deviceMotion_updateHandler( event:DeviceMotionEvent ):void
{
var q:Quaternion = new Quaternion( event.values[1], event.values[2], event.values[3], event.values[0] );
}

More information here:

com.distriqt.DeviceMotion

License

You can purchase a license for using this extension:

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/devicemotion/register-for-updates/index.html b/docs/devicemotion/register-for-updates/index.html index bfe2d0cfe2a..e905c5bb171 100644 --- a/docs/devicemotion/register-for-updates/index.html +++ b/docs/devicemotion/register-for-updates/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ unless you unregister the sensor.

DeviceMotion.service.unregister();

Notes

We highly suggest that you check for deactivation events in your application and make sure that you unregister the device motion updates. This is to reduce strain on the device and increase battery life.

Something like the following:

NativeApplication.nativeApplication.addEventListener( Event.DEACTIVATE, deactivateHandler );

function deactivateHandler( event:Event ):void
{
try
{
if (DeviceMotion.isSupported && DeviceMotion.service.isRegistered)
DeviceMotion.service.unregister();
}
catch (e:Error)
{
}
}
- + \ No newline at end of file diff --git a/docs/dialog/action-sheet/index.html b/docs/dialog/action-sheet/index.html index 0dc2166c942..3f74c666325 100644 --- a/docs/dialog/action-sheet/index.html +++ b/docs/dialog/action-sheet/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Action Sheet

Action sheets display a set of buttons representing several alternative choices to complete a task initiated by the user. It allows your application to get a user to quickly select from a list of actions or to confirm / cancel an action.

The list is presented from the bottom of the screen.

An Action Sheet is created by using an ActionSheetBuilder.

var actionSheet:DialogView = Dialog.service.create( 
new ActionSheetBuilder()
.setTitle( "Pick an Action" )
.setMessage( "Pick one of the following amazing options" )
.addAction( "The first action" )
.addAction( "Second thing" )
.addAction( "Cancel", DialogAction.STYLE_CANCEL )
.build()
);

actionSheet.addEventListener( DialogViewEvent.CLOSED, actionSheet_closedHandler );
actionSheet.show();

...

private function actionSheet_closedHandler( event:DialogViewEvent ):void
{
trace( "actionSheet closed " + event.index );
var actionSheet:DialogView = DialogView(event.currentTarget);
actionSheet.removeEventListener( DialogViewEvent.CLOSED, actionSheet_closedHandler );
actionSheet.dispose();
}
- + \ No newline at end of file diff --git a/docs/dialog/activity-dialog/index.html b/docs/dialog/activity-dialog/index.html index d5aa4b0b51b..6a6b49e9d40 100644 --- a/docs/dialog/activity-dialog/index.html +++ b/docs/dialog/activity-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It is a very simple activity indicator which can be used in cases where the Progress Dialog is too detailed. Generally it just displays a native activity indicator in the form of a circular spinner.

An activity dialog is created by using an ActivityBuilder.

var activityDialog:DialogView = Dialog.service.create( 
new ActivityBuilder()
.setTheme( new DialogTheme( DialogTheme.DEVICE_DEFAULT_DARK ))
.build()
);
activityDialog.show();

To remove the activity dialog simply call dismiss() as below:

activityDialog.dismiss();

iOS Additions

iOS allows some minor additions to the display of the activity dialog. You can either use the native iOS activity indicator which is a spinner type animation with marks around a circle or an annular style more closely resembling the more modern look of the Android activity indicator. You specify the difference using the setStyle function on the builder, using either DialogType.STYLE_ANNULAR or DialogType.STYLE_SPINNER

On iOS you can also add some text below the animation by using the setTitle function. For example:

new ActivityBuilder()
.setTheme( new DialogTheme( DialogTheme.DEVICE_DEFAULT_DARK ))
.setStyle( DialogType.STYLE_SPINNER )
.setTitle( "Test Title" )
.build()
DialogType.STYLE_ANNULARDialogType.STYLE_SPINNER
- + \ No newline at end of file diff --git a/docs/dialog/add-the-extension/index.html b/docs/dialog/add-the-extension/index.html index bea91121926..8a033c9dd97 100644 --- a/docs/dialog/add-the-extension/index.html +++ b/docs/dialog/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

AIR SDK

This ANE requires AIR version 33 +, due to the additions for Android, in particular the ability to use the Android X libraries.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.Dialog

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.Dialog.ane # Dialog extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Dialog.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/dialog/air-fallback/index.html b/docs/dialog/air-fallback/index.html index 80bab3df45b..956cbba359c 100644 --- a/docs/dialog/air-fallback/index.html +++ b/docs/dialog/air-fallback/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ These are mainly designed for testing and currently only the following dialogs are supported:

We will progressively be adding more of these dialogs, please feel free to request an implementation in github.

In order for these to display, you must inform the Dialog ANE of a container for the dialogs to be displayed. Generally this should either be the Stage or a container display object (such as the nativeOverlay property in Starling). For example in a simple AIR project you would need:

Dialog.service.root = stage;

or for Starling:

Dialog.service.root = Starling.current.nativeStage;

This will be ignored when on a real device.

- + \ No newline at end of file diff --git a/docs/dialog/alerts/index.html b/docs/dialog/alerts/index.html index 6fb5501f355..29a375fb71a 100644 --- a/docs/dialog/alerts/index.html +++ b/docs/dialog/alerts/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ such as a username and password. You add text fields by using the addTextField function on the AlertBuilder. The values for the text fields are then returned in the values array on the closed event.

var alert:DialogView = Dialog.service.create( 
new AlertBuilder()
.setTitle( "Text Input Alert" )
.setMessage( "Enter your username and password" )
.addTextField( "", "Username" )
.addTextField( "", "Password", true )
.addOption( "OK", DialogAction.STYLE_POSITIVE )
.addOption( "Cancel", DialogAction.STYLE_CANCEL )
.build()
);
alert.addEventListener( DialogViewEvent.CLOSED, textInputAlert_closedHandler );
alert.show();

...

private function textInputAlert_closedHandler( event:DialogViewEvent ):void
{
trace( "text input closed: " + event.index +"::"+ event.values.join(",") );
var alert:DialogView = DialogView(event.currentTarget);
alert.removeEventListener( DialogViewEvent.CLOSED, textInputAlert_closedHandler );
alert.dispose();
}
- + \ No newline at end of file diff --git a/docs/dialog/changelog/index.html b/docs/dialog/changelog/index.html index 96155da4749..bf07b45d078 100644 --- a/docs/dialog/changelog/index.html +++ b/docs/dialog/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.17 [v8.7.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2022.03.16 [v8.6.11]

Add missing android emoji2 dependency to air package (resolves #285)

2022.02.18 [v8.6.10]

Resolved issue with android text field KeyboardType.NAME_PHONE_PAD (resolves #283)

2022.02.05 [v8.6.9]

Update package dependencies
Update docs to use apm

2021.10.05 [v8.6.8]

Add air package

2021.07.06 [v8.6.7]

Added new iOS date / time dialog implementation (resolves #263)

2021.07.04 [v8.5.6]

Updated asdocs

2021.07.03 [v8.5.5]

Added different autocapitalisation types (resolves #275)

2021.07.02 [v8.5.4]

Android: Fixed spacing between buttons on Samsung devices (resolves #273)
iOS: Fixed toast display in fullscreen on devices with notches (resolves #274)
Added auto capitalisation and auto correct options to addTextField method (resolves #275)

2021.03.16 [v8.4.094]

Removed ios_version_min (#26)

2020.11.25 [v8.4.092]

iOS: Corrected issue with determinate progress dialog style (resolves #265)

2020.11.16 [v8.3.073]

Fixed packaging issue with IntelliJ on windows (resolves #264)

2020.11.11 [v8.3.071]

iOS: Corrected date/time dialogs on iOS 14 (resolves #262) 
Implemented default progress dialog (resolves #125)

2020.10.28 [v8.2.058]

Android: Fixed issue when attempting to set selected index to the last item in a picker (resolves #260)
Android: Corrected issues with selected / closed events in the date / time picker (resolves #257, resolves #186)

2020.10.01 [v8.2.046]

iOS: Resolved crash with stage text on iOS 14 (resolves #258)
tvOS: Updates for issues caused by iOS dark theme
Android: x64 support

2020.05.08 [v8.1.026]

iOS: Corrected system dark theme colours (resolves #253)

2020.03.23 [v8.0.013]

Android X migration (resolves #248)

2019.08.16 [v7.0.004]

Android 64bit support (resolves #237)
Updated minimum iOS version to 9.0
Embedded iOS bitcode

2018.12.05 [v6.0.242]

iOS: Reverted transparency of activity dialog background (resolves #224)

2018.12.01 [v6.0.240]

iOS: Removed @available references for Windows compatibility (resolves #221)

2018.11.21 [v6.0.234]

tvOS implementation (resolves #150)
Added better padding around text input dialogs
Added ability to update message in a progress dialog (resolves #181)
Removed application key requirements

2018.06.20 [v5.1.178]

iOS: Added additional checks when adding dialogs to the view

2018.03.25 [v5.1.175]

Resolved theme issues with latest app compat libraries (resolves #208)

2018.03.20 [v5.1.164]

Added alpha for toast dialogs (resolves #207)
Added style options for activity dialog on iOS (resolves #206)

2018.01.08 [v5.1.153]

Added colour for toast dialogs (resolves #193)
Added gravity for positioning toast dialogs (resolves #169)

2017.12.11 [v5.1.134]

Updated toast timings (resolves #198)

2017.12.06 [v5.1.133]

Fixed issue with Android action sheet compat usage (resolves #196)

2017.10.20 [v5.1.124]

Android: Fixed popover events (resolves #189)

2017.08.01 [v5.1.096]

Added ability to change the index of a picker dialog (resolves #178)
Android: Fixed alert with many options (resolves #179)

2017.07.10 [v5.1.075]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.07.09 [v5.1.074]

Fixed potential crash with error handler

2017.04.13 [v5.1.072]

Added TODAY option to the DateTime Dialog (resolves #149)

2017.03.21 [v5.0.058]

Android: Resolves multiselect issue on Android N (resolves #136)

2016.12.21 [v5.0.036]

Updating documentation

2016.12.19 [v5.0.036]

Added Animate example

2016.12.16 [v5.0.036]

Added images

2016.12.16 [v5.0.036]

iOS: Fix for iOS 7 (#153, #154)
AIR Simulator Activity indicator implementation
Added wiki documentation

2016.11.25 [v5.0.030]

iOS: Fix for displaying alerts above top view controller (resolves #151)
iOS: Fix for TextView dialog on iOS 10 (resolves #148)

2016.10.13 [v5.0.024]

Implemented setCancelable on builders (resolves #140)
Android: Updated cancellation of DateTime dialog (#139)

2016.10.03 [v5.0.022]

Android: Corrected date time cancel action (resolves #139)
Android: Corrected date time maximum (resolves #143)

2016.09.06 [v4.8.011]

Updated simple example application

2016.08.15 [v4.8.006]

Corrected issue with closed event from Alerts dispatching early (resolves #133)

2016.08.03

Updated Core library compatibility

2016.07.12

Default: Added checks for root display object (resolves #127)

2016.07.11

Added the ActivityBuilder.setCancelable function to set whether clicking outside cancels the dialog (resolves #124)
Android: Corrected time returned on close when only changing AM/PM (resolves #121)
Default: Added the AIR simulator version of the Alert Dialog (resolves #105)
Default: Added the AIR simulator version of the Toast Dialog (resolves #126)

2016.06.23

iOS: Corrected orientation of picker dialogs on iOS < 8.1 (resolves #118)

2016.06.18

iOS: Corrected Alert Dialogs on iOS 6, 7 (resolves #116)

2016.06.15

Android: Centered title and added ability to show message (resolves #114)

2016.06.05

iOS: Added cancelled event to progress dialog (resolves #113)

2016.06.03

Allowed removal of title and message areas on ActionSheet (resolves #112)
iOS: Fixed ActionSheet implementation on iOS < v8
iOS: Implemented the progress dialog cancellable property (resolves #104)

2016.05.21

iOS: Fixed date dialog min/max ranges (resolves #107)
iOS: Added delegate removal on dispose of progress (#106)

2016.04.20

Android: Fixed issue with invalid package name and key validation (resolves #100)

2016.04.13

iOS: Fixed issue with initial values of MultiSelect dialog

2016.04.12

Implemented the setIdentifier builder function to allow custom ids (resolves #98)

2016.04.06

Added the TextViewAlertBuilder for multiline text input (resolves #71)
Updated default lib to match native class signatures (#94)

2016.04.06

Added the TextViewAlertBuilder for multiline text input (resolves #71)
Updated default lib to match native class signatures (#94)

2016.02.27

Android: Fixed date time background on v5+ (resolves #83)

2016.02.27

Date Time Dialog update including DateTimeDialogBuilder (resolves #80, resolves #38, #79)

2016.02.22

Android: Fixed issue with auto focus on text inputs (resolves #81)
Android: Fixed issue with progress 'Invalid JSON' (resolves #82)

2016.02.14

Updated asdoc documentation

2016.02.06

Corrected missing date events (resolves #76)

2016.02.01

Fix for Flash CC incorrectly handling some simple actionscript (resolves #74)

2016.01.30

Documentation update

2016.01.30

Introducing Dialog Builders 

ActionSheet (resolves #66)
Activity indicator (resolves #43, resolves #36)
Multi-Selection Dialog (resolves #60, resolves #46, resolves #16)
Custom Picker (resolves #33)

iOS: Added theme (light/dark) to progress dialog (resolves #47)
Android: Fixed message string not displaying in multiple option dialog (resolves #72)
Android: Changed resource package folder name (resolves #6)

2015.12.12

iOS: Corrected issues introduced from last commit (resolves #67)

2015.12.11

Fixed issue with comma producing additional buttons in 'otherLabels' field (resolves #65)

2015.11.10

Android: Material Theme and global theme settings (resolves #15, #47, #58)
Android: Updated Popover Theme (resolves #21)
Android: Fixed Soft Keyboard not hiding (resolves #49)

2015.06.23

Android: Fix for time picker dialog on 5.0 not returning correct time (resolves #52)

2015.06.12

Android: Changed name of resource folder to avoid conflicts (resolves #51)
Android: x86 Support

2015.06.02

Repackaged to test distriqt/ANE-Calendar#10

2015.05.19

Corrected default library method signatures (#44)

2015.04.28

iOS: Fixed conflict with Toast class (resolves #39)

2015.03.23

iOS: Fixed events not dispatching from Alerts on iOS < 8 (resolves #32)

2015.03.19

iOS: Moved all alerts to the new iOS 8 UIAlertController to fix orientation issues (resolves #25)
Added the ability to initialise input text alert with text, and place holder text (resolves #27)
Added the ability to set keyboard type on input text alert (resolves #13)

2015.03.18

iOS: Fix for 0 value on width / hieght of position of popover (resolves: #31)

2015.03.16

iOS: Corrected popover positioning on some versions of iOS (resolves #28)
Android: Fixed selected index starting from -1 instead of 0 (resolves #22)
Changed class structure to support FlashBuilder 4.6

2015.02.03

Android: Corrected time picker incorrectly always displaying AM (resolves #11)
Android: Implemented a fallback option for older SDK (< v11). This will fix the application crash on 2.3.7 (resolves #9)

2015.02.02

Added check for .debug suffix in application id

2015.01.23

iOS: Corrected popover positioning when a toast is visible (resolves #2)

2015.01.23

iOS: Fixed popover positioning on iOS > 8.1 due to changed coordinate systems (resolves #7)
iOS: Updated progress dialog to correctly handle orientations on iOS > 8.1 (resolves #10)
iOS: Corrected popover selection of last item due to navigation bar (resolves #1)

2014.12.23

iOS: Fixed iOS 8 toast orientation issue (resolves #5)

2014.12.19

iOS: Included arm64 support (resolves #4) 
Android: Corrected application id check when doesn't contain air prefix

2014.12.05

Corrected missing EventDispatcher functions from base class
iOS: Implemented autoreleasepools for all C function calls

2014.12.01

New application based key check, removing server checks

2014.11.26

Changed version check for iOS 8.0 orientations #256

2014.11.21

Added CHANGELOG

2014.11.21

iOS DateTime Landscape correction
- iOS: Fixes #256 so that a date time dialog is correctly displayed in landscape and portrait modes

2014.10.18

iOS Update for iOS 8
- iOS: Corrected progress dialog rotation (resolves #225)

2014.10.13

iOS Update for iOS 8
- iOS: Fixed compilation error 'ld: 21 duplicate symbols for architecture armv7' (resolves #119)
- iOS: Updated toast and progress dialog to latest versions
- iOS: Added cancelOnTouchOutside functionality to iPhone devices (resolves #88 & #208)
- + \ No newline at end of file diff --git a/docs/dialog/custom-picker/index.html b/docs/dialog/custom-picker/index.html index fa70c1ff07d..8fa6488ceb7 100644 --- a/docs/dialog/custom-picker/index.html +++ b/docs/dialog/custom-picker/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ PickerDialogView. Each spinner or column is created by calling addColumn on the builder and passing an array of possible values and the index of the initially selected value.

var picker:PickerDialogView = Dialog.service.create(
new PickerDialogBuilder()
.setTitle( "Pick a Value" )
.setCancelLabel("Cancel")
.setAcceptLabel("Done")
.addColumn( [ "Item 1", "Item 2", "Item 3" ], 2 )
.addColumn( [ "1", "2", "3", "4", "5", "6" ], 1 )
.build()
);

picker.addEventListener( DialogViewEvent.CLOSED, picker_closedHandler );
picker.addEventListener( DialogViewEvent.CANCELLED, picker_closedHandler );
picker.addEventListener( DialogViewEvent.CHANGED, picker_changedHandler );
picker.show();

...

private function picker_changedHandler( event:DialogViewEvent ):void
{
trace( "picker changed [ " + event.indexes.join(",") + " ] " + event.values.join(",") );
}

private function picker_closedHandler( event:DialogViewEvent ):void
{
trace( "picker closed ("+event.index+") -> [ " + event.indexes.join(",") + " ] " + event.values.join(",") );
var picker:PickerDialogView = PickerDialogView(event.currentTarget);
picker.removeEventListener( DialogViewEvent.CLOSED, picker_closedHandler );
picker.removeEventListener( DialogViewEvent.CANCELLED, picker_closedHandler );
picker.removeEventListener( DialogViewEvent.CHANGED, picker_changedHandler );
picker.dispose();
}

Updating the selected indices

You can change the selected items in the picker by using the setSelectedIndex method on the PickerDialogView. For example to change the index of the second column to the fourth value (indexes are zero based):

picker.setSelectedIndex( 1, 3 );
- + \ No newline at end of file diff --git a/docs/dialog/date-time-dialog/index.html b/docs/dialog/date-time-dialog/index.html index ac0ce6c78d5..7cd67137a2f 100644 --- a/docs/dialog/date-time-dialog/index.html +++ b/docs/dialog/date-time-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ the value displayed in the dialog using the DateTimeDialogView interface.

var dateTime:DateTimeDialogView = Dialog.service.create( 
new DateTimeDialogBuilder()
.setMode( DialogType.MODE_TIME )
.setTitle( "Select Time" )
.setAcceptLabel( "ACCEPT" )
.setCancelLabel( "Cancel" )
.build()
);
dateTime.setTime( 9, 30 );

dateTime.addEventListener( DialogViewEvent.CLOSED, dateTime_closedHandler );
dateTime.addEventListener( DialogDateTimeEvent.SELECTED, dateTime_selectedHandler );

dateTime.show();



function dateTime_selectedHandler( event:DialogDateTimeEvent ):void
{
trace( event.type +"::"+ event.date.toString() );
}

function dateTime_closedHandler( event:DialogViewEvent ):void
{
var dateTime:DateTimeDialogView = DateTimeDialogView(event.currentTarget);
dateTime.removeEventListener( DialogViewEvent.CLOSED, dateTime_closedHandler );
dateTime.removeEventListener( DialogDateTimeEvent.SELECTED, dateTime_changedHandler );
dateTime.dispose();
}

iOS

On iOS versions previous to 14 used a "picker" style dialog using wheels to select the date and time. iOS 14 introduces a new style which we have applied as the default and presented in a modal dialog.

If you wish to retain the legacy style utilising the picker then you can call usePickerIfAvailable() on your builder:

new DateTimeDialogBuilder()
.setMode( DialogType.MODE_TIME )
.setTitle( "Select Time" )
.setAcceptLabel( "ACCEPT" )
.setCancelLabel( "Cancel" )
.usePickerIfAvailable() // Forces picker / wheels usage on iOS
.build()

Adding a TODAY button

You can add a button to the dialog which will allow the user to select the current day by using the setTodayLabel method on the DateTimeDialogBuilder.

var builder:DateTimeDialogBuilder = new DateTimeDialogBuilder();
// other options...

builder.setTodayLabel( "Today" );

This will add an additional button to the dialog that will set the date to the current date as reported by the user's device.

When the user clicks this button you will receive the normal date change events.

- + \ No newline at end of file diff --git a/docs/dialog/dialog-views-and-builders/index.html b/docs/dialog/dialog-views-and-builders/index.html index ed4033cbc54..3ec48323eb8 100644 --- a/docs/dialog/dialog-views-and-builders/index.html +++ b/docs/dialog/dialog-views-and-builders/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ as soon as the dialog is dismissed. To use this method you must pass true to the constructor of your dialog builder to specify the dialog should be disposed automatically when closed.

Dispose on close can be used to display a simple Alert without having to respond to the close event and dispose the resources yourself. The following example demonstrates this:

Dialog.service.create( 
new AlertBuilder( true )
.setTitle( "Alert" )
.setMessage( "Test Message" )
.addOption( "OK" )
.build()
).show();
- + \ No newline at end of file diff --git a/docs/dialog/index.html b/docs/dialog/index.html index ae3890d1476..9ef6cc0c9d9 100644 --- a/docs/dialog/index.html +++ b/docs/dialog/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ will be able to display many different forms of dialogs, giving your application a consistent natively integrated UI.

We provide complete guides to get you up and running with dialogs quickly and easily.

Latest Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

- + \ No newline at end of file diff --git a/docs/dialog/migrating-to-androidx/index.html b/docs/dialog/migrating-to-androidx/index.html index 15f3c4ab2f7..0f9876eded5 100644 --- a/docs/dialog/migrating-to-androidx/index.html +++ b/docs/dialog/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/dialog/multi-select/index.html b/docs/dialog/multi-select/index.html index 7ddb365240d..c8594262835 100644 --- a/docs/dialog/multi-select/index.html +++ b/docs/dialog/multi-select/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ specified by calling setValues on the builder and passing an array of possible options or values along with an array of Boolean values indicating the selected state of each corresponding value.

var multiSelect:DialogView = Dialog.service.create( 
new MultiSelectBuilder()
.setTitle( "Options" )
.setAcceptLabel( "OK" )
.setCancelLabel( "Cancel" )
.setValues( ["Vibration", "Rotation", "Fullscreen" ], [ true, true, false ] )
.build()
);

multiSelect.addEventListener( DialogViewEvent.CLOSED, multiSelect_closedHandler );
multiSelect.addEventListener( DialogViewEvent.CANCELLED, multiSelect_closedHandler );
multiSelect.addEventListener( DialogViewEvent.CHANGED, multiSelect_changedHandler );
multiSelect.show();

...

private function multiSelect_changedHandler( event:DialogViewEvent ):void
{
trace( "multiSelect changed [ " + event.indexes.join(",") + " ] " + event.values.join(",") );
}

private function multiSelect_closedHandler( event:DialogViewEvent ):void
{
trace( "multiSelect closed ("+event.index+") -> [ " + event.indexes.join(",") + " ] " + event.values.join(",") );
var multiSelect:DialogView = DialogView(event.currentTarget);
multiSelect.removeEventListener( DialogViewEvent.CLOSED, multiSelect_closedHandler );
multiSelect.removeEventListener( DialogViewEvent.CANCELLED, multiSelect_closedHandler );
multiSelect.removeEventListener( DialogViewEvent.CHANGED, multiSelect_changedHandler );
multiSelect.dispose();
}
- + \ No newline at end of file diff --git a/docs/dialog/progress-dialog/index.html b/docs/dialog/progress-dialog/index.html index dd9a6bdf229..399dc6e679b 100644 --- a/docs/dialog/progress-dialog/index.html +++ b/docs/dialog/progress-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ an annular / circular fill.

A progress dialog is created by using an ProgressDialogBuilder. The create function will return a progress dialog specific DialogView represented by the ProgressDialogView class.

var progressDialog:ProgressDialogView = Dialog.service.create( 
new ProgressDialogBuilder()
.setTitle( "A Long Process is happening" )
.setMessage( "Loading..." )
.setStyle( DialogType.STYLE_HORIZONTAL )
.setCancelable( false )
.setTheme( new DialogTheme( DialogTheme.DEVICE_DEFAULT_LIGHT ))
.build()
);

progressDialog.show();

Updating Progress

For a determinate progress dialog you can update the displayed value by calling update on the ProgressDialogView instance.

var progressInterval:uint;
var progress:Number = 0;
var progressDialog:ProgressDialogView;

if (Dialog.isSupported)
{
progressDialog = Dialog.service.create(
new ProgressDialogBuilder()
.setTitle( "A Long Process is happening" )
.setMessage( "Loading..." )
.setStyle( DialogType.STYLE_HORIZONTAL )
.setCancelable( false )
.setTheme( new DialogTheme( DialogTheme.DEVICE_DEFAULT_LIGHT ))
.build()
);
progressDialog.addEventListener( DialogViewEvent.CLOSED, progressDialog_closedHandler );
progressDialog.show();

progress = 0;
progressDialog.update( progress );

progressInterval = setInterval( progressDialog_intervalHandler, 2000 );
}

...

private function progressDialog_intervalHandler():void
{
progress += 0.1; // Change the value by some amount
progressDialog.update( progress );

if (progress >= 1) // Dismiss the dialog when complete
{
clearInterval( progressInterval );
progressDialog.dismiss();
}
}

private function progressDialog_closedHandler( event:DialogViewEvent ):void
{
trace( "progress dialog closed" );
progressDialog.removeEventListener( DialogViewEvent.CLOSED, progressDialog_closedHandler );
progressDialog.dispose();
}

Updating Message

Similarly you can update the message displayed in the progress dialog by using the setMessage() function on the ProgressDialogView instance.

For example you could update the text to represent the percentage complete of the process the progress dialog is tracking:

var percent:Number = ...;

progressDialog.setMessage( "Loading " + percent + "% complete" );
- + \ No newline at end of file diff --git a/docs/dialog/text-view-alert/index.html b/docs/dialog/text-view-alert/index.html index 421ae22c1c8..0ac248d2bda 100644 --- a/docs/dialog/text-view-alert/index.html +++ b/docs/dialog/text-view-alert/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Text View Alert

The Text View Alert is very similar to the basic Alert with text inputs except it contains a single text input allowing multiple lines of text.

It is created using the TextViewAlertBuilder.

The dialog is a modal dialog that can display a title, a message and 2 actions.

var textViewAlert:DialogView = Dialog.service.create( 
new TextViewAlertBuilder()
.setTitle( "Enter some text" )
.setMessage( "Please enter some multiline text" )
.addOption( "OK", DialogAction.STYLE_POSITIVE, 0 )
.build()
);
textViewAlert.addEventListener( DialogViewEvent.CLOSED, textViewAlert_closedHandler );
textViewAlert.show();

...

private function textViewAlert_closedHandler( event:DialogViewEvent ):void
{
trace( "text view closed: " + event.index +"::"+ event.values.join(",") );
var alert:DialogView = DialogView(event.currentTarget);
alert.removeEventListener( DialogViewEvent.CLOSED, alert_closedHandler );
alert.dispose();
}
- + \ No newline at end of file diff --git a/docs/dialog/toast/index.html b/docs/dialog/toast/index.html index feda4e16585..9f14723c9e8 100644 --- a/docs/dialog/toast/index.html +++ b/docs/dialog/toast/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ user with no interaction. You can use these to provide small pieces of information to your user, such as a background process completing.

It is a very simple dialog and requires no builder, simply call the toast function with the string you wish to display:

Dialog.service.toast( "An amazing toast" );

Length

You can select either a long or short time for the toast to be displayed. A short toast will be displayed for approximately 2 seconds and a long toast approximately 4 seconds.

Dialog.service.toast( "An amazing toast", Dialog.LENGTH_LONG );

The default is a short toast (Dialog.LENGTH_SHORT).

Colour

You can set the background colour of the toast by providing the third parameter to the function. This is an RGB value used for the background area of the toast.

Dialog.service.toast( "An amazing toast", Dialog.LENGTH_SHORT, 0xFF0000 );

Alpha

We have added the ability to set the alpha as well as the colour of the toast background. This is now the last parameter, for example to set the alpha to 0.5:

Dialog.service.toast( "An amazing toast", Dialog.LENGTH_SHORT, 0xFF0000, Gravity.BOTTOM, 0.5 );

Position

A standard toast notification appears near the bottom of the screen, centered horizontally. You can change the positioning by changing the gravity parameter to be one of:

For example to display a toast in the middle of the screen:

Dialog.service.toast( "An amazing toast", Dialog.LENGTH_SHORT, 0x333333, Gravity.MIDDLE );
- + \ No newline at end of file diff --git a/docs/dynamicicon/add-the-extension/index.html b/docs/dynamicicon/add-the-extension/index.html index 70735d01811..0a1ff8c9add 100644 --- a/docs/dynamicicon/add-the-extension/index.html +++ b/docs/dynamicicon/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.DynamicIcon

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.DynamicIcon.ane # DynamicIcon extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (DynamicIcon.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/dynamicicon/adding-icons/index.html b/docs/dynamicicon/adding-icons/index.html index 58be0331fa1..6039a110c77 100644 --- a/docs/dynamicicon/adding-icons/index.html +++ b/docs/dynamicicon/adding-icons/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Creating Icon Assets

In order to add icons to your application you firstly need to create the icon assets and add them to your application. With Xcode 13 in the recent releases of AIR you can now use icons in an asset catalogue, (the same way as you provide your application icon). Alternatively you can use the legacy method of generating png files and including them in your application.

Method 1: Asset Catalogue

The easiest way is to use our image script to generate the asset catalogue, you can download this script here. This will generate your app icon and launch storyboard along with any required alternate icons.

To summarise the process:

  • create a 1024x1024 png image and name it icon.png (this is your application icon)
  • create a 1024x1024 png image and name it icon-alt.png (this is your alternative icon)
  • create a 2732x2732 png named launch.png for your launch screen image

Then run the script alongside these files (check the repository for requirements of the script, i.e. Xcode and imagemagick)

It will generate a series of files in an out directory, in particular the Assets.car should be added to your application at the root level.

Method 2: PNG files

These should follow the native iOS naming conventions, eg the two most common iPhone icons are:

  • IconName@2x.png: 120x120
  • IconName@3x.png: 180x180

(Replace IconName with the name you intend to use for your icon).

These assets should be added to your AIR application package and included at the root level.

Info plist Changes

This stage involves extracting the Info.plist file from your IPA and adding the references to the alternate icons.

Before starting this we suggest you have completed any changes to your application descriptor's InfoAdditions and Entitlements nodes and ensured you have setup all your primary icons.

These settings affect the Info.plist file created. If the Info.plist changes on subsequent builds you will need to extract the file and modify it again.

Firstly package your application as normal and locate the IPA built. Unzip the IPA (you may need to change the extension to .zip depending on your process).

Make sure you are using the correct build, debug/production, i.e if you are going to be debugging the IPA make sure you use the IPA produced from a debug process.

Once you have extracted the IPA, locate the Info.plist file:

Payload/APPNAME.app/Info.plist

Copy this file to be alongside the resign script (or to a location you specify in the script).

Open the copied file in a text editor and locate the CFBundleIcons node. It should resemble the below:

<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon-Ipad-152.png</string>
<string>Icon-Iphone-120.png</string>
<string>Icon@2x.png</string>
<string>Icon-Ipad-76.png</string>
<string>Icon-Large.png</string>
<string>Icon.png</string>
<string>Icon-Small-50.png</string>
<string>Icon-Small.png</string>
</array>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</dict>

Next we need to modify this section, however it is slightly different depending on the method you are using to package your assets.

Method 1: Asset Catalogue

We need to add the CFBundleAlternateIcons node to this dictionary, replacing the AlternateIcon references below with the name of your alternate icon in the asset catalogue:

<key>CFBundleAlternateIcons</key>
<dict>
<key>AlternateIcon</key>
<dict>
<key>CFBundleIconName</key>
<string>AlternateIcon</string>
</dict>
</dict>
note

If you used the default AIR image script then you shouldn't need to change the AlternateIcon reference.

The final section should resemble the below:

<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AlternateIcon</key>
<dict>
<key>CFBundleIconName</key>
<string>AlternateIcon</string>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon-Ipad-152.png</string>
<string>Icon-Iphone-120.png</string>
<string>Icon@2x.png</string>
<string>Icon-Ipad-76.png</string>
<string>Icon-Large.png</string>
<string>Icon.png</string>
<string>Icon-Small-50.png</string>
<string>Icon-Small.png</string>
</array>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</dict>

Save these changes to the Info.plist file.

Method 2: PNG files

We need to add the CFBundleAlternateIcons node to this dictionary, replacing the IconName references below with the name of your alternate icon:

<key>CFBundleAlternateIcons</key>
<dict>
<key>IconName</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>IconName</string>
</array>
</dict>
</dict>

The final section should resemble the below:

<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AlternateIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AlternateIcon</string>
</array>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon-Ipad-152.png</string>
<string>Icon-Iphone-120.png</string>
<string>Icon@2x.png</string>
<string>Icon-Ipad-76.png</string>
<string>Icon-Large.png</string>
<string>Icon.png</string>
<string>Icon-Small-50.png</string>
<string>Icon-Small.png</string>
</array>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</dict>

Save these changes to the Info.plist file.

- + \ No newline at end of file diff --git a/docs/dynamicicon/change-icon/index.html b/docs/dynamicicon/change-icon/index.html index da62b507235..4fbf40f1453 100644 --- a/docs/dynamicicon/change-icon/index.html +++ b/docs/dynamicicon/change-icon/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Change Icon

To change the application icon use the setAlternateIconName() function and pass the name of the icon you wish to use.

For example, if you added an icon named "AlternateIcon" to your application, you change it using:

DynamicIcon.instance.setAlternateIconName( "AlternateIcon" );

To reset the icon to the primary icon, pass either an empty string or null to this function:

DynamicIcon.instance.setAlternateIconName( null );

Example images:

PrimaryConfirmationAlternate

Listen for Result

You can listen to two events to confirm the icon was changed after a call to setAlternateIconName()

  • DynamicIconEvent.SETALTERNATEICON_SUCCESS: Dispatched if the icon was successfully changed;
  • DynamicIconEvent.SETALTERNATEICON_FAILED: Dispatched if there was an error changing the icon, check the error property on the event for more information;

For example:

DynamicIcon.instance.addEventListener( DynamicIconEvent.SETALTERNATEICON_SUCCESS, successHandler );
DynamicIcon.instance.addEventListener( DynamicIconEvent.SETALTERNATEICON_FAILED, failedHandler );

function setAlternateIcon_successHandler( event:DynamicIconEvent ):void
{
trace( "Icon change success" );
}

function setAlternateIcon_failedHandler( event:DynamicIconEvent ):void
{
trace( "Icon change error: " + event.error );
}

The most common error is a missing icon file: "The file doesn't exist". This is caused because the icon wasn't correctly added to your application when repackaging.

You should expect this error if you are debugging / packaging directly from AIR.

Checking for Support

You can directly check whether the device supports changing the icon by checking the supportsAlternateIcons flag:

if (DynamicIcon.instance.supportsAlternateIcons)
{
// Device supports changing icons
}
- + \ No newline at end of file diff --git a/docs/dynamicicon/changelog/index.html b/docs/dynamicicon/changelog/index.html index 040ac6bed33..c0cc6a27aba 100644 --- a/docs/dynamicicon/changelog/index.html +++ b/docs/dynamicicon/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.18 [v1.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2022.08.04 [v1.0.29]

feat(docs,build): updated docs to use asset catalogue with xcode 13 tools
feat(docs): deprecated wiki

2022.02.05 [v1.0.28]

Add air package
Update docs to use apm

2022.02.05 [v1.0.28]

Add air package
Update docs to use apm

2021.12.16 [v1.0.27]

Update docs and latest build

2020.03.22 [v1.0.026]

Android X migration (resolves #1)

2020.01.13 [v0.0.021]

Updated docs

2020.01.13 [v0.0.020]

Initial release
- + \ No newline at end of file diff --git a/docs/dynamicicon/index.html b/docs/dynamicicon/index.html index 029ea6e118a..51e63266357 100644 --- a/docs/dynamicicon/index.html +++ b/docs/dynamicicon/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

DynamicIcon

The DynamicIcon extension gives you the ability to change the application icon displayed for your application.

Features:

  • Change the icon of your application programmatically
  • Single API interface - your code works across supported platforms with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

if (DynamicIcon.instance.supportsAlternateIcons)
{
DynamicIcon.instance.setAlternateIconName( "AlternateIcon" );
}

More information here:

com.distriqt.DynamicIcon

Native Extensions

The highest quality and widest range of Native Extensions for Adobe AIR

With many native extensions available, we are the largest provider of native extensions for AIR developers. Our mobile solutions allow developers to fast-forward development and focus on building great games and apps.

airnativeextensions.com

- + \ No newline at end of file diff --git a/docs/dynamicicon/packaging/index.html b/docs/dynamicicon/packaging/index.html index 14de9652989..da16a6fbf47 100644 --- a/docs/dynamicicon/packaging/index.html +++ b/docs/dynamicicon/packaging/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Packaging

In order to change the contents of your IPA after packaging, we need to extract the IPA, change the contents (in particular the Info.plist file) and then importantly package and sign the IPA again.

If we don't correctly resign the application then it will be rejected by the AppStore (or when installing a debug IPA).

The resign script provided is designed to handle this process, (including extracting your IPA, updating the Info.plist and resigning the application).

IMPORTANT: This script must be run on a macOS machine with Xcode installed and your signing certificate(s) installed into Keychain

Firstly, open the resign script. You will need to update the configuration parameters at the top of the script.

  • IPA: The full path to your application
  • PROVISIONING_PROFILE: The full path to your mobile provisioning profile
  • SIGNING_IDENTITY: The name of the signing identity

Optional:

  • INFO_PLIST: The full path to your Info.plist if you don't place it alongside the script

The paths should be fairly self explanitory. However you get the signing identity string by running the following in a terminal and selecting the name of the appropriate certificate:

security find-identity -v -p codesigning

IMPORTANT: You must ensure you are using the correct mobile provisioning profile and certificate. If you are testing a debug build make sure you are using a developer profile and certificate, and if you are publishing a release make sure you are using the distribution profile and certificate.

Once you have made these changes, run the script in a terminal:

./resign

This will produce an IPA alongside the script named: APPNAME_resigned.ipa

You can then use the IPA produced by the script to either upload to the app store or install on a device for debugging.

resign

The below is the current resign script. You will find this script in the repository as well.

#!/bin/bash

#####################################
## CONFIG

# You need to set the values below for your application
# We suggest they are full paths to the files.

# The path to the ipa generated from your AIR application packaging
IPA="/path/to/yourApp.ipa"

# The provisioning profile for your application
PROVISIONING_PROFILE="/path/to/profile.mobileprovision"

# The name of the signing identity. You get this by running the following in a terminal
# and selecting the name of your certificate:
#
# security find-identity -v -p codesigning
SIGNING_IDENTITY="iPhone Distribution: XXXXXXXXX (XXXXX)"

#
INFO_PLIST="./Info.plist"

## END CONFIG
#####################################


OUTPUT=.
WORKING_DIR=.tmp
WORKING_PROFILE="profile.mobileprovision"
IPA_NAME=$(basename ${IPA%.*})

cp -f "$PROVISIONING_PROFILE" "$WORKING_PROFILE"

rm -rf "$WORKING_DIR"
unzip -qq -o $IPA -d $WORKING_DIR
find . -iname '$WORKING_DIR/*.DS_Store' -delete

rm -rf "$WORKING_DIR/Payload/$APP_NAME/_CodeSignature/"
rm -f "$WORKING_DIR/Payload/$APP_NAME/embedded.mobileprovision"

APP_NAME=$(ls -1 $WORKING_DIR/Payload)

cp $INFO_PLIST "$WORKING_DIR/Payload/$APP_NAME/Info.plist"

#####################################
echo "Create Signing Entitlements"
ENTITLEMENTS="$OUTPUT/Entitlements.plist"
rm -f "$ENTITLEMENTS"
WORKING_PROFILE_PLIST="$OUTPUT/$WORKING_PROFILE.plist"
security cms -D -i "$WORKING_PROFILE" > "$WORKING_PROFILE_PLIST"


TEAM_IDENTIFIER=$(/usr/libexec/Plistbuddy -c "Print :TeamIdentifier:0" "$WORKING_PROFILE_PLIST")
APPLICATION_IDENTIFIER_PREFIX=$(/usr/libexec/Plistbuddy -c "Print :ApplicationIdentifierPrefix:0" "$WORKING_PROFILE_PLIST")
BUNDLE_IDENTIFIER=$(/usr/libexec/Plistbuddy -c "Print :CFBundleIdentifier" "$WORKING_DIR/Payload/$APP_NAME/Info.plist")
APS_ENVIRONMENT=$(/usr/libexec/Plistbuddy -c "Print Entitlements:aps-environment" "$WORKING_PROFILE_PLIST")
BETA_REPORTS=$(/usr/libexec/Plistbuddy -c "Print Entitlements:beta-reports-active" "$WORKING_PROFILE_PLIST")
PROVISIONING_GET_TASK_ALLOW=$(/usr/libexec/Plistbuddy -c "Print :Entitlements:get-task-allow" "$WORKING_PROFILE_PLIST")

echo " APP_NAME = $APP_NAME"
echo " TEAM_IDENTIFIER = $TEAM_IDENTIFIER"
echo " APPLICATION_IDENTIFIER_PREFIX = $APPLICATION_IDENTIFIER_PREFIX"
echo " BUNDLE_IDENTIFIER = $BUNDLE_IDENTIFIER"
echo " APS_ENVIRONMENT = $APS_ENVIRONMENT"
echo " BETA_REPORTS = $BETA_REPORTS"
echo " PROVISIONING_GET_TASK_ALLOW = $PROVISIONING_GET_TASK_ALLOW"


/usr/libexec/PlistBuddy -c "Add :application-identifier string $APPLICATION_IDENTIFIER_PREFIX.$BUNDLE_IDENTIFIER" "$ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Add :get-task-allow bool $PROVISIONING_GET_TASK_ALLOW" "$ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Add :keychain-access-groups array" "$ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Add :keychain-access-groups:0 string $APPLICATION_IDENTIFIER_PREFIX.$BUNDLE_IDENTIFIER" "$ENTITLEMENTS"
if [ $APS_ENVIRONMENT ]; then
echo "Setting aps-environment=$APS_ENVIRONMENT"
/usr/libexec/PlistBuddy -c "Add :aps-environment string $APS_ENVIRONMENT" "$ENTITLEMENTS"
fi
if [ $BETA_REPORTS ]; then
echo "Setting beta-reports-active=$BETA_REPORTS"
/usr/libexec/PlistBuddy -c "Add :beta-reports-active bool $BETA_REPORTS" "$ENTITLEMENTS"
fi

# Uncomment these lines if you are using AppleSignIn
#/usr/libexec/PlistBuddy -c "Add :com.apple.developer.applesignin array" "$ENTITLEMENTS"
#/usr/libexec/PlistBuddy -c "Add :com.apple.developer.applesignin:0 string Default" "$ENTITLEMENTS"


#####################################
echo "Sign Frameworks"

find $WORKING_DIR/Payload/$APP_NAME/Frameworks/ -name "*.framework" -exec codesign --force --sign "$SIGNING_IDENTITY" --generate-entitlement-der {} \;


#####################################
echo "Sign Application"
codesign --force --entitlements "$ENTITLEMENTS" --sign "$SIGNING_IDENTITY" "$WORKING_DIR/Payload/$APP_NAME" --verbose

#codesign --verify --verbose --deep --no-strict "$WORKING_DIR/Payload/$APP_NAME"


OUTPUT_IPA="$OUTPUT/"$IPA_NAME"_resigned.ipa"
cd $WORKING_DIR
zip -q --symlinks --recurse-paths "../.tmp_output.ipa" .
cd ..
mv ".tmp_output.ipa" "$OUTPUT_IPA"


# Cleanup
rm -Rf "$WORKING_DIR"
rm -f "$ENTITLEMENTS"
rm -f "$WORKING_PROFILE_PLIST"
rm -f "$WORKING_PROFILE"

# ideviceinstaller -i "$OUTPUT_IPA"
- + \ No newline at end of file diff --git a/docs/epos/add-the-extension/index.html b/docs/epos/add-the-extension/index.html index 19a0bf2ac1a..35a1f38baa3 100644 --- a/docs/epos/add-the-extension/index.html +++ b/docs/epos/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.epson.epos

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.epson.epos.ane # Epos extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set the configuration values for usage in the extension. Call the following to step through the configuration values for this extension:
apm project config set com.distriqt.Epos

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Epos.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/epos/changelog/index.html b/docs/epos/changelog/index.html index e461982387d..b711e98051c 100644 --- a/docs/epos/changelog/index.html +++ b/docs/epos/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.05.22 [v1.1.0]

fix(scripts): correct repo location

2023.05.22 [v1.1.0]

feat(android,ios): add pulse functionality to kick drawer (addPulse, forcePulse)

2023.05.20 [v1.0.2]

Initial release
- + \ No newline at end of file diff --git a/docs/epos/index.html b/docs/epos/index.html index e91b1c6aaaa..c2fc6df0cb3 100644 --- a/docs/epos/index.html +++ b/docs/epos/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Epos

The Epos extension gives you access to Epson's Epos SDK for interacting with printers.

We provide complete guides to get you up and running with sharing quickly and easily.

Features

  • Access to the Epos SDK
  • Single API interface - your code works across iOS and Android with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

AIR

More information here:

com.epson.epos

License

You can purchase a license for using this extension:

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/epos/initialisation/index.html b/docs/epos/initialisation/index.html index e06abac1bd3..6fb59a77855 100644 --- a/docs/epos/initialisation/index.html +++ b/docs/epos/initialisation/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Initialisation

In order to access a printer you must first initialise an EposPrinter instance via the initPrinterWithOptions() method.

This method takes an instance of the EposPrinterOptions class as a parameter which specified the printer series and language.

var printer:EposPrinter = 
Epos.instance.initPrinterWithOptions(
new EposPrinterOptions()
.setPrinterSeries( EposPrinterOptions.TM_T88VII )
.setLang( EposPrinterOptions.MODEL_ANK )
);

The EposPrinter instance will now form your main access to the printer.

Connecting

You will next need to connect to the printer by specifying a target for the EposPrinter instance:

printer.connect( "TCP:192.168.1.209", EposFlags.PARAM_DEFAULT );

The first parameter is the target string and it specifies the method of connecting to the printer. The connection method varies according to the system configuration.

  • TM Printer Models: <connection type>:<identifier>
I/FConnection typeIdentifierExample
Wi-Fi/Ethernet"TCP"IP address in IPv4 format, MAC address or Printer host name"TCP:192.168.192.168"
Bluetooth"BT"BD address"BT:00:22:15:7D:70:9C"
USB"USB"USB Serial number, Omitted"USB:000000000000000000" "USB:"
Bluetooth Low Energy"BLE"Bluetooth Low Energy BD address"BLE:00:22:15:7D:70:9C"

For further variations and explanation refer to the Epos documentation

- + \ No newline at end of file diff --git a/docs/epos/printing/index.html b/docs/epos/printing/index.html index 79ab769b98b..7fc0eac0719 100644 --- a/docs/epos/printing/index.html +++ b/docs/epos/printing/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Printing

Once you have created your EposPrinter instance and initiated a connection you can print to the connected device by using a series of commands.

Image

To send an image to the printer use the addImage() method. This method adds a raster image print command to the command buffer. You will need to load your image into a BitmapData instance and pass this (along with any options) to the addImage() method.

var image:BitmapData = (new EmbeddedImage() as Bitmap).bitmapData;

printer.addImage( image );

You can also specify some options for the image if required:

var options:ImageOptions = new ImageOptions();
options.x = 10;
options.y = 10;

printer.addImage( image, options );

The image should contain a single pixel for each dot on the printer. We have found a 500 pixel wide image works well with the TM_T88VII printer.

Cutting

To trigger a cut of the paper, call the addCut() method and pass the cut type. The cut types are defined by the constants in the EposCut class.

printer.addCut( EposCut.CUT_FEED );

Print

Once you have assembled your commands, call the sendData() method to send your print commands to the printer. Calling this method will start the print process.

printer.sendData();

Clear Command Buffer

Once you have completed your print you should clear the command buffer by calling clearCommandBuffer(). This will ensure the command buffer is empty before any further prints are done.

printer.clearCommandBuffer();

Example

The following example prints an image and cuts the paper.

var image:BitmapData = (new EmbeddedImage() as Bitmap).bitmapData;

printer.addImage( image );
printer.addCut( EposCut.CUT_FEED );
printer.sendData();
printer.clearCommandBuffer();
- + \ No newline at end of file diff --git a/docs/exceptions/add-the-extension/index.html b/docs/exceptions/add-the-extension/index.html index 58919821e41..47879f23b57 100644 --- a/docs/exceptions/add-the-extension/index.html +++ b/docs/exceptions/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.Exceptions

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.Exceptions.ane # Exceptions extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Exceptions.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/exceptions/changelog/index.html b/docs/exceptions/changelog/index.html index a30e42f9b23..cdcba375f15 100644 --- a/docs/exceptions/changelog/index.html +++ b/docs/exceptions/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.18 [v3.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

2021.12.06 [v3.0.8]

Add airpackage

2021.03.12 [v3.0.007]

Updated to latest build process  
Added Android-x64 support

2020.03.25 [v3.0.005]

Android X migration (resolves #13)

2019.08.15 [v2.0.002]

Android 64bit support (resolves #12)
Updated minimum iOS version to 9.0

2018.11.18 [v1.1.016]

Added ability to write crash report to file (resolves #10)

2016.11.02

iOS: Added checking of crash report details before returning to AS (#3)

2016.10.13

Initial Release
- + \ No newline at end of file diff --git a/docs/exceptions/index.html b/docs/exceptions/index.html index a9a1d201f8d..3bd5e2f9d19 100644 --- a/docs/exceptions/index.html +++ b/docs/exceptions/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Exceptions

Exceptions

Exceptions is an AIR Native Extension to enable a global exception handler for iOS and Android.

This will catch and store information about crashes of your application allowing you to process them on the next application run. In using this extension you can report crashes and errors in your application to your own error logging server.

Features

  • Catch exceptions
  • Process exceptions on startup
  • Single API interface - your code works across supported platforms with no modifications
  • Sample project code and ASDocs reference

Documentation

Latest documentation can be found in the documentation site along with the asdocs.

Quick Example:

Exceptions.service.setUncaughtExceptionHandler();

Acknowledgements

This extension was made possible with support by MovieStarPlanet

MovieStarPlanet

- + \ No newline at end of file diff --git a/docs/exceptions/usage/index.html b/docs/exceptions/usage/index.html index a08a6f579e9..5752c42362a 100644 --- a/docs/exceptions/usage/index.html +++ b/docs/exceptions/usage/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Usage

This extension is very simple in the implementation, having only 2 main functions.

To start catching exceptions you simply call setUncaughtExceptionHandler() at some point at the beginning of your application.

Exceptions.service.setUncaughtExceptionHandler();

To check if your application crashed previously you use the hasPendingException() function.

if (Exceptions.service.hasPendingException())
{
var report:ExceptionReport = Exceptions.service.getPendingException();
trace( "date: "+ new Date(report.timestamp).toLocaleString() );
trace( "name: "+ report.name );
trace( "reason: "+ report.reason );
trace( "report: "+ report.report );
}
note

You can generally only have one exception handler in an application.

So if you are using another library that tracks exceptions (Google Analytics or a bug tracker) then the functionality provided here may not work or may stop the library from working.

You should decide which is the more important method and ensure only one method is used in your application.

- + \ No newline at end of file diff --git a/docs/expansionfiles/add-the-extension/index.html b/docs/expansionfiles/add-the-extension/index.html index ca0220ffe2d..297a32cadfb 100644 --- a/docs/expansionfiles/add-the-extension/index.html +++ b/docs/expansionfiles/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ will avoid conflicts, allowing you to use multiple ANEs in the one application.

This ANE requires the following Google Play Services:

You must include the above native extensions in your application along with this extension, and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ExpansionFiles.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/expansionfiles/changelog/index.html b/docs/expansionfiles/changelog/index.html index 205092c7937..7d6b1b56466 100644 --- a/docs/expansionfiles/changelog/index.html +++ b/docs/expansionfiles/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.04.26 [v4.2.1]

fix(docs): remove incorrectly included bluetooth documentation (resolves #37)
feature: update to latest build process

2023.01.18 [v4.2.0]

NOTE THIS EXTENSION IS DEPRECATED IN FAVOUR OF PLAY ASSET DELIVERY

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag
feat(android): Move to new permissions request process

2022.02.05 [v4.1.16]

Update for Android 31
Update docs to use apm

2021.10.05 [v4.1.15]

Add air package

2020.03.22 [v4.0.010]

Android X migration (resolves #27)

2019.08.16 [v3.0.006]

Android 64bit support (resolves #24)
Updated minimum iOS version to 9.0

2018.07.18 [v2.3.025]

Updated for recent Android changes (resolves #22)

2018.04.20 [v2.2.013]

Corrected setDownloadFlags functionality to enable download over cellular (#21)

2017.12.22 [v2.2.008]

Updated documentation on progress info fields (resolves #18)
Added documentation on extension ids (resolves #17)

2017.08.25 [v2.2.006]

Removed debugging traces

2017.07.10 [v2.2.003]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.02.01 [v2.2.002]

Added authorisation requests for v6.0+ (resolves #9)

2017.01.19 [v2.1.010]

Will now re-download if filesize is incorrect

2016.12.28 [v2.1.008]

Updated to latest SDK + documentation

v2.0 2016.07.31

Added mounting of OBB files (resolves #5)

2015.11.10

Android: Fix for 'Service Intent must be explicit' (resolves #1)

2015.09.07

First release
- + \ No newline at end of file diff --git a/docs/expansionfiles/downloading-expansion-files/index.html b/docs/expansionfiles/downloading-expansion-files/index.html index caac0e30170..eb1b10bd3bd 100644 --- a/docs/expansionfiles/downloading-expansion-files/index.html +++ b/docs/expansionfiles/downloading-expansion-files/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ to the Play Store. If you don't then this will always return false and may incorrectly download your file on every launch.

The following example shows the major events in this process and the suggested method of checking for the existence of expansion files.

public static const BASE64_PUBLIC_KEY   : String = "YOUR_LICENSING_PUBLIC_KEY";
public static const SALT : Vector.<int> = Vector.<int>( [ 1, 43, -12, -1, 54, 98, -100, -12, 43, 2, -8, -4, 9, 5, -106, -108, -33, 45, -1, 84 ]);
ExpansionFiles.service.setup( BASE64_PUBLIC_KEY, SALT );

ExpansionFiles.service.addEventListener( ExpansionFilesEvent.CONNECTED, connectedHandler );
ExpansionFiles.service.addEventListener( ExpansionFilesEvent.STATE_CHANGED, stateChangedHandler );
ExpansionFiles.service.addEventListener( ProgressEvent.PROGRESS, progressHandler );
ExpansionFiles.service.addEventListener( ExpansionFilesEvent.COMPLETE, completeHandler );

// Add the details of your expansion file(s)
var expansionFile:ExpansionFile = new ExpansionFile( ExpansionFile.MAIN, 1001002, 233017 );
ExpansionFiles.service.addExpansionFile( expansionFile );

// Check if the files have been delivered / downloaded already
if (!ExpansionFiles.service.expansionFilesDelivered())
{
// Start the downloading
ExpansionFiles.service.download();
}
else
{
// Already have expansion files - use as required
}
private function connectedHandler( event:ExpansionFilesEvent ):void
{
trace( "connectedHandler()" );
}

private function stateChangedHandler( event:ExpansionFilesEvent ):void
{
trace( "stateChangedHandler(): " + event.state );
}

private function completeHandler( event:ExpansionFilesEvent ):void
{
trace( "completeHandler()" );
// Read your expansion files
}

private function progressHandler( event:ProgressEvent ):void
{
trace( "progressHandler( " + event.progress.toString() + " )" );
}
- + \ No newline at end of file diff --git a/docs/expansionfiles/index.html b/docs/expansionfiles/index.html index 9dfab8f9546..9e33bb184e0 100644 --- a/docs/expansionfiles/index.html +++ b/docs/expansionfiles/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ just a few lines of code. We provide complete guides and asdocs to get you up and running with expansion files quickly and easily.

We provide complete guides to get you up and running with expansion files quickly and easily.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.ExpansionFiles

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/expansionfiles/jobb-files/index.html b/docs/expansionfiles/jobb-files/index.html index c94bb86a452..15af07170da 100644 --- a/docs/expansionfiles/jobb-files/index.html +++ b/docs/expansionfiles/jobb-files/index.html @@ -13,7 +13,7 @@ - + @@ -37,7 +37,7 @@ your OBB file later you will need to pass this same key to the mount function.

jobb -d assets -o main.1001003.air.com.distriqt.test.obb -k secretKey -pn air.com.distriqt.test -pv 1001003

Further information can be found in the JOBB tool documentation:

Tip: If when using the JOBB tool you are getting an "java.io.IOException: FAT Full" error, then try adding more files into your folder. It seems the tool can have issue with a small amount of data.

- + \ No newline at end of file diff --git a/docs/expansionfiles/migrating-to-androidx/index.html b/docs/expansionfiles/migrating-to-androidx/index.html index fef6662cafb..994fd618eaf 100644 --- a/docs/expansionfiles/migrating-to-androidx/index.html +++ b/docs/expansionfiles/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/expansionfiles/migrating-to-v4.2/index.html b/docs/expansionfiles/migrating-to-v4.2/index.html index 1ba57701ff9..0cad54d305e 100644 --- a/docs/expansionfiles/migrating-to-v4.2/index.html +++ b/docs/expansionfiles/migrating-to-v4.2/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v4.2

This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

The authorisation process remains the same however there is a small change to the manifest.

This update requires the latest version of the Core ANE (v7+).

If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

apm update 
apm generate app-descriptor src/Main-app.xml
- + \ No newline at end of file diff --git a/docs/expansionfiles/mounting-an-obb-file/index.html b/docs/expansionfiles/mounting-an-obb-file/index.html index 9c3ae90d0a7..fed2a7910e6 100644 --- a/docs/expansionfiles/mounting-an-obb-file/index.html +++ b/docs/expansionfiles/mounting-an-obb-file/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ generate the file).

Once the mount process is complete an event will be dispatched indicating the state of the mounted OBB file.

var obbFile:ExpansionFile = new ExpansionFile( ExpansionFile.MAIN, 1001003, 93147195 );

if (ExpansionFiles.service.expansionFilesDelivered())
{
ExpansionFiles.service.obbUtils.addEventListener( OBBUtilsEvent.STATE_CHANGED, obbUtils_stateChangedHandler );
var success:Boolean = ExpansionFiles.service.obbUtils.mount( obbFile );
}
private function obbUtils_stateChangedHandler( event:OBBUtilsEvent ):void
{
trace( event.type + " : "+ ExpansionFiles.service.getFilenameForExpansionFile(event.file) );
if (event.state == OBBState.MOUNTED)
{
trace( "OBB file mounted" );
}
}

Unmounting an OBB File

You can unmount an OBB file if you have finished loading your content into memory and no longer require file access. This is a simple call to unmount

var obbFile:ExpansionFile = new ExpansionFile( ExpansionFile.MAIN, 1001003, 93147195 );

if (ExpansionFiles.service.obbUtils.isMounted( obbFile ))
{
ExpansionFiles.service.obbUtils.unmount( obbFile );
}
- + \ No newline at end of file diff --git a/docs/expansionfiles/reading-an-obb-file/index.html b/docs/expansionfiles/reading-an-obb-file/index.html index 53a49e0e636..7bb23dc1c31 100644 --- a/docs/expansionfiles/reading-an-obb-file/index.html +++ b/docs/expansionfiles/reading-an-obb-file/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ passed to the JOBB tool. You can then reference the content in this directory with normal File objects. In the following example we access a file we placed in an images directory call image.jpg

var obbFile:ExpansionFile = new ExpansionFile( ExpansionFile.MAIN, 1001003, 93147195 );

if (ExpansionFiles.service.obbUtils.isMounted( obbFile ))
{
var path:String = ExpansionFiles.service.obbUtils.getMountedPath( obbFile );
var file:File = new File( path + "/images/image.jpg" );

// You can use normal file operations
trace( file.url );
trace( "exists="+file.exists );
trace( "size="+file.size );

var loader:Loader = new Loader();
loader.load( new URLRequest( file.url ) );
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, loader_completeHandler );
}
private function loader_completeHandler(event:flash.events.Event):void
{
var bitmap:Bitmap = event.currentTarget.loader.content as Bitmap;
// Use your bitmap as required
}
- + \ No newline at end of file diff --git a/docs/expansionfiles/request-authorisation/index.html b/docs/expansionfiles/request-authorisation/index.html index 20325895212..59ba1ca8f75 100644 --- a/docs/expansionfiles/request-authorisation/index.html +++ b/docs/expansionfiles/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ that you request the permissions similar to iOS. You will still need to list them in your manifest and then follow the same code below.

You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

switch (ExpansionFiles.service.authorisationStatus())
{
case AuthorisationStatus.AUTHORISED:
// This device has been authorised.
break;

case AuthorisationStatus.NOT_DETERMINED:
case AuthorisationStatus.SHOULD_EXPLAIN:
// You are yet to ask for authorisation
// At this point you should consider your strategy to get your
// user to authorise by explaining your need for the permissions
ExpansionFiles.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
ExpansionFiles.service.requestAuthorisation();
break;

case AuthorisationStatus.DENIED:
case AuthorisationStatus.UNKNOWN:
case AuthorisationStatus.RESTRICTED:
// The user has disabled the permissions
// Advise your user of the lack of permissions as you see fit
break;
}

You will then receive a change event if the user accepted your permission request:

private function authorisationChangedHandler( event:AuthorisationEvent ):void
{
// Check the authorisation state again (as above)
}
- + \ No newline at end of file diff --git a/docs/expansionfiles/setup-licensing/index.html b/docs/expansionfiles/setup-licensing/index.html index f01b9b3a081..7c2773d7eb0 100644 --- a/docs/expansionfiles/setup-licensing/index.html +++ b/docs/expansionfiles/setup-licensing/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ the data as it is written to or read from storage. The salt should be an array of 20 randomly generated integer values.

The two values (base64 public license key and your salt values) should be passed to the setup function as in the following example.

public static const BASE64_PUBLIC_KEY   : String = "YOUR_LICENSING_PUBLIC_KEY";
public static const SALT : Vector.<int> = Vector.<int>( [ 1, 43, -12, -1, 54, 98, -100, -12, 43, 2, -8, -4, 9, 5, -106, -108, -33, 45, -1, 84 ]);
ExpansionFiles.init( "APP_KEY" );

trace( "ExpansionFiles Supported: " + ExpansionFiles.isSupported );
trace( "ExpansionFiles Version: " + ExpansionFiles.service.version );

if (ExpansionFiles.isSupported)
{
ExpansionFiles.service.setup( BASE64_PUBLIC_KEY, SALT );
}
- + \ No newline at end of file diff --git a/docs/expansionfiles/uploading-expansion-files/index.html b/docs/expansionfiles/uploading-expansion-files/index.html index 82d8d0356ed..9c38dc5ba02 100644 --- a/docs/expansionfiles/uploading-expansion-files/index.html +++ b/docs/expansionfiles/uploading-expansion-files/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ access the files directly. See later for more information on creating OBB files using the JOBB tool.

You upload this file alongside an APK update. You must take note of the type (main / patch), version and the files byte size to use in the next step.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/account-kit---add-the-extension/index.html b/docs/facebookapi-legacy/account-kit---add-the-extension/index.html index 7172ff16f2c..6c94b47c18a 100644 --- a/docs/facebookapi-legacy/account-kit---add-the-extension/index.html +++ b/docs/facebookapi-legacy/account-kit---add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Account Kit - Add the Extension

caution

This is the legacy extension documentation. Find the new documentation here

Account Kit has been discontinued and has been removed

Account Kit was deprecated on March 9, 2020. For more information, see Account Kit services no longer available starting in March.

Android Manifest Additions

If you are using Account Kit then you will need to add some additional information here, including

  • meta-data tags
  • activities

You will need to replace [YOUR_FACEBOOK_APP_NAME], [YOUR_ACCOUNT_KIT_CLIENT_TOKEN]and [YOUR_FACEBOOK_APP_ID] in the below with the relevant details for your application.

<meta-data android:name="com.facebook.accountkit.ApplicationName" android:value="[YOUR_FACEBOOK_APP_NAME]" />
<meta-data android:name="com.facebook.accountkit.ClientToken" android:value="[YOUR_ACCOUNT_KIT_CLIENT_TOKEN]" />

<activity android:name="com.facebook.accountkit.ui.AccountKitActivity" android:theme="@style/AppLoginTheme" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize" />

<activity android:name="com.facebook.accountkit.ui.AccountKitEmailRedirectActivity" android:exported="true" android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ak[YOUR_FACEBOOK_APP_ID]" />
</intent-filter>
</activity>

These should be added within the application node.

Phone Permissions

Facebook recommends requesting the following permissions for SMS:

  • RECEIVE_SMS - auto-fill SMS confirmation code
  • READ_PHONE_STATE - auto-read device's phone number

Auto-fill confirmation code from received SMS

If people grant the RECEIVE_SMS permission, the Account Kit SDK automatically fills in the confirmation code sent to the device. People still need to manually submit the code to continue the login process.

Add the following permission to your manifest additions to allow the SDK to auto-fill the confirmation code from the SMS:

<uses-permission android:name="android.permission.RECEIVE_SMS" />

Read Phone Number on Device

If people grant the READ_PHONE_STATE permission, the SDK can automatically fill in the device’s phone number. People still need to manually submit their phone number to continue the login process

Add the following permission to your manifest additions to allow the SDK to auto-fill the device's phone number:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Email Permissions

Facebook recommends requesting the following permissions:

  • GET_ACCOUNTS - provide drop-down list of device emails

Certain features of the Account Kit SDK are only available when specific Android Permissions are granted to your app. If people grant the GET_ACCOUNTS permission, the SDK allows them to select the emails available on the device.

Add the following permission to your manifest additions to allow the SDK to populate a drop-down of emails:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

iOS Info Additions

If you are using Account Kit then you will need to add some additional information added to the Info Additions on top of the base Facebook API additions:

  • An additional url scheme with the ak prefix
  • The AccountKitClientToken key from your Account Kit configuration

Your info additions should end up looking like the following:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<!-- Don't remove the 'fb' prefix -->
<string>fb[YOUR_FACEBOOK_APP_ID]</string>
<!-- Account Kit Addition -->
<string>ak[YOUR_FACEBOOK_APP_ID]</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>[YOUR_FACEBOOK_APP_ID]</string>
<key>FacebookDisplayName</key>
<string>[YOUR_FACEBOOK_APP_NAME]</string>
<key>AccountKitClientToken</key>
<string>[YOUR_ACCOUNT_KIT_CLIENT_TOKEN]</string>
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/account-kit---deprecation/index.html b/docs/facebookapi-legacy/account-kit---deprecation/index.html index 5333d8851c3..ac6a9c8103d 100644 --- a/docs/facebookapi-legacy/account-kit---deprecation/index.html +++ b/docs/facebookapi-legacy/account-kit---deprecation/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Account Kit - Deprecation

caution

This is the legacy extension documentation. Find the new documentation here

Account Kit has been discontinued and has been removed

Account Kit was deprecated on March 9, 2020. For more information, see Account Kit services no longer available starting in March.

Android

You will need to remove any references you may have in your manifest additions to the account kit activities etc:

i.e. Remove these:

<meta-data android:name="com.facebook.accountkit.ApplicationName" android:value="[YOUR_FACEBOOK_APP_NAME]" />
<meta-data android:name="com.facebook.accountkit.ClientToken" android:value="[YOUR_ACCOUNT_KIT_CLIENT_TOKEN]" />

<activity android:name="com.facebook.accountkit.ui.AccountKitActivity" android:theme="@style/AppLoginTheme" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize" />

<activity android:name="com.facebook.accountkit.ui.AccountKitEmailRedirectActivity" android:exported="true" android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ak[YOUR_FACEBOOK_APP_ID]" />
</intent-filter>
</activity>

iOS

You can remove <string>ak[YOUR_FACEBOOK_APP_ID]</string> from the CFBundleURLSchemes in your Info Additions and also remove the AccountKitClientToken key.

Code

If you correctly wrapped your code in the isSupported flag then this will now return false and you shouldn't need to make any changes.

if (FacebookAPI.service.accountKit.isSupported)
{
// Account Kit is available
}

The functions should still all operate however none of the events will fire and you should just expect them to fail silently. We suggest you remove or plan to remove this code from your app in the near future.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/account-kit---overview/index.html b/docs/facebookapi-legacy/account-kit---overview/index.html index c1c877c911e..025de1c9616 100644 --- a/docs/facebookapi-legacy/account-kit---overview/index.html +++ b/docs/facebookapi-legacy/account-kit---overview/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ powered by Facebook's email and SMS sending infrastructure for reliable scalable performance with global reach. Using email and phone number authentication doesn't require a Facebook account, and is the ideal alternative to a social login.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/account-kit---setup/index.html b/docs/facebookapi-legacy/account-kit---setup/index.html index 2674352a2d1..41713842f64 100644 --- a/docs/facebookapi-legacy/account-kit---setup/index.html +++ b/docs/facebookapi-legacy/account-kit---setup/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Account Kit - Setup

caution

This is the legacy extension documentation. Find the new documentation here

Account Kit has been discontinued and has been removed

Account Kit was deprecated on March 9, 2020. For more information, see Account Kit services no longer available starting in March.

Add Account Kit

Click "Add Product" and select the "Account Kit" option.

Enable the services you will allow in your application and take note of the "Account Kit Client Token", you will need this when adding the extension to your applicaiton.

Also at this point you should setup the display options as you require changing the colours of the UI to match your application.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/account-kit---usage/index.html b/docs/facebookapi-legacy/account-kit---usage/index.html index 68f2819bd6f..57b8bcddf2b 100644 --- a/docs/facebookapi-legacy/account-kit---usage/index.html +++ b/docs/facebookapi-legacy/account-kit---usage/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ enabled in your application settings.

Any of the login processes will dispatch one of the following events:

Example:

FacebookAPI.service.accountKit.addEventListener( AccountKitEvent.LOGIN_WITH_AUTHORISATIONCODE, loginAuthorisationCodeHandler );
FacebookAPI.service.accountKit.addEventListener( AccountKitEvent.LOGIN_WITH_ACCESSTOKEN, loginAccessHandler );
FacebookAPI.service.accountKit.addEventListener( AccountKitEvent.CANCELLED, cancelledHandler );
FacebookAPI.service.accountKit.addEventListener( AccountKitEvent.ERROR, errorHandler );
private function loginAuthorisationCodeHandler( event:AccountKitEvent ):void 
{
trace( event.type +"::"+event.authorisationCode );
}

private function loginAccessHandler( event:AccountKitEvent ):void
{
trace( event.type +"::"+event.accessToken.tokenString );
}

private function cancelledHandler( event:AccountKitEvent ):void
{
trace( event.type );
}

private function errorHandler( event:AccountKitEvent ):void
{
trace( event.type +"::["+event.errorCode+"] "+event.errorMessage );
}

Login with Phone

To login using the user's phone number you call the loginWithPhone function.

FacebookAPI.service.accountKit.loginWithPhone();

You can prefill the phone number entry by specifying the country code and phone number:

FacebookAPI.service.accountKit.loginWithPhone( "+61", "0400000000" );

Login with Email

To login using the user's email address you call the loginWithEmail function:

FacebookAPI.service.accountKit.loginWithEmail();

Again you can prefill this:

FacebookAPI.service.accountKit.loginWithEmail( "test@example.com" );

Account Information

If you have received an access token you can use the getAccountInfo function to query the details the user used to login. This function will dispatch one of the following events:

FacebookAPI.service.accountKit.addEventListener( AccountKitEvent.ACCOUNTINFO, accountInfoHandler );
FacebookAPI.service.accountKit.addEventListener( AccountKitEvent.ACCOUNTINFO_ERROR, accountInfoErrorHandler );

FacebookAPI.service.accountKit.getAccountInfo();
private function accountInfoHandler( event:AccountKitEvent ):void 
{
// event.account will contain the account info
trace( event.type + "::" + event.account.toString() );
}

private function accountInfoErrorHandler( event:AccountKitEvent ):void
{
trace( event.type +"::["+event.errorCode+"] "+event.errorMessage );
}
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/add-the-extension/index.html b/docs/facebookapi-legacy/add-the-extension/index.html index b4fbb4c6187..ff20e50b011 100644 --- a/docs/facebookapi-legacy/add-the-extension/index.html +++ b/docs/facebookapi-legacy/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -39,7 +39,7 @@ under the iPhone node.

You will need to replace the instances of [YOUR_FACEBOOK_APP_ID] and [YOUR_FACEBOOK_APP_NAME] with the relevant settings from your Facebook app. (Don't include the braces).

This is required additions for the InfoAdditions section:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<!-- Don't remove the 'fb' prefix -->
<string>fb[YOUR_FACEBOOK_APP_ID]</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>[YOUR_FACEBOOK_APP_ID]</string>
<key>FacebookDisplayName</key>
<string>[YOUR_FACEBOOK_APP_NAME]</string>

<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>facebook.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
<key>fbcdn.net</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
<key>akamaihd.net</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>

<!-- Required to check availability and communicate with other Facebook applications -->
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fb</string>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>

We also suggest adding the photo usage description string in case you will be sharing photos using the share dialogs

<key>NSPhotoLibraryUsageDescription</key>
<string>Access to photo library is required to save images and videos.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Access to photo library is required to save images and videos.</string>
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/advanced-facebook-settings/index.html b/docs/facebookapi-legacy/advanced-facebook-settings/index.html index 87ba68ca491..dfa35b3ae3d 100644 --- a/docs/facebookapi-legacy/advanced-facebook-settings/index.html +++ b/docs/facebookapi-legacy/advanced-facebook-settings/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Advanced Facebook Settings

caution

This is the legacy extension documentation. Find the new documentation here

Setup: Advanced Facebook Settings

Finally, on the Settings page for your Facebook app, select Advanced in the top menu.

Under App Restrictions, ensure that Native or desktop app is set to YES,

And under Client OAuth Settings, ensure that Client OAuth Login is set to YES.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-events---automatic-logging/index.html b/docs/facebookapi-legacy/app-events---automatic-logging/index.html index d56601a1fa5..e58eb643b3e 100644 --- a/docs/facebookapi-legacy/app-events---automatic-logging/index.html +++ b/docs/facebookapi-legacy/app-events---automatic-logging/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

App Events - Automatic Logging

caution

This is the legacy extension documentation. Find the new documentation here

Automatically Logged Events

When you use the Facebook SDK, certain events in your app are automatically logged and collected for Facebook Analytics unless you disable automatic event logging. These events are relevant for all use cases - targeting, measurement and optimization.

Disable Automatically Logged Events

To disable automatic logging you must add certain fields to the manifest and info additions in your application descriptor.

For Android add the following line to your manifest additions:

<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
android:value="false"/>

This must be added inside the application node of your manifest additions.

For iOS add the following to your info additions:

<key>FacebookAutoLogAppEventsEnabled</key>
<false/>

In some cases, you want to only delay the collection of automatically logged events, such as to obtain User consent or fulfill legal obligations. In this case disable the automatic logging as above and then once you have been provided consent call the setAutoLogAppEventsEnabled function:

FacebookAPI.service.appEvents.setAutoLogAppEventsEnabled( true );

Similarly to suspend collection again for any reasons:

FacebookAPI.service.appEvents.setAutoLogAppEventsEnabled( false );

Disable Collection of Advertiser IDs

To disable collection of the advertiser id, you must add certain fields to the manifest and info additions in your application descriptor.

For Android add the following line to your manifest additions:

<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled"
android:value="false"/>

This must be added inside the application node of your manifest additions.

For iOS add the following to your info additions:

<key>FacebookAdvertiserIDCollectionEnabled</key>
<false/>

In some cases, you want to delay the collection of the advertiser id, such as to obtain User consent or fulfill legal obligations, instead of disabling it. In this case disable the collection of the advertiser id as above and then once you have been provided consent call the setAdvertiserIDCollectionEnabled function:

FacebookAPI.service.appEvents.setAdvertiserIDCollectionEnabled( true );

Similarly to suspend collection again for any reasons:

FacebookAPI.service.appEvents.setAdvertiserIDCollectionEnabled( false );
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-events---logging/index.html b/docs/facebookapi-legacy/app-events---logging/index.html index 50b7b5d3c7e..42b59ae53fd 100644 --- a/docs/facebookapi-legacy/app-events---logging/index.html +++ b/docs/facebookapi-legacy/app-events---logging/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ be logged once this cap is hit. However it is possible to deactivate obsolete events.

Read more about event limits in the FAQ.

Purchase Events

You can log purchase events using the logPurchase function.

var event:FacebookAppPurchaseEvent = new FacebookAppPurchaseEvent( 
79.99,
"USD"
);

FacebookAPI.service.appEvents.logPurchase( event );

The currency specification is expected to be an ISO 4217 currency code. This is used to determine a uniform value for use in ads optimization.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-events---overview/index.html b/docs/facebookapi-legacy/app-events---overview/index.html index 7c6300af028..1a77a981d8a 100644 --- a/docs/facebookapi-legacy/app-events---overview/index.html +++ b/docs/facebookapi-legacy/app-events---overview/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ This analytics channel provides demographic info about the people using your app, offers tools for better understanding the flows people follow in your app, and lets you compare cohorts of different kids of people performing the same actions.

See the documentation for Facebook Analytics for Apps for more information.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-events---user-properties/index.html b/docs/facebookapi-legacy/app-events---user-properties/index.html index d5f38ca780a..e016c5953e9 100644 --- a/docs/facebookapi-legacy/app-events---user-properties/index.html +++ b/docs/facebookapi-legacy/app-events---user-properties/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ allows you to understand user behavior. One of the key features of Facebook Analytics is segments. Segments allow you to better understand your audience by analyzing the behavior and demographics of a group of people that you define.

Many businesses also want to create segments based on other things they know about their customers. For example, an airline might want to create a segment based on values from their customer relationship management (CRM) system, such as frequent flyer status or the year that a customer became a member of their frequent flyer program.

With user properties, businesses can use their own CRM data to understand and analyze behavior. You can create user properties directly in your app or by using our API.

User IDs and user properties can't include any personally identifying information, such as people's names or email addresses.

User ID

By calling the setUserID function, you can assign an ID to a user of your app. For example, you could create a number that associates the user with information you collected when they installed your app. Typically, this is your identifier for the user in your own CRM or other back-end systems. The setUserID function is helpful if you expect to upload data from your app and use the API because it ensures that properties are attributed to the same user.

FacebookAPI.service.appEvents.setUserID( "user1234" );

The length of the user ID must be less than 100 characters.

When you set a user ID, this ID is stored on the user's device, and is included in app events logged from that device.

Properties

Once you have called setUserID, then you can also create a table with custom fields for user properties, that you can update with custom values. For example, you could have a user property like "Customer Loyalty Status" with values like "Gold," "Silver," or "Bronze." This would allow you to see and segment analytics based on these values in Analytics.

FacebookAPI.service.appEvents.setUserProperties( 
{
test_prop: "test_value"
});

Further Information

More information can be found in the Facebook documentation

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-invites---dialog/index.html b/docs/facebookapi-legacy/app-invites---dialog/index.html index 728e123b09e..8afe83fd8fa 100644 --- a/docs/facebookapi-legacy/app-invites---dialog/index.html +++ b/docs/facebookapi-legacy/app-invites---dialog/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ or if the application isn't setup correctly.

Events

There are three possible events dispatched after a call to show:

FacebookAPI.service.appInvite.addEventListener( AppInviteEvent.DIALOG_COMPLETED, appInviteDialogEventHandler );
FacebookAPI.service.appInvite.addEventListener( AppInviteEvent.DIALOG_CANCELLED, appInviteDialogEventHandler );
FacebookAPI.service.appInvite.addEventListener( AppInviteEvent.DIALOG_ERROR, appInviteDialogEventHandler );

And then your event handler:

private function appInviteDialogEventHandler( event:AppInviteEvent ):void 
{
}

Note that in some circumstances the completed event maybe dispatched even when the user cancelled the invite. This is an issue with the Facebook SDK and we will update as soon as they have made a fix available.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-links---incoming-links/index.html b/docs/facebookapi-legacy/app-links---incoming-links/index.html index acdb7acafb7..177ebdf6880 100644 --- a/docs/facebookapi-legacy/app-links---incoming-links/index.html +++ b/docs/facebookapi-legacy/app-links---incoming-links/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ Enter the url for your app eg distriqtTestApp://link and you'll get a notification in your Facebook application.

You must be logged into the Facebook app on your device with your developer account in order for this to work.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/app-links---overview/index.html b/docs/facebookapi-legacy/app-links---overview/index.html index 9f4f0c2bf19..7c672a11697 100644 --- a/docs/facebookapi-legacy/app-links---overview/index.html +++ b/docs/facebookapi-legacy/app-links---overview/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ to your app. Read more about App Links at applinks.org or read Facebook's guide on App Links.

The following is an example of App Link markup.

<html>
<head>
<meta property="al:ios:url" content="couchinapp://invite_from_fb?referral=123456789" />
<meta property="al:ios:app_store_id" content="123456789" />
<meta property="al:ios:app_name" content="Couchin'" />
<meta property="al:android:url" content="couchinapp://invite_from_fb?referral=123456789" />
<meta property="al:android:app_name" content="Couchin" />
<meta property="al:android:package" content="com.mycompany.couchin" />
<meta property="al:web:url" content="http://www.couchinapp.com/myapp.html" />
</head>
<body>
Couchin App Link
</body>
</html>

You can use our tool to create App Links hosted on Facebook. This is useful if you're a mobile developer and you don't want to host any content on the web.

Create App Link

App Invites

Starting 6th February 2018, App Invites will no longer be supported. Starting with SDK version 4.28 and above.

See the notice here

For an alternative see the Game Request Dialog

App Invites are a content-rich, personal way for people to invite their Facebook friends to a mobile app.

You can integrate App Invites into your app in place where people want to invite friends to your app. When the person taps the invite button, you can trigger the flow to send invites.

The person who wants to send invitations sees a UI flow where they can select the recipients and add a personalized message to the invite.

As the app developer, you can also include an image as part of the invite. If someone selects multiple recipients, each recipeint will receive an individual invite. Once the invite is sent or canceled, the person will return back to the app.

Facebook Login is not required for app invites because the experience takes place in the Facebook native mobile app. As a result, you should check to make sure this feature is available and hide the flow if it isn't.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/changelog/index.html b/docs/facebookapi-legacy/changelog/index.html index b106398690a..2a4ac7af9ca 100644 --- a/docs/facebookapi-legacy/changelog/index.html +++ b/docs/facebookapi-legacy/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2020.05.08 [v7.1.193]
Updated SDK
- iOS v5.15.1

Removed discontinued AccountKit (https://developers.facebook.com/blog/post/2019/09/09/account-kit-services-no-longer-available-starting-march)
- contained UIWebView usages (resolves #266)
2020.03.26 [v7.0.187]
Corrected issue with make request events not dispatching (#260)
2020.03.23 [v7.0.186]
Android X migration (resolves #259)
Updated SDK
- iOS: v5.9.0
- Android: v6.1.0 (resolves #258, resolves #249, #235)
Added functionality to handle batch requests (resolves #257)

2019.11.22 [v6.1.173]
Updated SDK (resolves #252, resolves #234, #249)
- iOS: v5.9.0
- Android: v5.9.0
2019.07.31 [v6.0.168]
Android 64bit support (resolves #238)
Updated SDK (resolves #236)
- iOS: v5.3.0
- Android: v5.2.0
Added ability to disable / enable automatic logging (resolves #215)
2019.03.12 [v5.8.144]
Embedded iOS bitcode
2019.02.23 [v5.8.143]
Updated SDK 
- iOS: v4.40.0 - January 22, 2019
- Android: v4.40.0 - January 22, 2019
- resolves #226
2018.11.02 [v5.7.138]
Updated SDK 
- iOS: v4.38.0 - October 23, 2018
- Android: v4.38.1 - November 1, 2018
2018.08.31 [v5.6.131]
Improved performance of logEvent and logPurchase calls (resolves #203)
2018.07.23 [v5.6.126]
Updated SDK 
- iOS: v4.34.0 - June 18, 2018
- Android: v4.34.0 - June 18, 2018
(resolves #199, #197, #194, #189, #188)
2018.04.28 [v5.5.122]
Added ability to add int/Number typed parameters to a GraphAPIRequest (resolves #193)
2018.03.30 [v5.5.120]
Corrected graph requests on iOS made with a different access token
2018.03.26 [v5.5.118]
Updated docs
2018.03.26 [v5.5.118]
Account Kit dependencies correction (#188)
2018.03.13 [v5.5.088]
Updated SDK 
- iOS: v4.30.0 - January 24, 2018
- Android: v4.30.0 - January 24, 2018
Added Share Open Graph Stories (resolves #162)
Corrected canShow share dialog flags (resolves #173)
Added additional LoginBehaviour options
Added the ShareAPI for dialog free sharing
2017.09.08 [v5.4.015]
Updated to the latest SDK (v4.26.0 - August 24, 2017)
Corrected missing classes from default lib (resolves #172)
2017.07.12 [v5.3.005]
Updated to the latest SDK (v4.24.0 - June 26, 2017)
2017.07.10 [v5.2.006]
Updated for compatibility with new Core library (for Notifications/PushNotifications fix)
2017.05.31 [v5.2.002]
Updated to the latest SDK (v4.23.0 - May 25, 2017) (#155,#156,#160)
Fixes issue with unsupported language in App Store Review process (resolves #157)
2017.04.28 [v5.1.114]
Added user properties for AppEvents / Analytics
2017.04.02 [v5.0.112]
Release v5.0 (resolves #149)
Account Kit Implementation (resolves #129)
Added System Account Login Behaviour (resolves #108)
Android: Resolved NPE (resolves #144)
Added missing functions for platforms (resolves #127)
Deferred deep linking (resolves #48)
Game request filters (resolves #74)
Graph API implementation (resolves #136)
New login process (resolves #144, resolves #138, resolves #133, resolves #125, resolves #116, resolves #144, resolves #113, resolves #111, resolves #109, resolves #108, resolves #75)
New share dialogs (resolves #145, resolves #146, resolves #134, resolves #132, resolves #130, resolves #122, resolves #120, resolves #117, resolves #112, resolves #74, resolves #32)
App Links (resolves #128, resolves #48)
2017.01.16 [v4.1.011]
Updated Android Facebook SDK, new documentation
2017.01.05 [v4.1.001]
Update to fix some errors with share dialogs
2016.09.07 [v4.0.001]
Updated documentation
2016.09.07 [v4.0.001]
Updated documentation
2016.08.18 [v4.0.001]
Update to latest version, resolving issues with login behaviours and restoring sessions etc
2016.05.12
iOS: Made some changes to help automatically restore a session. After calling 'initialiseApp', you should receive a SESSION_INFO event if a previous session was found (resolves #28)

Fixed an issue to correctly return the postId of a share post (resolves #57)

Fixed a bug which would not always populate the 'data' parameter of a Game Request object (resolves #65)

Android: Fixed a bug which could cause a crash depending on the result of a graph request call (resolves #89)

Fixed a bug where the recipientIds for a game request were not always correctly returned (resolves #93)

Fixed a bug where the properties for a share dialog would not be passed through successfully in some cases depending on the preferred dialog type (resolves #95)
2015.10.27
Added missing call to initialiseApp() in example code
2015.10.27
Updated to FacebookSDK v4.7.0 for iOS to support iOS9 changes; Added a new basic example application and descriptor; Added initial implementation of deferred app-link handling for testing
2015.09.18
Corrected a bug on Android which could prevent graph requests which contained field parameters from working correctly
2015.09.08
Updated FacebookSDK to latest version, 5.4.1
2015.07.23
Made changelog publicly available
2015.07.23
Made changelog publicly available
2015.07.23
Updated to support latest version of Facebook's SDK (4.2+)
2015.03.12
Updated iOS Facebook SDK version and added capability to issue app install events without a session being required
2015.02.24
Fixed system account login bug for iOS native login
2015.01.06
iOS: Included arm64 support
2014.12.17
Re-added support for missing methods - logEvent, logPurchase etc
2014.12.11
Updated with new base key check etc
2014.12.11
New application based key check, removing server checks
iOS: Implemented autoreleasepools for all C function calls
Both platforms now support the V2 SDK Message dialog (basic share)
2014.12.10
First version of FacebookAPI V2 added to new repo
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/facebook-android-app/index.html b/docs/facebookapi-legacy/facebook-android-app/index.html index 2b378294afc..a9f18669c00 100644 --- a/docs/facebookapi-legacy/facebook-android-app/index.html +++ b/docs/facebookapi-legacy/facebook-android-app/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ called Alias name. This is the alias parameter that's required.

Flash Builder

If you are running debug builds from Flash Builder, it uses a different P12 file than you might expect. You'll need to get the key hash from the following certificate for debug builds.

On OSX:

/Applications/Adobe Flash Builder 4.7/eclipse/plugins/com.adobe.flexide.multiplatform.android_4.7.0.349722/resources/debug-certificate-android.p12

On Windows it will be similar to:

C:\Program Files\eclipse\plugins\com.adobe.flexide.multiplatform.android_4.7.0.349722\resources\debug-certificate-android.p12
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/facebook-application/index.html b/docs/facebookapi-legacy/facebook-application/index.html index 12e2a098895..813675e45a2 100644 --- a/docs/facebookapi-legacy/facebook-application/index.html +++ b/docs/facebookapi-legacy/facebook-application/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ dashboard settings page. Select the Settings option in the left menu to continue.

Enter the basic information for your app, including Display Name, Namespace, App Domains and Contact Email.

Here's an example of the settings we'll use for our app:

At this point you will need to add the relevant platforms you need to support. The following sections cover the setup for iOS and Android separately, so select Add Platform, then choose either iOS or Android and continue below.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/facebook-ios-app/index.html b/docs/facebookapi-legacy/facebook-ios-app/index.html index 6eb04117c76..cb4d155f775 100644 --- a/docs/facebookapi-legacy/facebook-ios-app/index.html +++ b/docs/facebookapi-legacy/facebook-ios-app/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Facebook iOS App

caution

This is the legacy extension documentation. Find the new documentation here

Setup: Facebook iOS App

For iOS, you'll need to set some properties about your app here. Here's an example of the settings we're using:

Bundle ID: This is the ID of your AIR application as set in your application descriptor. This is generally a reverse DNS style name, such as com.distriqt.example.

iPhone Store ID / iPad Store ID: This will be the iTunes app ID of your app when published. At this stage, you probably won't have this ID since it's a new app. You can just use another app ID here for now, and replace it later once your iOS app is live. We're just using the ID of Adobe Photoshop Express for the time being, which is 331975235.

URL Scheme Suffix: This is only required if you want to share your app ID across multiple apps - for example, if you wanted to have a free and a paid version of your app. You can read more about this here: https://developers.facebook.com/docs/ios/troubleshooting.

Single Sign On: Turn this to ON. This is required for users to be able to log in through your application.

Deep Linking: Turn this to ON. This is not required, but will be needed if you want to be able to link back to your app from Facebook links.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/games---game-request-dialog/index.html b/docs/facebookapi-legacy/games---game-request-dialog/index.html index 203cdefb197..2dc7ef2f093 100644 --- a/docs/facebookapi-legacy/games---game-request-dialog/index.html +++ b/docs/facebookapi-legacy/games---game-request-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ or if the application isn't setup correctly.

Events

There are three possible events dispatched after a call to show:

FacebookAPI.service.appInvite.addEventListener( GameRequestEvent.DIALOG_COMPLETED, gameRequestEventHandler );
FacebookAPI.service.appInvite.addEventListener( GameRequestEvent.DIALOG_CANCELLED, gameRequestEventHandler );
FacebookAPI.service.appInvite.addEventListener( GameRequestEvent.DIALOG_ERROR, gameRequestEventHandler );

And then your event handler:

private function gameRequestEventHandler( event:GameRequestEvent ):void 
{
}

Note that in some circumstances the completed event maybe dispatched even when the user cancelled the invite. This is an issue with the Facebook SDK and we will update as soon as they have made a fix available.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/games---overview/index.html b/docs/facebookapi-legacy/games---overview/index.html index d5e43eabd8c..261aa4f4d15 100644 --- a/docs/facebookapi-legacy/games---overview/index.html +++ b/docs/facebookapi-legacy/games---overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/graph-api---basics/index.html b/docs/facebookapi-legacy/graph-api---basics/index.html index a7c31a8804a..163979507b9 100644 --- a/docs/facebookapi-legacy/graph-api---basics/index.html +++ b/docs/facebookapi-legacy/graph-api---basics/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ users email address. To add a field use the addField or addFields function on the builder:

new GraphAPIRequestBuilder()
.setPath( "/me" )
.addField( "email" )
.build();

Parameters are often additional information passed along with the request, for example a link passed along with a post request. To add a parameter use the addParameter function on the builder:

new GraphAPIRequestBuilder()
.setPath( "/me/feed" )
.setMethod( GraphAPIRequestBuilder.METHOD_POST )
.addParameter( "link", "https://airnativeextensions.com" )
.build();

Image Data

If you wish to add image data to a post you can use the setImage function:

new GraphAPIRequestBuilder()
.setPath( "/me/photos" )
.setMethod( GraphAPIRequestBuilder.METHOD_POST )
.setImage( yourBitmapData )
.addParameter( "message", "Image posted through the Graph API from the Facebook API ANE" )
.build();
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/graph-api---batch/index.html b/docs/facebookapi-legacy/graph-api---batch/index.html index 5fd8153c6d6..d810217a446 100644 --- a/docs/facebookapi-legacy/graph-api---batch/index.html +++ b/docs/facebookapi-legacy/graph-api---batch/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Graph API - Batch

caution

This is the legacy extension documentation. Find the new documentation here

Graph API Batch

If you have several requests you wish to batch together you can use the GraphAPIRequestBatchBuilder to create a batch request.

To create a batch, firstly create your GraphAPIRequest instances as normal:

var request1:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath('/me')
.setMethod('GET')
.addFields(["first_name","gender","picture.width(160).height(160)" ])
.build();

var request2:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath('/me/friends')
.setMethod('GET')
.addParameter("limit", 200 )
.addFields(["id","first_name","installed","picture.width(160).height(160)" ])
.build();

Then construct the GraphAPIRequestBatch using a GraphAPIRequestBatchBuilder:

var batch:GraphAPIRequestBatch = new GraphAPIRequestBatchBuilder()
.addRequest( request1 )
.addRequest( request2 )
.build();

Then call makeBatchRequest() with your GraphAPIRequestBatch instance:

FacebookAPI.service.graphAPI.makeBatchRequest( batch );

Events

You can add event listeners to the request objects to process the return data from each individual request, as you would for a single request:

request1.addEventListener( GraphAPIRequestEvent.COMPLETE, request1_completeHandler );
request1.addEventListener( GraphAPIRequestEvent.ERROR, request1_errorHandler );
request2.addEventListener( GraphAPIRequestEvent.COMPLETE, request2_completeHandler );
request2.addEventListener( GraphAPIRequestEvent.ERROR, request2_errorHandler );

function request1_completeHandler( event:GraphAPIRequestEvent ):void
{
// event.data will contain the Facebook response
}

function request1_errorHandler( event:GraphAPIRequestEvent ):void
{
// event.errorCode and event.errorMessage will contain details on the error
}

function request2_completeHandler( event:GraphAPIRequestEvent ):void
{
// event.data will contain the Facebook response
}

function request2_errorHandler( event:GraphAPIRequestEvent ):void
{
// event.errorCode and event.errorMessage will contain details on the error
}

Additionally you can listen for a GraphAPIRequestEvent.BATCH_COMPLETE event to be notified when all the requests have been completed.

batch.addEventListener( GraphAPIRequestEvent.BATCH_COMPLETE, batch_completeHandler );

function batch_completeHandler( event:GraphAPIRequestEvent ):void
{
trace( "batch complete" );
}

You should make sure to add these listeners before the call to makeBatchRequest().

Callbacks

As an alternative to events, you can add callbacks to the requests as you do with a normal GraphAPIRequest:

var request1:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath( "/me" )
.setCompleteCallback(
function( data:Object ):void
{
log( "request complete: " + JSON.stringify(data) );
}
)
.setErrorCallback(
function( code:int, message:String ):void
{
log( "request error: " + code + "::"+ message );
}
)
.build();

Additionally you can add a completion callback to the GraphAPIRequestBatch object:

var batch:GraphAPIRequestBatch = new GraphAPIRequestBatchBuilder()
.addRequest( request1 )
.addRequest( request2 )
.addRequest( request3 )
.setCompleteCallback(
function():void
{
log( "batch complete" );
}
)
.build();
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/graph-api---examples/index.html b/docs/facebookapi-legacy/graph-api---examples/index.html index 4f944d86d5d..a8debfac2fe 100644 --- a/docs/facebookapi-legacy/graph-api---examples/index.html +++ b/docs/facebookapi-legacy/graph-api---examples/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Graph API - Examples

caution

This is the legacy extension documentation. Find the new documentation here

Some examples of using the Graph API

Get Current User Info

Requires the "email" permission.

var request:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath( "/me" )
.addField( "email" )
.addField( "name" )
.build();

FacebookAPI.service.graphAPI.makeRequest( request );

Get User Permissions

new GraphAPIRequestBuilder()
.setPath( "/me/permissions" )
.build();

Get User Friends

Requires the "user_friends" permission.

var request:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath( "/me/friends" )
.addField( "name" )
.build();

Post Status Update

Requires the "publish_actions" permission.

new GraphAPIRequestBuilder()
.setPath( "/me/feed" )
.setMethod( METHOD_POST )
.addParameter( "message", message )
.build();

Requires the "publish_actions" permission.

var request:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath( "/me/feed" )
.setMethod( GraphAPIRequestBuilder.METHOD_POST )
.addParameter( "link", "https://airnativeextensions.com" )
.addParameter( "caption", "Posted through the Graph API from the Facebook API ANE" )
.build();

FacebookAPI.service.graphAPI.makeRequest( request );

Posting an Image

Requires the "publish_actions" permission.

var request:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath( "/me/photos" )
.setMethod( GraphAPIRequestBuilder.METHOD_POST )
.setImage( _image.bitmapData )
.addParameter( "message", "Image posted through the Graph API from the Facebook API ANE" )
.build();

FacebookAPI.service.graphAPI.makeRequest( request );
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/graph-api---overview/index.html b/docs/facebookapi-legacy/graph-api---overview/index.html index b0ecae6cff3..8514a6a72b3 100644 --- a/docs/facebookapi-legacy/graph-api---overview/index.html +++ b/docs/facebookapi-legacy/graph-api---overview/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ it will still involve knowledge of the API.

Load the Graph API Explorer

The easiest way to understand the Graph API is to use it with the Graph API Explorer, a low-level tool you can use to query, add and remove data. It's a very handy resource to have at your fingertips while you integrate with Facebook.

So your next step is to go to the Graph API Explorer.

Further Information

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/index.html b/docs/facebookapi-legacy/index.html index 436fe448f2b..c39e14f0c1d 100644 --- a/docs/facebookapi-legacy/index.html +++ b/docs/facebookapi-legacy/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ allows you to connect users with Facebook and utilise the integrated SDK and Facebook application features.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/initialise-facebook-app/index.html b/docs/facebookapi-legacy/initialise-facebook-app/index.html index 56bf86df39a..0ac4413a396 100644 --- a/docs/facebookapi-legacy/initialise-facebook-app/index.html +++ b/docs/facebookapi-legacy/initialise-facebook-app/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Initialise Facebook App

caution

This is the legacy extension documentation. Find the new documentation here

Initialise the Facebook Application

The first step to use the Facebook API ANE is to inform the ANE of your Facebook Application ID.

This is a simple matter of calling initialiseApp and must be done after init is called but before any other functionality is used.

// Initialise the ANE with your Facebook App ID
FacebookAPI.service.initialiseApp( "YOUR_FACEBOOK_APP_ID" );

This will initialise the Facebook SDK internally and inform the SDK of your applicaiton id.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/initialise-the-extension/index.html b/docs/facebookapi-legacy/initialise-the-extension/index.html index 0416e3ab109..f19170f4389 100644 --- a/docs/facebookapi-legacy/initialise-the-extension/index.html +++ b/docs/facebookapi-legacy/initialise-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Initialise the Extension

caution

This is the legacy extension documentation. Find the new documentation here

Initialising the Extension

You should perform this once in your application to initialise the extension . Note you should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

try
{
Core.init();
FacebookAPI.init();
if (FacebookAPI.isSupported)
{
// Functionality here
}
}
catch (e:Error)
{
trace( e );
}
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/login---access-token/index.html b/docs/facebookapi-legacy/login---access-token/index.html index feb029cf8f5..08776254543 100644 --- a/docs/facebookapi-legacy/login---access-token/index.html +++ b/docs/facebookapi-legacy/login---access-token/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ class represents a user's access token.

You will have access to this after a session is successfully created, it will be part of the FacebookAPISessionEvent event dispatched and also available by the getAccessToken function:

var token:AccessToken = FacebookAPI.service.getAccessToken();

You will need the token String for any calls to the Facebook APIs.

Permissions

You can access the list of granted and denied permissions through the access token.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/login---facebook-login/index.html b/docs/facebookapi-legacy/login---facebook-login/index.html index 2759b6fb128..7044cf6d4de 100644 --- a/docs/facebookapi-legacy/login---facebook-login/index.html +++ b/docs/facebookapi-legacy/login---facebook-login/index.html @@ -13,7 +13,7 @@ - + @@ -46,7 +46,7 @@ same request so you should initially request your read permissions and then at some later point (normally just before you are going to perform a write) request the write permissions.

Calling requestPermissions will result in one of the FacebookAPISessionEvents

FacebookAPI.service.addEventListener( FacebookAPISessionEvent.REQUEST_PERMISSIONS_COMPLETED, requestPermissionsHandler );
FacebookAPI.service.addEventListener( FacebookAPISessionEvent.REQUEST_PERMISSIONS_CANCELLED, requestPermissionsHandler );
FacebookAPI.service.addEventListener( FacebookAPISessionEvent.REQUEST_PERMISSIONS_ERROR, requestPermissionsHandler );

Similar to the other events in the handler you will have access to the new access token:

function requestPermissionsHandler( event:FacebookAPISessionEvent ):void 
{
switch (event.type)
{
case FacebookAPISessionEvent.REQUEST_PERMISSIONS_COMPLETED:
trace("User ID: " + event.accessToken.userId );
trace("Expiration date: " + event.accessToken.expirationTimestamp );
trace("Permissions: " + event.accessToken.permissions.join(", "));
trace("Access token: " + event.accessToken.token);
break;

case FacebookAPISessionEvent.REQUEST_PERMISSIONS_CANCELLED:
// User cancelled the request
break;

case FacebookAPISessionEvent.REQUEST_PERMISSIONS_ERROR:
// There was an error
trace( "ERROR: "+ event.errorMessage );
break;
}
}
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/login---overview/index.html b/docs/facebookapi-legacy/login---overview/index.html index 9775e4973c0..628f297954f 100644 --- a/docs/facebookapi-legacy/login---overview/index.html +++ b/docs/facebookapi-legacy/login---overview/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ so you can retrieve information or perform actions on Facebook on their behalf.

If people don't have the Facebook app installed, Facebook Login uses Facebook Lite instead to display the login screen and get credentials. Previous SDKs required that people have the Facebook app installed.

For more information see the Facebook Login documentation

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/migrating-to-androidx/index.html b/docs/facebookapi-legacy/migrating-to-androidx/index.html index 5cc41a401e2..b93d2ea6257 100644 --- a/docs/facebookapi-legacy/migrating-to-androidx/index.html +++ b/docs/facebookapi-legacy/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

caution

This is the legacy extension documentation. Find the new documentation here

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/sharing---content/index.html b/docs/facebookapi-legacy/sharing---content/index.html index de4a04a748b..32ad95f874b 100644 --- a/docs/facebookapi-legacy/sharing---content/index.html +++ b/docs/facebookapi-legacy/sharing---content/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ share content.

You can add photos either by:

var bitmapData:BitmapData = ...;

var builder:SharePhotoContentBuilder = new SharePhotoContentBuilder()
.addBitmap( bitmapData );

Or using addImageUrl:

var builder:SharePhotoContentBuilder = new SharePhotoContentBuilder()
.addImageUrl( "https://airnativeextensions.com/images/extensions/icons/ane-facebookapi-icon.png" );

Videos

People using your app can share videos to Facebook with the Share dialog or with your own custom interface:

To share videos you will be using the ShareVideoContentBuilder to construct the share content.

var videoUrl:String = ...;

var builder:ShareVideoContentBuilder = new ShareVideoContentBuilder()
.setVideoUrl( videoUrl );

Media

People can share a combination of photos and videos from your app to Facebook with the Share Dialog.

Note the following:

To share media you will be using the ShareMediaContentBuilder to construct the share content.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/sharing---message-dialog/index.html b/docs/facebookapi-legacy/sharing---message-dialog/index.html index 9c1d50a51ff..78a502baebd 100644 --- a/docs/facebookapi-legacy/sharing---message-dialog/index.html +++ b/docs/facebookapi-legacy/sharing---message-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ of this function. It is a boolean value and indicates if the message dialog construction was initiated correctly. If will return false if the required dialog type isn't supported or if the application isn't setup correctly.

Events

There are three possible events dispatched after a call to show:

FacebookAPI.service.messageDialog.addEventListener( MessageDialogEvent.DIALOG_COMPLETED, messageDialogEventHandler );
FacebookAPI.service.messageDialog.addEventListener( MessageDialogEvent.DIALOG_CANCELLED, messageDialogEventHandler );
FacebookAPI.service.messageDialog.addEventListener( MessageDialogEvent.DIALOG_ERROR, messageDialogEventHandler );

And then your event handler:

private function messageDialogEventHandler( event:MessageDialogEvent ):void 
{
}
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/sharing---open-graph-stories/index.html b/docs/facebookapi-legacy/sharing---open-graph-stories/index.html index 1174e6fc767..f17430e7890 100644 --- a/docs/facebookapi-legacy/sharing---open-graph-stories/index.html +++ b/docs/facebookapi-legacy/sharing---open-graph-stories/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Sharing - Open Graph Stories

caution

This is the legacy extension documentation. Find the new documentation here

Available in v5.5

Open Graph Stories

With Open Graph people can share stories from your app to Facebook through a structured, strongly typed API.

When people engage with these stories they can go to your app or if they don't have your app installed, to your app's App Store page. This drives engagement and distribution for your app.

There are two ways to publish an Open Graph story:

  • Using the Share dialog
  • Using your own custom interface using the Graph API

The Share dialog lets people publish stories from your app without Facebook Login or the publish_actions permission.

The Share dialog does this with a fast app-switch to the native Facebook for Android app installed in the device. Once a story is published, control returns to your app.

Creating Open Graph Stories

Open Graph stories are made up of a verb, or action and noun, known as object. To create a story, you need to define the action and object for your app's content.

To demonstrate the concepts we will use an example of a story about "reading a book".

Create an object with the object type books.book and set the properties on the object:

var shareOpenGraphObject:Object = new ShareOpenGraphObjectBuilder()
.putString( "og:type", "books.book" )
.putString( "og:title", "A Game of Thrones" )
.putString( "og:description", "In the frozen wastes to the north of Winterfell, sinister and supernatural forces are mustering." )
.putString( "books:isbn", "0-553-57340-3" )
.build();

Then create an action and link the object to the action.

var shareOpenGraphAction:Object = new ShareOpenGraphActionBuilder()
.setActionType( "books.reads" )
.putObject( "book", shareOpenGraphObject )
.build();

Finally, create the content model to represent the Open Graph story.

var openGraphContent:Object = new ShareOpenGraphContentBuilder()
.setPreviewPropertyName("book")
.setAction( shareOpenGraphAction )
.build();

All objects and action types in your code must be lowercase. All property names require namespaces.

Show the Share Dialog

Present the Share dialog by using the show method on ShareDialog.

FacebookAPI.service.shareDialog.show( openGraphContent );

In past versions of the SDK for Android, your app had to check for a native, installed Facebook app before it could open the Share Dialog. If the person didn't have the app installed, you had to provide your own code to call a fallback dialog.

Now the SDK automatically checks for the native Facebook app. If it isn't installed the Web Share dialog launches as a fallback.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/sharing---overview/index.html b/docs/facebookapi-legacy/sharing---overview/index.html index bb41e227b0a..1f13fba3868 100644 --- a/docs/facebookapi-legacy/sharing---overview/index.html +++ b/docs/facebookapi-legacy/sharing---overview/index.html @@ -13,7 +13,7 @@ - + @@ -36,7 +36,7 @@ context of the share sheet. This means apps may not pre-fill the share sheet's initialText field with content that wasn't entered by the user of the app.

- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/sharing---share-api/index.html b/docs/facebookapi-legacy/sharing---share-api/index.html index ca22426c407..aa295864736 100644 --- a/docs/facebookapi-legacy/sharing---share-api/index.html +++ b/docs/facebookapi-legacy/sharing---share-api/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Sharing - Share API

caution

This is the legacy extension documentation. Find the new documentation here

Share API

The Share API allows you to perform similar things to the Share Dialog however instead of using the Facebook dialogs you can create your own interface for sharing,and post directly with this API. You will need to:

  • Build a custom interface
  • Add Facebook Login to your app
  • Request the publish_actions permission
  • Create your content to post using one of the content builders
  • Post to the API

Creating Content

Create content as you do for the Share and Message Dialogs using the builders, as outlined in the Share Content section.

For example, to create a link to share:

var builder:ShareLinkContentBuilder = new ShareLinkContentBuilder()
.setContentTitle("FacebookAPI ANE")
.setContentDescription("This link was shared using the distriqt FacebookAPI ANE" )
.setContentUrl("https://airnativeextensions.com/extension/com.distriqt.FacebookAPI");

Share

Once you have created your content you post this to Facebook by using the ShareAPI, share function:

var success:Boolean = FacebookAPI.service.shareAPI.share( builder.build() );

This may return false if the content isn't valid or cannot be shared via the ShareAPI.

If started successfully the ShareAPI will dispatch an event when the post is complete, similar to the ShareDialog process.

  • ShareAPIEvent.COMPLETED: when the share was successfully completed
  • ShareAPIEvent.CANCELLLED: when the share was cancelled
  • ShareAPIEvent.ERROR: when an error occurred during the process
FacebookAPI.service.shareAPI.addEventListener( ShareAPIEvent.COMPLETED, shareAPIEventHandler );
FacebookAPI.service.shareAPI.addEventListener( ShareAPIEvent.CANCELLED, shareAPIEventHandler );
FacebookAPI.service.shareAPI.addEventListener( ShareAPIEvent.ERROR, shareAPIEventHandler );

And then your event handler:

function shareAPIEventHandler( event:ShareAPIEvent ):void 
{
// If successful event.postId will contain the post identifier
if (event.postId != null)
{
trace( "postId="+event.postId);
}
}
- + \ No newline at end of file diff --git a/docs/facebookapi-legacy/sharing---share-dialog/index.html b/docs/facebookapi-legacy/sharing---share-dialog/index.html index a1bffbcab35..b2690f76985 100644 --- a/docs/facebookapi-legacy/sharing---share-dialog/index.html +++ b/docs/facebookapi-legacy/sharing---share-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ was initiated correctly. If will return false if the required dialog type isn't supported or if the application isn't setup correctly.

Events

There are three possible events dispatched after a call to show:

FacebookAPI.service.shareDialog.addEventListener( ShareDialogEvent.DIALOG_COMPLETED, shareDialogEventHandler );
FacebookAPI.service.shareDialog.addEventListener( ShareDialogEvent.DIALOG_CANCELLED, shareDialogEventHandler );
FacebookAPI.service.shareDialog.addEventListener( ShareDialogEvent.DIALOG_ERROR, shareDialogEventHandler );

And then your event handler:

private function shareDialogEventHandler( event:ShareDialogEvent ):void 
{
// If successful event.postId will contain the post identifier
if (event.postId != null)
{
trace( "postId="+event.postId);
}
}

Notes

Your app should not pre-fill any content to be shared. This is inconsistent with Facebook Platform Policy, see Facebook Platform Policy, 2.3.

Example


if (FacebookAPI.service.shareDialog.canShow( ShareLinkContentBuilder.TYPE ))
{
FacebookAPI.service.shareDialog.addEventListener( ShareDialogEvent.DIALOG_COMPLETED, shareDialogEventHandler );
FacebookAPI.service.shareDialog.addEventListener( ShareDialogEvent.DIALOG_CANCELLED, shareDialogEventHandler );
FacebookAPI.service.shareDialog.addEventListener( ShareDialogEvent.DIALOG_ERROR, shareDialogEventHandler );

var builder:ShareLinkContentBuilder = new ShareLinkContentBuilder()
.setContentTitle("FacebookAPI ANE")
.setContentDescription("This link was shared using the distriqt FacebookAPI ANE" )
.setContentUrl("https://airnativeextensions.com/extension/com.distriqt.FacebookAPI");

var success:Boolean = FacebookAPI.service.shareDialog.show( builder.build() );

}

...

private function shareDialogEventHandler( event:ShareDialogEvent ):void
{
FacebookAPI.service.shareDialog.removeEventListener( ShareDialogEvent.DIALOG_COMPLETED, shareDialogEventHandler );
FacebookAPI.service.shareDialog.removeEventListener( ShareDialogEvent.DIALOG_CANCELLED, shareDialogEventHandler );
FacebookAPI.service.shareDialog.removeEventListener( ShareDialogEvent.DIALOG_ERROR, shareDialogEventHandler );

if (event.postId != null) log( "postId="+event.postId);
}
- + \ No newline at end of file diff --git a/docs/facebookapi/changelog/index.html b/docs/facebookapi/changelog/index.html index 0c0f68707d1..6e239e73659 100644 --- a/docs/facebookapi/changelog/index.html +++ b/docs/facebookapi/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.04.04 [v16.0.101]
fix(ios): correct frameworks published in the repository (#373)
2023.04.04 [v16.0.101]
fix(ios): correct frameworks published in the repository (#373)
2023.04.04 [v16.0.101]
fix(ios): correct frameworks published in the repository (#373)
2023.04.03 [v16.0.1]
feat(sdk): update sdk, android v16.0.1, ios v16.0.1
2023.01.18 [v15.1.0]
feat(android): update facebook android sdk v15.2.0
feat(ios): update facebook ios sdk v15.1.0
feat(docs): add notes about requesting ATT auth on iOS for event tracking (#351)
feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #368)
2022.07.18 [v10.2.1]
feat(all): add ios simulator implementation and required dynamic frameworks to packages (resolves #352)
2022.07.18 [v10.2.1]
feat(all): add ios simulator implementation and required dynamic frameworks to packages (resolves #352)
2022.06.27 [v10.2.0]
feat(ios): update ios sdk v13.2.0
feat(login,ios): correct issue with not picking up previous login session on ios (resolves #343)
feat(share): add legacy game request dialog for legacy game implementations
2022.04.05 [v10.0.1]
Android: Fix issue with air package and facebook application id meta-data value (resolves #341) 
2022.03.21 [v10.0.0]
Facebook SDK update
- Android v13.0.0
- iOS v13.0.0

Update documentation to use apm
Update for Android 12 (API 31) support including latest androidx dependencies
2021.12.13 [v9.3.3]
Update air packages with config descriptions
2021.10.13 [v9.3.2]
CRITICAL FIX: 9.3.1 was a broken build (resolves #324)
2021.10.12 [v9.3.1]
Update documentation around manifest additions for AAB issue (resolves #321)
Update air package with new manifest additions
2021.09.06 [v9.3.0]
Added airpackages

Updated SDK
- Android v9.1.1
- iOS v9.3.0

Corrected issue with Gaming Services callbacks being blocked by uninitialised Share and Login
GamingServices : Added recipients to game request dialog event (resolves #308)
Added added set advertiser tracking enabled functions for iOS 14 (resolves #309)
2021.03.15 [v9.0.011]
Updated SDK
- iOS v9.0.1
2021.03.04 [v9.0.005]
Added the data field to game requests (resolves #301)
Corrected documentation around new initialisation process (#300)
2021.02.03 [v9.0.003]
Updated SDK
- iOS v9.0.0
- Android v9.0.0

Introduced new limited tracking login process
Added access token and profile changed events (resolves #292)
2021.01.13 [v8.1.021]
Gaming Services SDK Added
- Game Request Dialog
- Friend Finder Dialog

Updated SDK
- iOS v8.2.0 (resolves #285)
- Android v8.2.0
2020.11.27 [v8.0.013]
Major update and refactoring (resolves #277)
Extension has been broken up into Facebook SDK components

Updates
- Resolved delayed initialisation (resolves #274, resolves #265)
- Removed the deprecated game request share dialog (resolves #235)
2020.08.14 [v7.1.194]
Corrected multidex documentation + updated build
2020.05.08 [v7.1.193]
Updated SDK
- iOS v5.15.1

Removed discontinued AccountKit (https://developers.facebook.com/blog/post/2019/09/09/account-kit-services-no-longer-available-starting-march)
- contained UIWebView usages (resolves #266)
2020.03.26 [v7.0.187]
Corrected issue with make request events not dispatching (#260)
2020.03.23 [v7.0.186]
Android X migration (resolves #259)
Updated SDK
- iOS: v5.9.0
- Android: v6.1.0 (resolves #258, resolves #249, #235)
Added functionality to handle batch requests (resolves #257)

2019.11.22 [v6.1.173]
Updated SDK (resolves #252, resolves #234, #249)
- iOS: v5.9.0
- Android: v5.9.0
2019.07.31 [v6.0.168]
Android 64bit support (resolves #238)
Updated SDK (resolves #236)
- iOS: v5.3.0
- Android: v5.2.0
Added ability to disable / enable automatic logging (resolves #215)
2019.03.12 [v5.8.144]
Embedded iOS bitcode
2019.02.23 [v5.8.143]
Updated SDK
- iOS: v4.40.0 - January 22, 2019
- Android: v4.40.0 - January 22, 2019
- resolves #226
2018.11.02 [v5.7.138]
Updated SDK
- iOS: v4.38.0 - October 23, 2018
- Android: v4.38.1 - November 1, 2018
2018.08.31 [v5.6.131]
Improved performance of logEvent and logPurchase calls (resolves #203)
2018.07.23 [v5.6.126]
Updated SDK
- iOS: v4.34.0 - June 18, 2018
- Android: v4.34.0 - June 18, 2018
(resolves #199, #197, #194, #189, #188)
2018.04.28 [v5.5.122]
Added ability to add int/Number typed parameters to a GraphAPIRequest (resolves #193)
2018.03.30 [v5.5.120]
Corrected graph requests on iOS made with a different access token
2018.03.26 [v5.5.118]
Updated docs
2018.03.26 [v5.5.118]
Account Kit dependencies correction (#188)
2018.03.13 [v5.5.088]
Updated SDK
- iOS: v4.30.0 - January 24, 2018
- Android: v4.30.0 - January 24, 2018
Added Share Open Graph Stories (resolves #162)
Corrected canShow share dialog flags (resolves #173)
Added additional LoginBehaviour options
Added the ShareAPI for dialog free sharing
2017.09.08 [v5.4.015]
Updated to the latest SDK (v4.26.0 - August 24, 2017)
Corrected missing classes from default lib (resolves #172)
2017.07.12 [v5.3.005]
Updated to the latest SDK (v4.24.0 - June 26, 2017)
2017.07.10 [v5.2.006]
Updated for compatibility with new Core library (for Notifications/PushNotifications fix)
2017.05.31 [v5.2.002]
Updated to the latest SDK (v4.23.0 - May 25, 2017) (#155,#156,#160)
Fixes issue with unsupported language in App Store Review process (resolves #157)
2017.04.28 [v5.1.114]
Added user properties for AppEvents / Analytics
2017.04.02 [v5.0.112]
Release v5.0 (resolves #149)
Account Kit Implementation (resolves #129)
Added System Account Login Behaviour (resolves #108)
Android: Resolved NPE (resolves #144)
Added missing functions for platforms (resolves #127)
Deferred deep linking (resolves #48)
Game request filters (resolves #74)
Graph API implementation (resolves #136)
New login process (resolves #144, resolves #138, resolves #133, resolves #125, resolves #116, resolves #144, resolves #113, resolves #111, resolves #109, resolves #108, resolves #75)
New share dialogs (resolves #145, resolves #146, resolves #134, resolves #132, resolves #130, resolves #122, resolves #120, resolves #117, resolves #112, resolves #74, resolves #32)
App Links (resolves #128, resolves #48)
2017.01.16 [v4.1.011]
Updated Android Facebook SDK, new documentation
2017.01.05 [v4.1.001]
Update to fix some errors with share dialogs
2016.09.07 [v4.0.001]
Updated documentation
2016.09.07 [v4.0.001]
Updated documentation
2016.08.18 [v4.0.001]
Update to latest version, resolving issues with login behaviours and restoring sessions etc
2016.05.12
iOS: Made some changes to help automatically restore a session. After calling 'initialiseApp', you should receive a SESSION_INFO event if a previous session was found (resolves #28)

Fixed an issue to correctly return the postId of a share post (resolves #57)

Fixed a bug which would not always populate the 'data' parameter of a Game Request object (resolves #65)

Android: Fixed a bug which could cause a crash depending on the result of a graph request call (resolves #89)

Fixed a bug where the recipientIds for a game request were not always correctly returned (resolves #93)

Fixed a bug where the properties for a share dialog would not be passed through successfully in some cases depending on the preferred dialog type (resolves #95)
2015.10.27
Added missing call to initialiseApp() in example code
2015.10.27
Updated to FacebookSDK v4.7.0 for iOS to support iOS9 changes; Added a new basic example application and descriptor; Added initial implementation of deferred app-link handling for testing
2015.09.18
Corrected a bug on Android which could prevent graph requests which contained field parameters from working correctly
2015.09.08
Updated FacebookSDK to latest version, 5.4.1
2015.07.23
Made changelog publicly available
2015.07.23
Made changelog publicly available
2015.07.23
Updated to support latest version of Facebook's SDK (4.2+)
2015.03.12
Updated iOS Facebook SDK version and added capability to issue app install events without a session being required
2015.02.24
Fixed system account login bug for iOS native login
2015.01.06
iOS: Included arm64 support
2014.12.17
Re-added support for missing methods - logEvent, logPurchase etc
2014.12.11
Updated with new base key check etc
2014.12.11
New application based key check, removing server checks
iOS: Implemented autoreleasepools for all C function calls
Both platforms now support the V2 SDK Message dialog (basic share)
2014.12.10
First version of FacebookAPI V2 added to new repo
- + \ No newline at end of file diff --git a/docs/facebookapi/core/add-the-extension/index.html b/docs/facebookapi/core/add-the-extension/index.html index 87c52d2c0e7..b003f42b6bc 100644 --- a/docs/facebookapi/core/add-the-extension/index.html +++ b/docs/facebookapi/core/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ It contains the Bolts framework.

You can access this extension here: https://github.com/distriqt/ANE-Bolts.

Android Support

The Android Support libraries encompass the Android Support, Android X and common Google libraries.

These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

This extension requires the following extensions:

You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

Note: if you have been using the older com.distriqt.androidsupport.* (Android Support) extensions you should remove these extensions and replace it with the androidx extensions listed above. This is the new version of the android support libraries and moving forward all our extensions will require AndroidX.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-events/automatic-logging/index.html b/docs/facebookapi/core/app-events/automatic-logging/index.html index 7a29e498249..51dbc9772e9 100644 --- a/docs/facebookapi/core/app-events/automatic-logging/index.html +++ b/docs/facebookapi/core/app-events/automatic-logging/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Automatic Logging

When you use the Facebook SDK, certain events in your app are automatically logged and collected for Facebook Analytics unless you disable automatic event logging. These events are relevant for all use cases - targeting, measurement and optimization.

Disable Automatically Logged Events

To disable automatic logging you must add certain fields to the manifest and info additions in your application descriptor.

This value is set by configuration parameters in your project configuration. You most likely set this value initially when you ran through the extension configuration, but this will allow you to change it easily.

apm project config set facebookAutoLogAppEventsEnabled true

Once you have added this configuration run the steps to update / generate your application descriptor. This will apply to both iOS and Android.

In some cases, you want to only delay the collection of automatically logged events, such as to obtain User consent or fulfill legal obligations. In this case disable the automatic logging as above and then once you have been provided consent call the setAutoLogAppEventsEnabled() function:

Facebook.instance.setAutoLogAppEventsEnabled( true );

Similarly to suspend collection again for any reasons:

Facebook.instance.setAutoLogAppEventsEnabled( false );

Disable Collection of Advertiser IDs

To disable collection of the advertiser id, you must add certain fields to the manifest and info additions in your application descriptor.

This value is set by configuration parameters in your project configuration. You most likely set this value initially when you ran through the extension configuration, but this will allow you to change it easily.

apm project config set facebookAdvertiserIDCollectionEnabled true

Once you have added this configuration run the steps to update / generate your application descriptor.

In some cases, you want to delay the collection of the advertiser id, such as to obtain User consent or fulfill legal obligations, instead of disabling it. In this case disable the collection of the advertiser id as above and then once you have been provided consent call the setAdvertiserIDCollectionEnabled function:

Facebook.instance.setAdvertiserIDCollectionEnabled( true );

Similarly to suspend collection again for any reasons:

Facebook.instance.setAdvertiserIDCollectionEnabled( false );
- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-events/logging/index.html b/docs/facebookapi/core/app-events/logging/index.html index 3573f36f2cf..1062d2b1312 100644 --- a/docs/facebookapi/core/app-events/logging/index.html +++ b/docs/facebookapi/core/app-events/logging/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ When reported, all of the valueToSum properties will be summed together. For example, if 10 people each purchased one item that cost $10 (and passed in valueToSum) then they would be summed to report a number of $100.

The parameters are set in the parameters object event.parameters or using the event.setParameter() function. The must be String or Number values.

Note that both the valueToSum and parameters arguments are optional.

The full list of pre-defined events and pre-defined parameters are listed in the AppEventConstants class or in the Facebook documentation.

Custom App Events

You can also choose to create your own custom events, which is done simply by specifying their name as a string:

var event:AppEvent = new AppEvent( "a_custom_event_name" );

Facebook.instance.appEventsLogger.logEvent( event );

The maximum number of different event names is 1,000. Note no new event types will be logged once this cap is hit. However it is possible to deactivate obsolete events.

Read more about event limits in the FAQ.

Purchase Events

You can log purchase events using the logPurchase function.

var event:AppPurchaseEvent = new AppPurchaseEvent( 
79.99,
"USD"
);

Facebook.instance.appEventsLogger.logPurchase( event );

The currency specification is expected to be an ISO 4217 currency code. This is used to determine a uniform value for use in ads optimization.

Further Information

More information can be found in the Facebook documentation

- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-events/overview/index.html b/docs/facebookapi/core/app-events/overview/index.html index 5e1f4d48321..94f99e4371b 100644 --- a/docs/facebookapi/core/app-events/overview/index.html +++ b/docs/facebookapi/core/app-events/overview/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ This analytics channel provides demographic info about the people using your app, offers tools for better understanding the flows people follow in your app, and lets you compare cohorts of different kids of people performing the same actions.

See the documentation for Facebook Analytics for Apps for more information.

iOS App Tracking Transparency

With iOS 14+ you now need to request authorisation to track users. This applies directly to app events and you won't be able to receive them on iOS without having gained this authorisation.

To do so, add the com.distriqt.IDFA extension to your application (it's a free extension). Then request authorisation and inform Facebook as below :

IDFA.service.requestAuthorisation( function( authorisationStatus:String ):void 
{
Facebook.instance.setAdvertiserTrackingEnabled(
authorisationStatus == TrackingAuthorisationStatus.AUTHORISED
);
});

More information on this here.

- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-events/user-properties/index.html b/docs/facebookapi/core/app-events/user-properties/index.html index 079557738ed..29a3edb0c93 100644 --- a/docs/facebookapi/core/app-events/user-properties/index.html +++ b/docs/facebookapi/core/app-events/user-properties/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ allows you to understand user behavior. One of the key features of Facebook Analytics is segments. Segments allow you to better understand your audience by analyzing the behavior and demographics of a group of people that you define.

Many businesses also want to create segments based on other things they know about their customers. For example, an airline might want to create a segment based on values from their customer relationship management (CRM) system, such as frequent flyer status or the year that a customer became a member of their frequent flyer program.

With user properties, businesses can use their own CRM data to understand and analyze behavior. You can create user properties directly in your app or by using our API.

User IDs and user properties can't include any personally identifying information, such as people's names or email addresses.

User ID

By calling the setUserID function, you can assign an ID to a user of your app. For example, you could create a number that associates the user with information you collected when they installed your app. Typically, this is your identifier for the user in your own CRM or other back-end systems. The setUserID function is helpful if you expect to upload data from your app and use the API because it ensures that properties are attributed to the same user.

Facebook.instance.appEventsLogger.setUserID( "user1234" );

The length of the user ID must be less than 100 characters.

When you set a user ID, this ID is stored on the user's device, and is included in app events logged from that device.

Further Information

More information can be found in the Facebook documentation

- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-links/handling-incoming-links/index.html b/docs/facebookapi/core/app-links/handling-incoming-links/index.html index 3680c1c946f..2f2175a3171 100644 --- a/docs/facebookapi/core/app-links/handling-incoming-links/index.html +++ b/docs/facebookapi/core/app-links/handling-incoming-links/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Handling Incoming Links

When someone taps a link posted from your app or taps the app attribution in an Open Graph story posted from your app in Facebook, they may be presented with the option to open your content in your app. Alternatively, they may be immediately directed to your app.

To ensure an engaging user experience, you should process the incoming link when your app is activated and direct the person to the object featured in the story they're coming from.

Your app will receive a link where {url} is the incoming URL based on a custom scheme that you have defined for your app. You'll also receive an al_applink_data query parameter with JSON encoded content.

{url}?al_applink_data=
{
"target_url": "{the-target-url}",
"extras": {
"fb_app_id": {your-fb-app-id},
"fb_access_token": "{your-access-token}]",
"fb_expires_in": "3600"
},
"referer_app_link": {
"url": "{your-fb-app-back-link}",
"app_name": "Facebook"
}
}

Where fb_access_token and fb_expires_in are only available if the person has authenticated with Facebook in your app.

Your application will be notified of App Link openings using the AppLinkEvent.

FacebookCore.instance.appLinks.addEventListener( AppLinkEvent.APP_LINK, appLinkHandler );

When this event is triggered it will contain details on the App Link in the event:

private function appLinkHandler( event:AppLinkEvent ):void 
{
// event.appLink will contain the details on the App Link.
// If null the link could not be processed
if (event.appLink != null)
{
trace(
JSON.stringify(
event.appLink.data
));
}
}

Startup

At startup the extension will check for app links as soon as you initialise the Core extension. You should ensure that you have added the listener for the AppLinkEvent.APP_LINK before calling initialise().

For example:

// Add the listener
Facebook.instance.appLinks.addEventListener( AppLinkEvent.APP_LINK, appLinkHandler );

// Call initialise
Facebook.instance.initialise();


// Handle any links
function appLinkHandler( event:AppLinkEvent ):void
{
trace( "APPLINK: " + event.appLink.dataJSON );
}

After startup, events may be dispatched when your application is activated from a link.

If you wish to return to the application that referred your application you can call the openReferer function and pass in the same App Link that was passed in the event:

FacebookCore.instance.appLinks.openReferer( appLink );

Testing

The easiest way to test, is to copy the url of your app link and create a private "Group" on Facebook with your testers. Post the link into the group and then access the group through the Facebook app on your device.

Clicking the link should open your application.

You can test a link by using the "Deep Link Tester" in the Facebook Ads Helper.

Select your application and go to the "Deep Link Tester" and click "Test Deep Link".

Enter the url for your app eg distriqtTestApp://link and you'll get a notification in your Facebook application.

You must be logged into the Facebook app on your device with your developer account in order for this to work.

- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-links/overview/index.html b/docs/facebookapi/core/app-links/overview/index.html index afaa564213c..6f64eb3445d 100644 --- a/docs/facebookapi/core/app-links/overview/index.html +++ b/docs/facebookapi/core/app-links/overview/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

App Links

App Links is an open omni-channel solution for deep linking to content in your mobile app

Your app can post stories to news feed. When people click on those stories, Facebook can send people to either your app or your app's App Store page. This drives traffic and app installs. You can implement this behavior using App Links.

When someone taps on one of the links shared through your app or on the story attribution (name of your app) in one of the Open Graph stories shared through your app, the link content appears in a webview with a menu item Open in {app name}. Clicking on that menu item will either open your app or, if the your app is not installed on the device, open your app's App Store page. If your app is mobile-only and has no web content, when someone clicks the shared link they either open your app, if it's installed, or go to your app's App Store page (if your app isn't installed). The image below shows this flow:

iOS
Android

In either case, once the person reaches your app (directly or after the app install), information will be passed in an event that can be used by your app to decide what to show the person to provide continuity in the user experience. For example, if I see a story on my Facebook feed about one of my friends completing this share tutorial and I tap on it, I will expect to be redirected to a view in your app that features this tutorial and not to your app's main activity.

Format

The App Links protocol is a cross-platform, open-source protocol for simple mobile deep-linking. App Invites uses App Links to determine which apps to display on install and what URL to pass to your app. Read more about App Links at applinks.org or read Facebook's guide on App Links.

The following is an example of App Link markup.

<html>
<head>
<meta property="al:ios:url" content="customscheme://example" />
<meta property="al:ios:app_store_id" content="12345" />
<meta property="al:ios:app_name" content="your facebook app" />

<meta property="al:android:url" content="customscheme://example" />
<meta property="al:android:package" content="air.com.example.app" />
<meta property="al:android:app_name" content="your facebook app" />

<meta property="al:web:should_fallback" content="false" />

<meta property="og:title" content="facebook applinks test" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://example.com/applink.html" />
<meta property="og:description" content="facebook applinks test" />
<meta property="og:image" content="https://example.com/image.png" />
<meta property="fb:app_id" content="XXXXXXXXXXXXXXX" />

<!-- Other headers -->
</head>
<body>
Facebook AppLink Test
</body>
</html>
</head>

More information here: https://developers.facebook.com/docs/applinks/add-to-content

Note: Facebook AppLinks while described as an "open" protocol really have only been implemented by Facebook. So you shouldn't expect these to work in a normal browser.

Instead you must share the link in Facebook and click on the link in the Facebook app on your device.

- + \ No newline at end of file diff --git a/docs/facebookapi/core/app-links/support/index.html b/docs/facebookapi/core/app-links/support/index.html index 30f39a212d2..a96488a35bd 100644 --- a/docs/facebookapi/core/app-links/support/index.html +++ b/docs/facebookapi/core/app-links/support/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ they will be taken to your app. The URL defined in the App Link will be passed in.

In order to support incoming links you need to add some additions to your application descriptor, that will ensure your application receives the links correctly.

Android

To respond to opening links for your custom URL scheme, add an intent-filter for that specific URL. For example in the following we will add an intent-filter to accept distriqttestapp:// urls.

Firstly add a custom Android configuration file by running:

apm generate config android

Edit the config/android/AndroidManifest.xml file that was generated to resemble the following, adding the activity:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

<application>

<activity>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<!-- This intent filter is for your custom url -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<!-- Accepts URIs "distriqttestapp://" -->
<data android:scheme="distriqttestapp" />
</intent-filter>

</activity>

</application>

</manifest>

Once you have added this configuration run the steps to update / generate your application descriptor.

iOS

You'll need to add a custom url that you will use to open your application. In the following you would be able to open the application using the distriqttestapp:// url.

Firstly add a custom iOS configuration file by running:

apm generate config ios

Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following:

<plist version="1.0">
<dict>

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>distriqttestapp</string>
</array>
</dict>
</array>

</dict>
</plist>

Once you have added this configuration run the steps to update / generate your application descriptor.

- + \ No newline at end of file diff --git a/docs/facebookapi/core/graph-api/basics/index.html b/docs/facebookapi/core/graph-api/basics/index.html index 64f24ca016f..9bb6a15faf6 100644 --- a/docs/facebookapi/core/graph-api/basics/index.html +++ b/docs/facebookapi/core/graph-api/basics/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ users email address. To add a field use the addField or addFields function on the builder:

new GraphRequestBuilder()
.setPath( "/me" )
.addField( "email" )
.build();

Parameters are often additional information passed along with the request, for example a link passed along with a post request. To add a parameter use the addParameter function on the builder:

new GraphRequestBuilder()
.setPath( "/me/feed" )
.setMethod( GraphRequestBuilder.METHOD_POST )
.addParameter( "link", "https://airnativeextensions.com" )
.build();

Image Data

If you wish to add image data to a post you can use the setImage function:

new GraphRequestBuilder()
.setPath( "/me/photos" )
.setMethod( GraphRequestBuilder.METHOD_POST )
.setImage( yourBitmapData )
.addParameter( "message", "Image posted through the Graph API from the Facebook API ANE" )
.build();
- + \ No newline at end of file diff --git a/docs/facebookapi/core/graph-api/batch/index.html b/docs/facebookapi/core/graph-api/batch/index.html index 33a88ccc0e2..fd3a5678c7d 100644 --- a/docs/facebookapi/core/graph-api/batch/index.html +++ b/docs/facebookapi/core/graph-api/batch/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Batch

If you have several requests you wish to batch together you can use the GraphRequestBatchBuilder to create a batch request.

To create a batch, firstly create your GraphRequest instances as normal:

var request1:GraphRequest = new GraphRequestBuilder()
.setPath('/me')
.setMethod('GET')
.addFields(["first_name","gender","picture.width(160).height(160)" ])
.build();

var request2:GraphRequest = new GraphRequestBuilder()
.setPath('/me/friends')
.setMethod('GET')
.addParameter("limit", 200 )
.addFields(["id","first_name","installed","picture.width(160).height(160)" ])
.build();

Then construct the GraphRequestBatch using a GraphRequestBatchBuilder:

var batch:GraphRequestBatch = new GraphRequestBatchBuilder()
.addRequest( request1 )
.addRequest( request2 )
.build();

Then call makeBatchRequest() with your GraphRequestBatch instance:

Facebook.instance.graphAPI.makeBatchRequest( batch );

Events

You can add event listeners to the request objects to process the return data from each individual request, as you would for a single request:

request1.addEventListener( GraphRequestEvent.COMPLETE, request1_completeHandler );
request1.addEventListener( GraphRequestEvent.ERROR, request1_errorHandler );
request2.addEventListener( GraphRequestEvent.COMPLETE, request2_completeHandler );
request2.addEventListener( GraphRequestEvent.ERROR, request2_errorHandler );

function request1_completeHandler( event:GraphRequestEvent ):void
{
// event.data will contain the Facebook response
}

function request1_errorHandler( event:GraphRequestEvent ):void
{
// event.errorCode and event.errorMessage will contain details on the error
}

function request2_completeHandler( event:GraphRequestEvent ):void
{
// event.data will contain the Facebook response
}

function request2_errorHandler( event:GraphRequestEvent ):void
{
// event.errorCode and event.errorMessage will contain details on the error
}

Additionally you can listen for a GraphRequestEvent.BATCH_COMPLETE event to be notified when all the requests have been completed.

batch.addEventListener( GraphRequestEvent.BATCH_COMPLETE, batch_completeHandler );

function batch_completeHandler( event:GraphRequestEvent ):void
{
trace( "batch complete" );
}

You should make sure to add these listeners before the call to makeBatchRequest().

Callbacks

As an alternative to events, you can add callbacks to the requests as you do with a normal GraphRequest:

var request1:GraphRequest = new GraphRequestBuilder()
.setPath( "/me" )
.setCompleteCallback(
function( data:Object ):void
{
log( "request complete: " + JSON.stringify(data) );
}
)
.setErrorCallback(
function( code:int, message:String ):void
{
log( "request error: " + code + "::"+ message );
}
)
.build();

Additionally you can add a completion callback to the GraphRequestBatch object:

var batch:GraphRequestBatch = new GraphRequestBatchBuilder()
.addRequest( request1 )
.addRequest( request2 )
.addRequest( request3 )
.setCompleteCallback(
function():void
{
log( "batch complete" );
}
)
.build();
- + \ No newline at end of file diff --git a/docs/facebookapi/core/graph-api/examples/index.html b/docs/facebookapi/core/graph-api/examples/index.html index b08a1e2c77e..ac8d4c2139c 100644 --- a/docs/facebookapi/core/graph-api/examples/index.html +++ b/docs/facebookapi/core/graph-api/examples/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Examples

Some examples of using the Graph API

Get Current User Info

Requires the "email" permission.

var request:GraphRequest = new GraphRequestBuilder()
.setPath( "/me" )
.addField( "email" )
.addField( "name" )
.build();

Facebook.instance.graphAPI.makeRequest( request );

Get User Permissions

new GraphRequestBuilder()
.setPath( "/me/permissions" )
.build();

Get User Friends

Requires the "user_friends" permission.

var request:GraphRequest = new GraphRequestBuilder()
.setPath( "/me/friends" )
.addField( "name" )
.build();

Post Status Update

Requires the "publish_actions" permission.

new GraphRequestBuilder()
.setPath( "/me/feed" )
.setMethod( METHOD_POST )
.addParameter( "message", message )
.build();

Requires the "publish_actions" permission.

var request:GraphRequest = new GraphRequestBuilder()
.setPath( "/me/feed" )
.setMethod( GraphRequestBuilder.METHOD_POST )
.addParameter( "link", "https://airnativeextensions.com" )
.addParameter( "caption", "Posted through the Graph API from the Facebook API ANE" )
.build();

Facebook.instance.graphAPI.makeRequest( request );

Posting an Image

Requires the "publish_actions" permission.

var request:GraphRequest = new GraphRequestBuilder()
.setPath( "/me/photos" )
.setMethod( GraphRequestBuilder.METHOD_POST )
.setImage( _image.bitmapData )
.addParameter( "message", "Image posted through the Graph API from the Facebook API ANE" )
.build();

Facebook.instance.graphAPI.makeRequest( request );
- + \ No newline at end of file diff --git a/docs/facebookapi/core/graph-api/overview/index.html b/docs/facebookapi/core/graph-api/overview/index.html index b2563d4ff09..4043f94dd5a 100644 --- a/docs/facebookapi/core/graph-api/overview/index.html +++ b/docs/facebookapi/core/graph-api/overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Graph API

The Graph API is the primary way to get data into and out of the Facebook platform. It's an HTTP-based API that apps can use to programmatically query data, post new stories, manage ads, upload photos, and perform a wide variety of other tasks.

The Basics

The Graph API is named after the idea of a 'social graph' - a representation of the information on Facebook composed of:

  • nodes - basically "things" such as a User, a Photo, a Page, a Comment
  • edges - the connections between those "things", such as a Page's Photos, or a Photo's Comments
  • fields - info about those "things", such as a person's birthday, or the name of a Page

Typically you use nodes to get data about a specific object, use edges to get collections of objects on a single object, and use fields to get data about a single object or each object in a collection.

The Graph API is HTTP-based, so it works with any language that has an HTTP library, such as cURL and urllib. We'll explain a bit more about what you can do with this in the section below, but it means you can also use the Graph API directly in your browser, for example a Graph API request is equivalent to:

GET graph.facebook.com
/facebook/picture?
redirect=false

Most Graph API requests require the use of access tokens, which your app can generate by implementing Facebook Login.

The implementation in this extension will help you construct these graph queries, however it will still involve knowledge of the API.

Load the Graph API Explorer

The easiest way to understand the Graph API is to use it with the Graph API Explorer, a low-level tool you can use to query, add and remove data. It's a very handy resource to have at your fingertips while you integrate with Facebook.

So your next step is to go to the Graph API Explorer.

Further Information

- + \ No newline at end of file diff --git a/docs/facebookapi/core/initialise-the-extension/index.html b/docs/facebookapi/core/initialise-the-extension/index.html index f62a68e5c11..d78aed48789 100644 --- a/docs/facebookapi/core/initialise-the-extension/index.html +++ b/docs/facebookapi/core/initialise-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Initialise the Extension

Core Extension

You must call Core.init(); once in your application to initialise the extension and correctly add application delegation handling.

Note you should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

Core.init();
if (Facebook.isSupported)
{
// Functionality here
}

Initialise the Facebook Application

To initialise the Facebook SDK call the initialise() function. You must do this before attempting to use any of the functionality in the Facebook Platform SDKs.

Facebook.instance.initialise();

If you plan to gather permission to track the user or other such consent you should do this before calling initialise().

Automatic initialisation

danger

Previously you may have relied on the Facebook Platform SDKs automatically initialising on launch. Starting with v9 Facebook has removed this auto-initialisation feature.

If you currently rely on the Facebook Platform SDKs being automatically initialized for use, you will now need to explicitly initialize the SDK by making the appropriate calls.

To produce consistent results we suggest you ensure you have disabled automatic initialisation in your application by setting set the AutoInitEnabled flag to false in the application descriptor. These flags should be ignored however it appears Android may still auto initialise in some cases.

This is the default value used by apm, but you can change it through your project configuration.

apm project config set facebookAutoInitEnabled false

Once you have added this configuration run the steps to update / generate your application descriptor. This will apply to both iOS and Android.

- + \ No newline at end of file diff --git a/docs/facebookapi/core/overview/index.html b/docs/facebookapi/core/overview/index.html index fba4a541328..4342b093673 100644 --- a/docs/facebookapi/core/overview/index.html +++ b/docs/facebookapi/core/overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Core

Facebook Core library provides the core components of the Facebook SDK including:

  • Analytics through App Events
  • Graph API
  • App Links

It is required for all other components of the Facebook SDK and must be added to your project to start.

- + \ No newline at end of file diff --git a/docs/facebookapi/gamingservices/add-the-extension/index.html b/docs/facebookapi/gamingservices/add-the-extension/index.html index c0c257c84be..1a9424dedb2 100644 --- a/docs/facebookapi/gamingservices/add-the-extension/index.html +++ b/docs/facebookapi/gamingservices/add-the-extension/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.facebook.GamingServices

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ assets
| |____ ios
| | |____ Frameworks
| | | |____ [dynamic frameworks]
|____ ane
| |____ com.distriqt.facebook.GamingServices.ane # Facebook Gaming Services extension
| |____ com.distriqt.facebook.Core.ane # Facebook Core extension
| |____ com.distriqt.facebook.Login.ane # Facebook Login extension
| |____ com.distriqt.facebook.Share.ane # Facebook Share extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

  • You will have an assets directory that contains required assets for the installed extensions. You must add the assets/ios folder to the root of your iOS application package. (The ios folder contains a Frameworks folder with the required iOS dynamic frameworks).

info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set some configuration items such as the Facebook application identifier. If you installed com.distriqt.facebook.Core already you would have set these configuration values then. If not, call the following to step through the configuration values:
apm project config set com.distriqt.facebook.Core

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/facebookapi/gamingservices/friend-finder-dialog/index.html b/docs/facebookapi/gamingservices/friend-finder-dialog/index.html index 29ae29c53da..850736f0534 100644 --- a/docs/facebookapi/gamingservices/friend-finder-dialog/index.html +++ b/docs/facebookapi/gamingservices/friend-finder-dialog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Friend Finder Dialog

Expand your player base and build community by connecting your players with their Facebook friends. Player Finder lets users find friends to share their gaming experience with. Having more friends playing is associated with higher retention for new players playing top social and turn-based games.

Player Finder connects people with their friends who are playing the same game. Unlike the user/friends Graph API which requires an App with user_friends permission, Player Finder does not require this permission; the connections are rendered as a Player Finder Dialog surfaced within the Facebook App.

Player Finder expands beyond players' social graph of direct Facebook friends, letting players connect with people with similar interests through groups.

Implementation

A typical use of the Player Finder Dialog is as follows:

  • Provide a button to open our Player Finder deeplink URL in your app to App Switch to Facebook
  • User selects people they want to invite or sees group to connect with.
  • Users will be redirected back to your app via App switch from Facebook upon closing the Player Finder Dialog

There is no other work needed other than ensuring that your application settings make app switching back to your app works properly and invoking the deep link.

Show

In order to show the friend finder dialog simply call the show() function at the appropriate time in your application:

FacebookGamingServices.instance.friendFinderDialog.show();

The extension will dispatch an event based on the response from the dialog:

  • FriendFinderDialogEvent.COMPLETE: Dispatched when the dialog was closed and the user completed the process;
  • FriendFinderDialogEvent.CANCEL: Dispatched if the dialog was cancelled by the user;
  • FriendFinderDialogEvent.ERROR: Dispatched if there was an error, the errorMessage of the event will contain more details;
FacebookGamingServices.instance.friendFinderDialog.addEventListener( FriendFinderDialogEvent.COMPLETE, completeHandler );
FacebookGamingServices.instance.friendFinderDialog.addEventListener( FriendFinderDialogEvent.CANCEL, cancelHandler );
FacebookGamingServices.instance.friendFinderDialog.addEventListener( FriendFinderDialogEvent.ERROR, errorHandler );


function completeHandler( event:FriendFinderDialogEvent ):void
{
trace( "completeHandler()" );
}

function cancelHandler( event:FriendFinderDialogEvent ):void
{
trace( "cancelHandler()" );
}

function errorHandler( event:FriendFinderDialogEvent ):void
{
trace( "errorHandler() " + event.errorMessage );
}
- + \ No newline at end of file diff --git a/docs/facebookapi/gamingservices/game-request-dialog/index.html b/docs/facebookapi/gamingservices/game-request-dialog/index.html index 526a238c4de..48fc9b182f8 100644 --- a/docs/facebookapi/gamingservices/game-request-dialog/index.html +++ b/docs/facebookapi/gamingservices/game-request-dialog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Game Request Dialog

Game requests give players a mechanism for inviting their friends to play a game. Requests are sent by a player to one or more friends, and always carry a call-to-action for the game. Recipients can be existing players or new players.

Game requests can be used to attract new players or to re-engage existing players. Requests can be sent in two scenarios:

  1. The recipient is a friend of the sender and has not authenticated the game. This scenario is useful for invites.
  2. The recipient is a friend of the sender and has authenticated the game before. This scenario is useful for turn-based notifications and asking for help.

Requests are sent while the sender is in-game and are surfaced to recipients in several places on Facebook. Requests are always private, and can only be seen by the recipient. While a single request can be sent to multiple recipients at once, the receiver of a request only ever sees details of the sender, and can never see either other recipients of the request.

An example Game Request surfaced on Facebook for Desktop.

Show

In order to show the game request dialog you must first create a content object that is used to populate the request. You will use the GameRequestContentBuilder class to build your content, for example:

var builder:GameRequestContentBuilder = new GameRequestContentBuilder()
.setMessage( "Come play this game with me" );

You must at least specify the message.

You can also specify other content with the builder such as specific recipients if you have used the graph api to get user ids.

var builder:GameRequestContentBuilder = new GameRequestContentBuilder()
.setMessage( "Come play this game with me" )
.setRecipients( [ "user_id_1", "user_id_2" ] );

Once you have your content simply call the show() function at the appropriate time in your application with the content:

FacebookGamingServices.instance.gameRequestDialog.show( builder.build() );

The extension will dispatch an event based on the response from the dialog:

  • GameRequestDialogEvent.COMPLETE: Dispatched when the dialog was closed and the user completed the process;
  • GameRequestDialogEvent.CANCEL: Dispatched if the dialog was cancelled by the user;
  • GameRequestDialogEvent.ERROR: Dispatched if there was an error, the errorMessage of the event will contain more details;
FacebookGamingServices.instance.gameRequestDialog.addEventListener( GameRequestDialogEvent.COMPLETE, completeHandler );
FacebookGamingServices.instance.gameRequestDialog.addEventListener( GameRequestDialogEvent.CANCEL, cancelHandler );
FacebookGamingServices.instance.gameRequestDialog.addEventListener( GameRequestDialogEvent.ERROR, errorHandler );


function completeHandler( event:GameRequestDialogEvent ):void
{
trace( "completeHandler()" );
}

function cancelHandler( event:GameRequestDialogEvent ):void
{
trace( "cancelHandler()" );
}

function errorHandler( event:GameRequestDialogEvent ):void
{
trace( "errorHandler() " + event.errorMessage );
}
- + \ No newline at end of file diff --git a/docs/facebookapi/gamingservices/overview/index.html b/docs/facebookapi/gamingservices/overview/index.html index 5ae114c8b9b..53de4d743db 100644 --- a/docs/facebookapi/gamingservices/overview/index.html +++ b/docs/facebookapi/gamingservices/overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Gaming Services

Facebook Gaming Services allow game developers to utilize Facebook’s large social audience via the Facebook Login for Gaming, which enables engagement and promotes social features, such as Player Finder, Sharing for Gaming, and Gaming Activity, connecting games to Facebook’s ecosystem. By building game communities, organic player acquisition, engagement and retention increases.

Your application needs to enroll in Gaming Services to access features in this section. Follow the instructions to enroll your application.

For more information see the Facebook Gaming Services documentation

Functionality

Currently this supports:

Login

You will login using the Login extension as normal however you need to specify the gaming_profile eg:

FacebookLogin.instance.logInWithReadPermissions( [ "gaming_profile", "email" ] );
- + \ No newline at end of file diff --git a/docs/facebookapi/get-started/index.html b/docs/facebookapi/get-started/index.html index 9f457f884e1..0bd6a78af69 100644 --- a/docs/facebookapi/get-started/index.html +++ b/docs/facebookapi/get-started/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ Android settings key hash fields.

The alias parameter is usually 1, however this may not always be the case. In order to verify that, you can run the following command, again replacing CERTIFICATE.p12:

keytool -v -list -keystore CERTIFICATE.p12 -storetype pkcs12

Which will output some information about the certificate, including a value called Alias name. This is the alias parameter that's required.

- + \ No newline at end of file diff --git a/docs/facebookapi/index.html b/docs/facebookapi/index.html index 900a3186b84..aa7bf7a10c1 100644 --- a/docs/facebookapi/index.html +++ b/docs/facebookapi/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

FacebookAPI

The FacebookAPI is a series of extensions that allow you to connect users with Facebook and utilise the Facebook SDK features including analytics, login and sharing.

Migrating

If you are migrating from version 7 or lower have a look over the migration guide

Legacy Documentation

If you are looking for the documentation on the legacy implementation (version 7) you can find that here

Features

The Facebook SDK consists of several components:

 +---------------+---------------+--------------+----------------+
| Login | Share | Places | Marketing |
| + Core | + Core | + Core | + Core |
| iOS : 1.8 MB | iOS : 2.3 MB | iOS : 2.6 MB | iOS : 1.8 MB |
| And : 246 KB | And : 247 KB | And : 53 KB | And : 67 KB |
+---------------+---------------+--------------+----------------+
| Core |
| iOS : 1.6 MB |
| Android : 52 K |
+---------------------------------------------------------------+

If you don't need the functionality of the full SDK, you can save space by using only the SDK(s) you need to support the Facebook products you want to use in your app.

Note that when you use one of the Facebook SDKs, events in your app are automatically logged and collected for Facebook Analytics unless you disable automatic event logging. For details about what information is collected and how to disable automatic event logging, see Automatic App Event Logging.

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

This site forms the best source of detailed documentation for the extension along with the asdocs

GET STARTED NOW

- + \ No newline at end of file diff --git a/docs/facebookapi/login/access-token/index.html b/docs/facebookapi/login/access-token/index.html index c77d36f2ea3..8d093723667 100644 --- a/docs/facebookapi/login/access-token/index.html +++ b/docs/facebookapi/login/access-token/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Access Token

When someone connects with an app using Facebook Login, the app will be able to obtain an access token which provides temporary, secure access to Facebook APIs.

An access token is an opaque string that identifies a user, app, or Page and can be used by the app to make graph API calls.

The token includes information about when the token will expire and which app generated the token. Because of privacy checks, the majority of API calls on Facebook need to include an access token.

Although each platform generates access tokens through different APIs, all platforms follow the basic strategy to get a user token:

The users Access Token is represented by the AccessToken class.

Tokens are Portable

One important aspect to understand about access token is that they are portable. Once you have an access token you can use it to make calls from a mobile client, a web browser, or from your server to Facebook's servers. If a token is obtained on a client, you can ship that token down to your server and use it in server-to-server calls. If a token is obtained via a server call, you can also ship that token up to a client and then make the calls from the client.

Moving tokens between your client and server must be done securely over HTTPS to ensure the security of people's accounts. Read more about the implications of moving tokens between your clients and your server.

Access Token class

The AccessToken class represents a user's access token.

You will have access to this after a user is successfully logged in through the getAccessToken() function:

var token:AccessToken = FacebookLogin.instance.getAccessToken();

You will need the token String for any calls to the Facebook APIs.

Permissions

You can access the list of granted and denied permissions through the access token.

  • token.permissions: contains an array of permissions strings that this access token has been granted
  • token.declinedPermissions: contains an array of permissions strings that this access token has been denied

Access Token Changes

The access token can be updated over time, such as when the SDK refreshes a token with a longer expiration date. You can respond to changes in the access token by listening for the FacebookAccessTokenEvent.CHANGED event. This event will be dispatched whenever the access token changes and contains the new access token in the accessToken property.

FacebookLogin.instance.addEventListener( FacebookAccessTokenEvent.CHANGED, accessTokenChangedHandler );

function accessTokenChangedHandler( event:FacebookAccessTokenEvent ):void
{
// Update access token
trace( event.accessToken.token )
}
- + \ No newline at end of file diff --git a/docs/facebookapi/login/add-the-extension/index.html b/docs/facebookapi/login/add-the-extension/index.html index b25f457f32a..2c9f7c35933 100644 --- a/docs/facebookapi/login/add-the-extension/index.html +++ b/docs/facebookapi/login/add-the-extension/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.facebook.Login

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ assets
| |____ ios
| | |____ Frameworks
| | | |____ [dynamic frameworks]
|____ ane
| |____ com.distriqt.facebook.Login.ane # Facebook Login extension
| |____ com.distriqt.facebook.Core.ane # Facebook Core extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

  • You will have an assets directory that contains required assets for the installed extensions. You must add the assets/ios folder to the root of your iOS application package. (The ios folder contains a Frameworks folder with the required iOS dynamic frameworks).

info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set some configuration items such as the Facebook application identifier. If you installed com.distriqt.facebook.Core already you would have set these configuration values then. If not, call the following to step through the configuration values:
apm project config set com.distriqt.facebook.Core

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/facebookapi/login/facebook-login/index.html b/docs/facebookapi/login/facebook-login/index.html index abedb031975..5027f86d902 100644 --- a/docs/facebookapi/login/facebook-login/index.html +++ b/docs/facebookapi/login/facebook-login/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Facebook Login

In order to log a user in you will be calling the logInWithConfiguration() function and awaiting a login event. This function takes a LoginConfiguration instance as the parameter. The LoginConfiguration allows you to specify the required configuration for the login request, including permissions and login tracking.

The simplest version just specifies the array of permissions:

if (FacebookLogin.isSupported)
{
FacebookLogin.instance.logInWithConfiguration(
new LoginConfiguration( [ "public_profile", "email" ] )
);
}

For the prefined permissions you can see the constants defined in the FacebookPermissions class.

As of April 24,2018, the pubish_actions permission has been removed. Please see the Breaking Changes Changelog for more details. To provide a way for your app users to share content to Facebook, you should use Facebook's Sharing products instead.

Events

After calling logInWithConfiguration() one of the following events will be dispatched:

  • FacebookLoginEvent.SUCCESS: The login was successful and the user is now logged in;
  • FacebookLoginEvent.CANCEL: The user cancelled the login process;
  • FacebookLoginErrorEvent.ERROR: There was an error during login, check the event properties for details.

When the user is successully logged in you will have access to the access token and to the requested user details (profile, email etc).

The FacebookLoginEvent class on success contains:

  • accessToken: An instance of AccessToken containing details about the token
  • profile: An instance of Profile containing details about the current user
  • authToken: An instance of AuthenticationToken containing details about the login request

The profile may be null if the profile information hasn't been retrieved or requested yet. Both will be null for a cancel event. The accessToken may be null if you have specified a limited tracking login.

For example:

FacebookLogin.instance.addEventListener( FacebookLoginEvent.SUCCESS, successHandler );
FacebookLogin.instance.addEventListener( FacebookLoginEvent.CANCEL, cancelHandler );
FacebookLogin.instance.addEventListener( FacebookLoginErrorEvent.ERROR, errorHandler );

FacebookLogin.instance.logInWithReadPermissions( [ "public_profile", "email" ] );


function successHandler( event:FacebookLoginEvent ):void
{
trace( "successHandler()" );
// You can now access the user
}

function cancelHandler( event:FacebookLoginEvent ):void
{
trace( "cancelHandler()" );
}

function errorHandler( event:FacebookLoginErrorEvent ):void
{
trace( "errorHandler() code : " + event.errorID );
trace( "errorHandler() message : " + event.text );
}

Existing Login

You can check if your user is already logged in by calling the isLoggedIn() function. This will return true if your user is already logged in.

if (FacebookLogin.instance.isLoggedIn())
{
// User logged in
}

You can also check for a valid access token, as this will only be available if the user is logged in:

var accessToken:AccessToken = FacebookLogin.instance.getAccessToken();
if (accessToken != null)
{
// User logged in
}

Logout

To logout the current user call the logout() function.

FacebookLogin.instance.logout();

Permissions

When a person logs into your app via Facebook Login you can access a subset of that person's data stored on Facebook. Permissions are how you ask someone if you can access that data. A person's privacy settings combined with what you ask for will determine what you can access.

Permissions are strings that are passed along with a login request or an API call. Here are two examples of permissions:

  • email - Access to a person's primary email address.
  • user_likes - Access to the list of things a person likes.

You can get the list of granted and denied permissions at any time by using the current AccessToken.

When to ask for Permissions

During basic login, your app receives access to a person's public profile. To access additional profile information or to publish content to Facebook on their behalf, you need to request additional permissions, see Permissions with Facebook Login.

Your app should manage permissions as follows:

  • Graph API Requests - Before you send Graph API requests, you should check for necessary permissions and request them if needed.

  • Missing and Revoked Permissions - Your app needs to deal with missing or revoked permissions errors from Facebook such as by asking for permissions and retrying. See Error-Handling, iOS SDK.

  • Timing Requests - You will get better conversion if you ask for permissions only when they are needed and provide functionality without requiring all permissions.

Permissions only need to be granted once per app, i.e. permissions granted on one platform are effectively granted on all the platforms your app supports.

Revoked Permissions

People can also revoke permissions granted to your app in Facebook's interface at any time after they have logged in. It is important that your app regularly checks which permissions have been granted, especially when launching on a new platform. We provide methods for you to check what permissions are currently granted to your app.

Request More Permissions

Use FacebookLogin to request additional permissions or request previously declined permissions using the same logInWithReadPermission() method. The SDK will see it's a re-request by the availability of the permissions in the current access token.

Profile

Once the user is logged in you can get the user's details through the Profile (assuming you requested profile read permissions).

var profile:Profile = FacebookLogin.instance.getProfile();
if (profile != null)
{
trace( profile.name );
}

The Profile contains information about the user such as firstName, lastName, and pictureUrl.

Profile Changes

If you need to respond to changes in the user profile during the application session you can listen for the FacebookProfileEvent.CHANGED event. This event will be dispatched whenever the profile is updated.

FacebookLogin.instance.addEventListener( FacebookProfileEvent.CHANGED, profileChangedHandler );

function profileChangedHandler( event:FacebookProfileEvent ):void
{
// Update profile information
}

This can also be useful during certain login scenarios where the profile may not be loaded initially but updated shortly after login.

Limited Login

Limited Login offers a login path that implements steps designed to prevent the fact that a person used Facebook to log in to your app from being used to target advertising or measure advertising effectiveness.

Limited Login returns an AuthenticationToken that wraps an OpenID Connect token. The ID token cannot be used to request additional data using the Graph API, such as friends, photos, or pages. Doing so requires the use of classic Facebook Login.

A successful login populates a global AuthenticationToken instance. You can provide a nonce for the login attempt that will be reflected in the return token. In addition, Limited Login populates a shared profile instance that contains the basic information including ID, name, profile picture, and email (if granted by the user).

To use a limited login you must set the login tracking to be LoginTracking.LIMITED in the LoginConfiguration instance when attempting login. (You will likely want to set a nonce value that you can use to validate the login serverside.)

var configuration:LoginConfiguration = new LoginConfiguration( [ "public_profile", "email" ] );

configuration.setLoginTracking( LoginTracking.LIMITED );
configuration.setNonce("123");


FacebookLogin.instance.logInWithConfiguration( configuration );

To retrieve the authentication token (OIDC token) you can call the getAuthenticationToken() function:

var token:AuthenticationToken = FacebookLogin.instance.getAuthenticationToken();

trace( token.token );
trace( token.nonce );
- + \ No newline at end of file diff --git a/docs/facebookapi/login/overview/index.html b/docs/facebookapi/login/overview/index.html index 700679b2273..a47db2bd6ff 100644 --- a/docs/facebookapi/login/overview/index.html +++ b/docs/facebookapi/login/overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Login

Facebook Login is a secure, fast and convenient way for people to log into your app .

Facebook Login for Apps is a fast and convenient way for people to create accounts and log into your app across multiple platforms. It's available on iOS, Android, Web, Windows Phone, desktop apps and devices such as Smart TVs and Internet of Things objects.

When people log into your app with Facebook they can grant permissions to your app so you can retrieve information or perform actions on Facebook on their behalf.

If people don't have the Facebook app installed, Facebook Login uses Facebook Lite instead to display the login screen and get credentials. Previous SDKs required that people have the Facebook app installed.

For more information see the Facebook Login documentation

- + \ No newline at end of file diff --git a/docs/facebookapi/migrating-to-androidx/index.html b/docs/facebookapi/migrating-to-androidx/index.html index 477607a3be3..4e9621e5816 100644 --- a/docs/facebookapi/migrating-to-androidx/index.html +++ b/docs/facebookapi/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/facebookapi/migrating-to-version-10/index.html b/docs/facebookapi/migrating-to-version-10/index.html index 2ddd2c54c50..bc3219b09e3 100644 --- a/docs/facebookapi/migrating-to-version-10/index.html +++ b/docs/facebookapi/migrating-to-version-10/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to Version 10

Version 10 of the FacebookAPI brings a major update to version 13 of the Facebook SDK.

This update also brings the Facebook API extension inline with the latest androidx libraries and support for Android 12 (API 31).

Client Token

There is a new configuration item required called the "client token". It is required for making certain graph queries and will cause the extension to fail if you do not add this new configuration item.

We are highly recommending using apm to manage updates now. This simplifies the process greatly as you no longer need to manage your manifest additions.

apm update
apm project config set com.distriqt.facebook.Core
apm generate app-descriptor src/MyApp-app.xml

Manual

If you are manually updating, then you will need to firstly ensure you have all the latest dependencies:

<extensionID>androidx.appcompat</extensionID>
<extensionID>androidx.browser</extensionID>
<extensionID>androidx.cardview</extensionID>
<extensionID>androidx.core</extensionID>
<extensionID>androidx.emoji2</extensionID>
<extensionID>androidx.vectordrawable</extensionID>
<extensionID>com.android.installreferrer</extensionID>
<extensionID>com.jetbrains.kotlin</extensionID>

Note there are additional dependencies from previous versions.

Then update your manifest additions to include the latest additions. These include new queries tag and several changes around the android:exported tag. Check the documentation on adding the extension for the latest information.

Make sure you add the client token configuration items too. Both to your info additions on iOS and to your manifest additions on Android.

iOS:

<key>FacebookClientToken</key>
<string>FACEBOOK_CLIENT_TOKEN</string>

Android:

<meta-data android:name="com.facebook.sdk.ClientToken" android:value="FACEBOOK_CLIENT_TOKEN"/>
- + \ No newline at end of file diff --git a/docs/facebookapi/migrating-to-version-8/index.html b/docs/facebookapi/migrating-to-version-8/index.html index b87fa79bbf2..326545cbdb4 100644 --- a/docs/facebookapi/migrating-to-version-8/index.html +++ b/docs/facebookapi/migrating-to-version-8/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to Version 8

Version 8 of the FacebookAPI brings a complete rewrite and restructure of the API to bring it inline with the latest Facebook SDK and to remove a series of API elements that Facebook have deprecated and removed over time.

During this redevelopment we have broken the extension up into several extensions each representing a component of the Facebook SDK.

  • Core: contains the base SDK including analytics, events, app links and the graph API;
  • Login: contains the login SDK allowing you to sign in users using their Facebook credentials;
  • Share: contains the share SDK allowing your users to share content;

This allows you to only add the components that you require in your application allowing you to reduce the size of your application.

Migrating from a previous version of the ANE will involve some major changes to your code. Below we will outline some of the major changes and how to address them.

While this guide covers the key points on migrating, we do highly recommend considering re-implementing the extensions from the start, due to the number of changes.

Change extensions

Firstly you should remove the com.distriqt.FacebookAPI extension from your application.

Then add the 3 new Facebook extensions:

  • com.distriqt.facebook.Core
  • com.distriqt.facebook.Login
  • com.distriqt.facebook.Share

Your extensions node should now contain:

<extensions>
<extensionID>com.distriqt.facebook.Core</extensionID>
<extensionID>com.distriqt.facebook.Login</extensionID>
<extensionID>com.distriqt.facebook.Share</extensionID>

<extensionID>com.distriqt.Core</extensionID>
<extensionID>com.distriqt.Bolts</extensionID>

<extensionID>androidx.core</extensionID>
<extensionID>androidx.appcompat</extensionID>
<extensionID>androidx.browser</extensionID>
<extensionID>androidx.cardview</extensionID>
<extensionID>androidx.vectordrawable</extensionID>
<extensionID>com.android.installreferrer</extensionID>
</extensions>

Application Descriptor

We suggest removing all your manifest additions and info additions and checking the add the extension guide to ensure you have the latest.

Note there is a small additional manifest entry for the Share extension here

Imports

Remove any imports from the com.distriqt.extension.facebookapi package. All the imports now are in the com.distriqt.extension.facebook package, eg:

import com.distriqt.extension.facebook.core.Facebook;

Initialisation

Previously you would have called initialiseApp() as below:

FacebookAPI.service.initialiseApp( "YOUR_FACEBOOK_APP_ID" );

Change this to:

Facebook.instance.initialise();

More on initialisation here

App Events

Key points:

  • Class rename: FacebookAppEvent -> AppEvent
  • FacebookAPI.service.appEvents.logEvent() -> Facebook.instance.appEventsLogger.logEvent()

For example the following legacy code:

var event:FacebookAppEvent = new FacebookAppEvent( AppEventsConstants.EVENT_NAME_ADDED_TO_CART );
event.valueToSum = 54.23;

event.setParameter( AppEventsConstants.EVENT_PARAM_CURRENCY, "USD" );
event.setParameter( AppEventsConstants.EVENT_PARAM_CONTENT_TYPE, "product" );
event.setParameter( AppEventsConstants.EVENT_PARAM_CONTENT_ID, "HDFU-8452" );


FacebookAPI.service.appEvents.logEvent( event );

becomes:

var event:AppEvent = 
new AppEvent()
.setEventName( AppEventsConstants.EVENT_NAME_ADDED_TO_CART )
.setValueToSum( 54.23 )
.setParameter( AppEventsConstants.EVENT_PARAM_CURRENCY, "USD" )
.setParameter( AppEventsConstants.EVENT_PARAM_CONTENT_TYPE, "product" )
.setParameter( AppEventsConstants.EVENT_PARAM_CONTENT_ID, "HDFU-8452" )
;

Facebook.instance.appEventsLogger.logEvent( event );

More on app events here

Graph API

The graph API remains fairly similar:

  • Package move: com.distriqt.extension.facebookapi.graphapi -> com.distriqt.extension.facebook.graphapi
  • Class rename: GraphAPIRequest -> GraphRequest
  • Class rename: GraphAPIRequestBuilder -> GraphRequestBuilder
  • FacebookAPI.service.graphAPI.makeRequest() -> Facebook.instance.graphAPI.makeRequest()

For example the following legacy code:

var request:GraphAPIRequest = new GraphAPIRequestBuilder()
.setPath( "/me" )
.build();

FacebookAPI.service.graphAPI.makeRequest( request );

becomes:

var request:GraphRequest = new GraphRequestBuilder()
.setPath( "/me" )
.build();

Facebook.instance.graphAPI.makeRequest( request );

More on the graph API here

Login

To login you would have called createSession():

FacebookAPI.service.createSession( [ "public_profile", "email" ], true );

This becomes:

FacebookLogin.instance.logInWithReadPermissions( [ "public_profile", "email" ] );

There are no longer a series of session events to handle, so you can remove any code handling FacebookAPISessionEvents and replace with a couple of simple FacebookLoginEvent/FacebookLoginErrorEvent events:

FacebookLogin.instance.addEventListener( FacebookLoginEvent.SUCCESS, successHandler );
FacebookLogin.instance.addEventListener( FacebookLoginEvent.CANCEL, cancelHandler );
FacebookLogin.instance.addEventListener( FacebookLoginErrorEvent.ERROR, errorHandler );

FacebookLogin.instance.logInWithReadPermissions( [ "public_profile", "email" ] );


function successHandler( event:FacebookLoginEvent ):void
{
trace( "successHandler()" );
// You can now access the user
}

function cancelHandler( event:FacebookLoginEvent ):void
{
trace( "cancelHandler()" );
}

function errorHandler( event:FacebookLoginErrorEvent ):void
{
trace( "errorHandler() code : " + event.errorID );
trace( "errorHandler() message : " + event.text );
}

More on the login process here

Share Dialog

Sharing through the Facebook SDK has changed dramatically over the past few years.

You basically only have access to the Share dialog now and a smaller set of content builders (with open graph stories being removed).

The share dialog show has moved, so:

FacebookAPI.service.shareDialog.show( builder.build() );

becomes:

FacebookShare.instance.shareDialog.show( builder.build() );

More on the share dialog here

- + \ No newline at end of file diff --git a/docs/facebookapi/migrating-to-version-9/index.html b/docs/facebookapi/migrating-to-version-9/index.html index daafbeb1edb..e11e4bb8ad7 100644 --- a/docs/facebookapi/migrating-to-version-9/index.html +++ b/docs/facebookapi/migrating-to-version-9/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to Version 9

Version 9 of the FacebookAPI brings a major internal update to the iOS SDK.

This new version of Facebook Login supports two distinct modes: Limited and Classic. Your app will pass Facebook a flag indicating the mode you have chosen for each of your users.

  1. Limited Login mode implements safeguards designed to prevent the fact that a person used Facebook to log into your iOS app from being used to target advertising or measure advertising effectiveness. The mode is based on the OpenID Connect standard and allows users to create new accounts or access existing accounts on your app while only sharing their name, profile pic, and (optionally) email address. Note that Limited Login mode utilizes a JSON Web Token, which does not support Graph API queries.

  2. Classic Login mode remains unchanged from the login product you and your users already know and love. It allows users to create new accounts or access existing accounts while granting your app the ability to access (with Facebook approval and user consent) certain Facebook data intended to improve their experience in your app. Note that Classic Login mode utilizes an oAuth 2.0 Access Token which supports Graph API queries.

You can choose either mode uniformly for all of your users, or choose one of the two modes conditionally.

info

This currently is an iOS only feature. It will be ignored on Android and you will always get the classic implementation with an access token and full tracking enabled.

API Changes

In order to support this new functionality there have been some additions to the API. If you plan to continue supporting classic login you should not need to change anything.

If you do plan to implement limited login, please see the guide on the new login call logInWithConfiguration(), LoginConfiguration class and the AuthenticationToken, in the Facebook Login documentation.

Note: isLoggedIn() will return true irrespective of the login tracking state.

- + \ No newline at end of file diff --git a/docs/facebookapi/share/add-the-extension/index.html b/docs/facebookapi/share/add-the-extension/index.html index 8777d86069e..81cbf3a6268 100644 --- a/docs/facebookapi/share/add-the-extension/index.html +++ b/docs/facebookapi/share/add-the-extension/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.facebook.Share

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ assets
| |____ ios
| | |____ Frameworks
| | | |____ [dynamic frameworks]
|____ ane
| |____ com.distriqt.facebook.Share.ane # Facebook Share extension
| |____ com.distriqt.facebook.Core.ane # Facebook Core extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

  • You will have an assets directory that contains required assets for the installed extensions. You must add the assets/ios folder to the root of your iOS application package. (The ios folder contains a Frameworks folder with the required iOS dynamic frameworks).

info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

  • You will need to set some configuration items such as the Facebook application identifier. If you installed com.distriqt.facebook.Core already you would have set these configuration values then. If not, call the following to step through the configuration values:
apm project config set com.distriqt.facebook.Core

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/facebookapi/share/content/index.html b/docs/facebookapi/share/content/index.html index 06ef415580c..3aa085294f5 100644 --- a/docs/facebookapi/share/content/index.html +++ b/docs/facebookapi/share/content/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Content

People can share the following kinds of content to Facebook:

  • Links - Most content is a URL which references an HTML page. To provide the most relevant information, you should mark up your page with Facebook-specific meta tags. See A Guide to Sharing for Webmasters.

  • Photos - Directly upload one or more user-generated photos.

  • Videos - Directly upload a user-generated video.

  • Multimedia - Directly upload a combination of photos and videos.

Builders

To use the share dialog you firstly create a builder to generate the content for the share dialog. There are different builders each representing a different content type.

When people share links from your app to Facebook it includes a contentURL with the link to be shared. Build your share content for links with the ShareLinkContentBuilder builder.

To share links you will be using the ShareLinkContentBuilder to construct the content.

var builder:ShareLinkContentBuilder = new ShareLinkContentBuilder()
.setContentUrl("https://airnativeextensions.com/extension/com.distriqt.FacebookAPI");

Using this builder you can set all of the appropriate parameters for sharing a link in your application.

Note: If you are looking for old features such as the title, description, caption and image field of ShareLinkContentBuilder have been deprecated as of v 4.22.0 of the Facebook SDK. They have now been removed completely from the SDK.

For a list of all attributes, see ShareLinkContentBuilder reference.

Photos

People can share photos from your app to Facebook with the Share Dialog or with a custom interface.

  • The photos must be less than 12MB in size
  • People need the native Facebook for Android or iOS app installed, version 7.0 or higher

Build your share content for photos with the SharePhotoContentBuilder builder.

To share photos you will be using the SharePhotoContentBuilder to construct the share content.

You can add photos either by:

  • bitmap data using the addBitmap() function
  • local file using the addImageFile() function
var bitmapData:BitmapData = ...;

var builder:SharePhotoContentBuilder = new SharePhotoContentBuilder()
.addBitmap( bitmapData );

Or using addImageFile:

var file:File = ...; // Some image file

var builder:SharePhotoContentBuilder = new SharePhotoContentBuilder()
.addImageFile( file );

For a list of all attributes, see SharePhotoContentBuilder reference.

Videos

People using your app can share videos to Facebook with the Share dialog or with your own custom interface:

  • The videos must be less than 50MB in size.
  • People who share should have Facebook for Android client version 26.0 or iOS client version 7.0 (or higher).

To share videos you will be using the ShareVideoContentBuilder to construct the share content.

var videoFile:File = ...; // Some video file

var builder:ShareVideoContentBuilder = new ShareVideoContentBuilder()
.setVideoFile( videoFile );

For a list of all attributes, see ShareVideoContentBuilder reference.

Media

People using your app can share a combination of photos and videos to Facebook with the Share dialog. Note the following:

  • People need to have Android version 26.0 or iOS version 7.0 or higher.
  • People who share should have Facebook for iOS client installed, version 52.0 or higher.
  • People need the native Facebook for Android app installed, version 71 or higher
  • Photos must be less than 12MB and video must be less than 50MB in size.
  • People can share a maximum of 1 video plus up to 29 photos or 30 photos.

To share media you will be using the ShareMediaContentBuilder to construct the share content.

var videoFile:File = File.applicationStorageDirectory.resolvePath( "assets/video.mp4" );
var image1:Bitmap = ...;
var image2:Bitmap = ...;


var builder:ShareMediaContentBuilder = new ShareMediaContentBuilder()
.addBitmap( image1.bitmapData )
.addBitmap( image2.bitmapData )

.addVideoFile( videoFile )
;

For a list of all attributes, see ShareMediaContentBuilder reference.

- + \ No newline at end of file diff --git a/docs/facebookapi/share/overview/index.html b/docs/facebookapi/share/overview/index.html index 358a8814dc4..764fb22db79 100644 --- a/docs/facebookapi/share/overview/index.html +++ b/docs/facebookapi/share/overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Sharing - Overview

This guide details how to enable sharing from your app to Facebook. When someone shares from your app, their content appears on their Timeline and may appear in their friends' News Feeds.

Share Dialog

The Share Dialog is an easy way to let people share content without having them to log into your app or grant any permissions. It works on web, Android and iOS.

People can share the following kinds of content to Facebook:

  • Links - Most content is a URL which references an HTML page. To provide the most relevant information, you should mark up your page with Facebook-specific meta tags. See A Guide to Sharing for Webmasters.

  • Photos - Directly upload one or more user-generated photos.

  • Videos - Directly upload a user-generated video.

  • Multimedia - Directly upload a combination of photos and videos.

Message Dialog

The message dialog used to be a way to let people privately share content to Messenger. This is no longer supported and you should use native Share methods instead to allow your users to share content to Messenger and other apps.

- + \ No newline at end of file diff --git a/docs/facebookapi/share/share-dialog/index.html b/docs/facebookapi/share/share-dialog/index.html index 4df61f20a76..b1d53b81460 100644 --- a/docs/facebookapi/share/share-dialog/index.html +++ b/docs/facebookapi/share/share-dialog/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Share Dialog

To use the Facebook-built sharing experiences, you want to define your content as in the modeling content section, and then call the Share Dialog.

Show

Once you have created the content builder you then pass the output from this builder to the show function of the ShareDialog interface:

FacebookShare.instance.shareDialog.show( builder.build() );

This initiates the dialog and presents it to the user. You should check the response of this function. It is a boolean value and indicates if the share dialog construction was initiated correctly. If will return false if the required dialog type / content isn't supported or if the application isn't setup correctly.

Can Show

You can check whether a particular share dialog type can be shown by calling the canShow() method and passing the required content type.

For example, to check if the link content share dialog can be shown:

if (FacebookShare.instance.shareDialog.canShow( ShareLinkContentBuilder.TYPE ))
{

}

You can use this process with any of the content builders and their TYPE definition.

Note: this check is performed internally in the show() call as well and will cause show() to return false if canShow() is false. So you can use this check as a check before attempting to show the dialog if you wish to present an alternative.

Events

There are three possible events dispatched after a call to show:

  • ShareDialogEvent.COMPLETE: when the share was successfully completed;
  • ShareDialogEvent.CANCEL: when the user cancelled the share dialog;
  • ShareDialogEvent.ERROR: when an error occurred during the process.
FacebookShare.instance.shareDialog.addEventListener( ShareDialogEvent.COMPLETE, shareDialogEventHandler );
FacebookShare.instance.shareDialog.addEventListener( ShareDialogEvent.CANCEL, shareDialogEventHandler );
FacebookShare.instance.shareDialog.addEventListener( ShareDialogEvent.ERROR, shareDialogEventHandler );

And then your event handler:

function shareDialogEventHandler( event:ShareDialogEvent ):void 
{
}

Notes

Your app should not pre-fill any content to be shared. This is inconsistent with Facebook Platform Policy, see Facebook Platform Policy, 2.3.

Example

The following example shows sharing a link using the share dialog

// Construct content
var content:ShareLinkContentBuilder = new ShareLinkContentBuilder()
.setContentUrl( "https://airnativeextensions.com" );

// Check if can show content
if (FacebookShare.instance.shareDialog.canShow( ShareLinkContentBuilder.TYPE ))
{
FacebookShare.instance.shareDialog.addEventListener(
ShareDialogEvent.COMPLETE, shareDialogEventHandler );
FacebookShare.instance.shareDialog.addEventListener(
ShareDialogEvent.CANCEL, shareDialogEventHandler );
FacebookShare.instance.shareDialog.addEventListener(
ShareDialogEvent.ERROR, shareDialogEventHandler );

// Display share dialog
var success:Boolean = FacebookShare.instance.shareDialog.show(
content.build()
);
}

function shareDialogEventHandler( event:ShareDialogEvent ):void
{
// Handle completion / cancellation / error

FacebookShare.instance.shareDialog.removeEventListener(
ShareDialogEvent.COMPLETE, shareDialogEventHandler );
FacebookShare.instance.shareDialog.removeEventListener(
ShareDialogEvent.CANCEL, shareDialogEventHandler );
FacebookShare.instance.shareDialog.removeEventListener(
ShareDialogEvent.ERROR, shareDialogEventHandler );
}

Additional Features

When you use the Facebook share dialog, you have additional options that aren't available when you share by using the API.

Hashtags

You can specify a single hashtag to appear with a shared photo, link, or video. This hashtag also appears in the Share dialog, and people have the the opportunity to remove it before publishing.

The following is an example of adding a hashtag to a link share.

var content:ShareLinkContentBuilder = new ShareLinkContentBuilder()
.setContentUrl( "https://airnativeextensions.com" )
.setShareHashtag( "#distriqt" )
;

Quote Sharing

You can enable people to highlight text to appear as a quote with a shared link. Alternatively, you can predefine a quote, for example, a pull quote in an article, to appear with the shared link. In either case, the quote appears in its own field separate from the user comments.

var content:ShareLinkContentBuilder = new ShareLinkContentBuilder()
.setContentUrl( "https://airnativeextensions.com" )
.setQuote( "Connect on a global scale." )
;

Advanced Topics

Built-In Share Fallbacks

In past versions of the SDK for Android, your app had to check for a native, installed Facebook app before it could open the Share Dialog. If the person didn't have the app installed, you had to provide your own code to call a fallback dialog.

Now the SDK automatically checks for the native Facebook app. If it isn't installed, the SDK switches people to their default browser and opens the Feed Dialog.

iOS Simulator and Testing

If you are using Simulator to test sharing in your application, you will see errors if you try to share videos or Photos. This is because you need Facebook for iOS installed which provides the Share Dialog. We do not support this for Simulator.

In the case of link shares, you do not need Facebook for iOS installed so this test case is possible. To test other Sharing scenarios, set up an actual test device with with Facebook for iOS installed.

- + \ No newline at end of file diff --git a/docs/facebookapi/signing/index.html b/docs/facebookapi/signing/index.html index 9ba953a5bb7..9753d3cfae4 100644 --- a/docs/facebookapi/signing/index.html +++ b/docs/facebookapi/signing/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

iOS Signing

In some circumstances the AIR SDK doesn't correctly sign all the packaged frameworks in an application.

This will result in an error when attempting an AppStore submission and installing development builds will fail with a signature validation error. Something like:

ERROR: Install failed. Got error "ApplicationVerificationFailed" with code 0xe8008001: Failed to verify code signature of

To get around this, before you upload or install your application you will need to run a script to resign your IPA. This script is available below.

info

This script will only work on a macOS machine with Xcode installed and your certificate installed in Keychain

Copy this script to a directory in your development environment.

Firstly edit the script to change the details of the IPA, provisioning profile and signing identity for your application. These details are located at the top of the script.

Now open a Terminal at the script location. You will need to run the script from this directory.

./resign

This should output a few informational items to the console and then once complete you should have a new IPA file in the directory named: yourApp_resigned.ipa. If there were any errors or warnings displayed, make sure the information above is all correct.

This resigned IPA is the file you should use.

Cause

The cause of this issue has been long standing and we have been in discussions about it with the AIR developers (Adobe and now Harman) for a long time:

Please help us in getting attention to the issue by voting for it here:

Resign Script

#!/bin/bash

#####################################
## CONFIG

# You need to set the values below for your application
# We suggest they are full paths to the files.

# The path to the ipa generated from your AIR application packaging
IPA="/path/to/yourApp.ipa"

# The provisioning profile for your application
PROVISIONING_PROFILE="/path/to/profile.mobileprovision"

# The name of the signing identity. You get this by running the following in a terminal
# and selecting the name of your certificate:
#
# security find-identity -v -p codesigning
SIGNING_IDENTITY="iPhone Distribution: XXXXXXXXX (XXXXX)"

## END CONFIG
#####################################




OUTPUT=.
WORKING_DIR=.tmp
WORKING_PROFILE="profile.mobileprovision"
IPA_NAME=$(basename ${IPA%.*})

cp -f "$PROVISIONING_PROFILE" "$WORKING_PROFILE"

rm -rf "$WORKING_DIR"
unzip -qq -o $IPA -d $WORKING_DIR
find . -iname '$WORKING_DIR/*.DS_Store' -delete

rm -rf "$WORKING_DIR/Payload/$APP_NAME/_CodeSignature/"
rm -f "$WORKING_DIR/Payload/$APP_NAME/embedded.mobileprovision"

APP_NAME=$(ls -1 $WORKING_DIR/Payload)


#####################################
echo "Create Signing Entitlements"
ENTITLEMENTS="$OUTPUT/Entitlements.plist"
rm -f "$ENTITLEMENTS"
WORKING_PROFILE_PLIST="$OUTPUT/$WORKING_PROFILE.plist"
security cms -D -i "$WORKING_PROFILE" > "$WORKING_PROFILE_PLIST"


TEAM_IDENTIFIER=$(/usr/libexec/Plistbuddy -c "Print :TeamIdentifier:0" "$WORKING_PROFILE_PLIST")
APPLICATION_IDENTIFIER_PREFIX=$(/usr/libexec/Plistbuddy -c "Print :ApplicationIdentifierPrefix:0" "$WORKING_PROFILE_PLIST")
BUNDLE_IDENTIFIER=$(/usr/libexec/Plistbuddy -c "Print :CFBundleIdentifier" "$WORKING_DIR/Payload/$APP_NAME/Info.plist")
APS_ENVIRONMENT=$(/usr/libexec/Plistbuddy -c "Print Entitlements:aps-environment" "$WORKING_PROFILE_PLIST")
BETA_REPORTS=$(/usr/libexec/Plistbuddy -c "Print Entitlements:beta-reports-active" "$WORKING_PROFILE_PLIST")
PROVISIONING_GET_TASK_ALLOW=$(/usr/libexec/Plistbuddy -c "Print :Entitlements:get-task-allow" "$WORKING_PROFILE_PLIST")

echo " APP_NAME = $APP_NAME"
echo " TEAM_IDENTIFIER = $TEAM_IDENTIFIER"
echo " APPLICATION_IDENTIFIER_PREFIX = $APPLICATION_IDENTIFIER_PREFIX"
echo " BUNDLE_IDENTIFIER = $BUNDLE_IDENTIFIER"
echo " APS_ENVIRONMENT = $APS_ENVIRONMENT"
echo " BETA_REPORTS = $BETA_REPORTS"
echo " PROVISIONING_GET_TASK_ALLOW = $PROVISIONING_GET_TASK_ALLOW"


/usr/libexec/PlistBuddy -c "Add :application-identifier string $APPLICATION_IDENTIFIER_PREFIX.$BUNDLE_IDENTIFIER" "$ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Add :get-task-allow bool $PROVISIONING_GET_TASK_ALLOW" "$ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Add :keychain-access-groups array" "$ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Add :keychain-access-groups:0 string $APPLICATION_IDENTIFIER_PREFIX.$BUNDLE_IDENTIFIER" "$ENTITLEMENTS"
if [ $APS_ENVIRONMENT ]; then
echo "Setting aps-environment=$APS_ENVIRONMENT"
/usr/libexec/PlistBuddy -c "Add :aps-environment string $APS_ENVIRONMENT" "$ENTITLEMENTS"
fi
if [ $BETA_REPORTS ]; then
echo "Setting beta-reports-active=$BETA_REPORTS"
/usr/libexec/PlistBuddy -c "Add :beta-reports-active bool $BETA_REPORTS" "$ENTITLEMENTS"
fi

# Apple Sign-In
#/usr/libexec/PlistBuddy -c "Add :com.apple.developer.applesignin array" "$ENTITLEMENTS"
#/usr/libexec/PlistBuddy -c "Add :com.apple.developer.applesignin:0 string Default" "$ENTITLEMENTS"

cp "$ENTITLEMENTS" "$WORKING_DIR/Payload/$APP_NAME/archived-expanded-entitlements.xcent"

#####################################
echo "Sign Frameworks"

function sign_framework() {
FRAMEWORK=$1.framework
if [ -d "$WORKING_DIR/Payload/$APP_NAME/Frameworks/$FRAMEWORK" ];
then
codesign --force --sign "$SIGNING_IDENTITY" --verbose "$WORKING_DIR/Payload/$APP_NAME/Frameworks/$FRAMEWORK"
fi
}


sign_framework FBSDKCoreKit
sign_framework FBSDKLoginKit
sign_framework FBSDKShareKit




#####################################
echo "Sign Application"
codesign --force --entitlements "$ENTITLEMENTS" --sign "$SIGNING_IDENTITY" "$WORKING_DIR/Payload/$APP_NAME" --verbose
codesign --verify --verbose --no-strict "$WORKING_DIR/Payload/$APP_NAME"

OUTPUT_IPA="$OUTPUT/"$IPA_NAME"_resigned.ipa"
cd $WORKING_DIR
zip -q --symlinks --recurse-paths "../.tmp_output.ipa" .
cd ..
mv ".tmp_output.ipa" "$OUTPUT_IPA"


# Cleanup
rm -Rf "$WORKING_DIR"
rm -f "$ENTITLEMENTS"
rm -f "$WORKING_PROFILE_PLIST"
rm -f "$WORKING_PROFILE"
- + \ No newline at end of file diff --git a/docs/facebookaudience/changelog/index.html b/docs/facebookaudience/changelog/index.html index 8a6e048935b..d5d1f60c903 100644 --- a/docs/facebookaudience/changelog/index.html +++ b/docs/facebookaudience/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

- + \ No newline at end of file diff --git a/docs/faqs/error-404/index.html b/docs/faqs/error-404/index.html index 8f8746c3fdd..9ac49140a3b 100644 --- a/docs/faqs/error-404/index.html +++ b/docs/faqs/error-404/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

404 error when accessing repository?

If you have purchased the extension and you are getting a 404 error when browsing to the repository you may have to accept an invitation to our GitHub organisation. This is a step required by GitHub before we can give you access to the private repositories.

Either check your GitHub email address for an invitation or browse to:

https://github.com/distriqt

and accept the invitation.

- + \ No newline at end of file diff --git a/docs/faqs/error-context-create/index.html b/docs/faqs/error-context-create/index.html index e9b367e8864..ef151e27e17 100644 --- a/docs/faqs/error-context-create/index.html +++ b/docs/faqs/error-context-create/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Error: The native extension context could not be created

Error: The native extension context could not be created
at com.distriqt.extension.vibration::Vibration()[/Users/marchbold/work/distriqt/svn/lib/extensions/vibration/trunk/actionscript/src/com/distriqt/extension/vibration/Vibration.as:65]
at com.distriqt.extension.vibration::Vibration$/createInstance()[/Users/marchbold/work/distriqt/svn/lib/extensions/vibration/trunk/actionscript/src/com/distriqt/extension/vibration/Vibration.as:110]
at com.distriqt.extension.vibration::Vibration$/get isSupported()[/Users/marchbold/work/distriqt/svn/lib/extensions/vibration/trunk/actionscript/src/com/distriqt/extension/vibration/Vibration.as:136]

If you receive an error such as the one above, then most likely the extension has been included but not packaged with your application. You'll need to double check the project settings:

Actionscript Build Packaging / [Platform] / Native Extensions / make sure the extension is checked

And ensure that you have correctly added the extension id to your application descriptor:

<?xml version="1.0" encoding="utf-8" ?>
<application xmlns="http://ns.adobe.com/air/application/26.0">

<!-- OTHER DESCRIPTOR INFORMATION -->

<extensions>
<extensionID>com.distriqt.Vibration</extensionID>
</extensions>

</application>

See the last step in the following tutorial for more information: here

- + \ No newline at end of file diff --git a/docs/faqs/index.html b/docs/faqs/index.html index b0e1cee74f9..1bf68f73666 100644 --- a/docs/faqs/index.html +++ b/docs/faqs/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

FAQs

The following are questions that are asked quite often when developing with native extensions. They aren't applicable to any extension in particular but are about using our support system or using native extensions in general. For specific tutorials and information on a native extension see the dedicated page for the native extension.

- + \ No newline at end of file diff --git a/docs/faqs/ld-framework-not-found/index.html b/docs/faqs/ld-framework-not-found/index.html index a151c1859d3..ef0d8c8739f 100644 --- a/docs/faqs/ld-framework-not-found/index.html +++ b/docs/faqs/ld-framework-not-found/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

ld: framework not found ...

A very common error you may come across is the one shown below, a linker error:

ld: framework not found ... 
Compilation failed while executing : ld64

The error is simply telling you that the native extension uses some functionality of the phone that is not found in the default SDK that AIR uses to compile against. To resolve this issue you must add in the iOS SDK path into the build packaging options of the iOS platform. Firstly you'll need to acquire the iOS SDK by going to the Apple developer site and downloading xcode.

Then in FlashBuilder you can specify the path in the Apple iOS build packaging options, as below.

If you are using adt to compile (which you'll need to use if you are using Windows) you'll need to specify the platformsdk argument:

adt -package -target ipa-app-store \ 
-provisioning-profile ./myProfile.mobileprovision \
-storetype pkcs12 -keystore ./Certificates.p12 \
-storepass XXX \
myApp.ipa myApp-app.xml Main.swf \
-extdir ext/ \
-platformsdk /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/
- + \ No newline at end of file diff --git a/docs/faqs/ld-unknown-option/index.html b/docs/faqs/ld-unknown-option/index.html index 272e0a09d2b..9aed6648a3c 100644 --- a/docs/faqs/ld-unknown-option/index.html +++ b/docs/faqs/ld-unknown-option/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

ld: unknown option

When packaging an iOS AIR application you may encounter the following error:

Error occurred while packaging the application:
ld: unknown option: -ios_version_min
Compilation failed while executing: ld64

As in the following screenshot:

This error simply indicates that the native extension you are attempting to package requires some features from the iOS SDK or a version greater than the one you are currently using. To remedy this, make sure you are using a recent version of the iOS SDK and correctly including it in your packaging options.

- + \ No newline at end of file diff --git a/docs/faqs/ld-warning/index.html b/docs/faqs/ld-warning/index.html index 0db8cb01816..d20200b3bac 100644 --- a/docs/faqs/ld-warning/index.html +++ b/docs/faqs/ld-warning/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

ld: warning

When compiling an iOS AIR mobile application you may encounter errors of the following:

ld: warning: ARM function not 4-byte aligned

These are just optimisation warnings and will not directly affect the operation of the application. You are safe to ignore them.

- + \ No newline at end of file diff --git a/docs/firebase/auth/add-the-extensions/index.html b/docs/firebase/auth/add-the-extensions/index.html index 98971af749c..985a4170dd8 100644 --- a/docs/firebase/auth/add-the-extensions/index.html +++ b/docs/firebase/auth/add-the-extensions/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ There is no problem packaging these ANEs with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/firebase/auth/initialise/index.html b/docs/firebase/auth/initialise/index.html index 7bbe504118e..305f0b4903e 100644 --- a/docs/firebase/auth/initialise/index.html +++ b/docs/firebase/auth/initialise/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Auth - Initialise

Authentication State

The most important listener you will probably want to use is for the Authentication state change.

This event is dispatched whenever the state of the user's authentication changes, such as signing in or out.

FirebaseAuth.service.addEventListener( FirebaseAuthEvent.AUTHSTATE_CHANGED, authState_changedHandler );

Whenever this event is dispatched you can check the current sign in status using the isSignedIn function as in the example event handler below:

private function authState_changedHandler( event:FirebaseAuthEvent ):void
{
trace( "auth state changed: "+FirebaseAuth.service.isSignedIn() );
}
- + \ No newline at end of file diff --git a/docs/firebase/auth/introduction/index.html b/docs/firebase/auth/introduction/index.html index 81debd4200f..7fe94e93344 100644 --- a/docs/firebase/auth/introduction/index.html +++ b/docs/firebase/auth/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ Facebook, Twitter, and GitHub accounts.

Anonymous auth

Use Firebase features that require authentication without requiring users to sign in first by creating temporary anonymous accounts. If the user later chooses to sign up, you can upgrade the anonymous account to a regular account, so the user can continue where they left off.

- + \ No newline at end of file diff --git a/docs/firebase/auth/link-multiple-providers/index.html b/docs/firebase/auth/link-multiple-providers/index.html index b1731f16606..274ef95b70e 100644 --- a/docs/firebase/auth/link-multiple-providers/index.html +++ b/docs/firebase/auth/link-multiple-providers/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ account and then, later, sign in with Facebook to continue using your app.

To link auth provider credentials to an existing user account, firstly ensure you have a user signed into Firebase, then:

var credential:AuthCredential = EmailAuthProvider.getEmailAuthCredential( Config.email, Config.password );

FirebaseAuth.service.getCurrentUser().addEventListener(
FirebaseUserEvent.LINK_WITH_CREDENTIAL_COMPLETE,
linkWithCredential_completeHandler );

FirebaseAuth.service.getCurrentUser().linkWithCredential( credential );

If the call to linkWithCredential succeeds, the user can now sign in using any linked authentication provider and access the same Firebase data.

You can unlink an auth provider from an account, so that the user can no longer sign in with that provider.

To unlink an auth provider from a user account, pass the provider ID to the unlink method. You can get the provider IDs of the auth providers linked to a user by using the providers array of the FirebaseUser.

FirebaseAuth.service.getCurrentUser().addEventListener(
FirebaseUserEvent.UNLINK_COMPLETE,
unlinkCompleteHandler );

FirebaseAuth.service.getCurrentUser().unlink( providerId );
- + \ No newline at end of file diff --git a/docs/firebase/auth/manage-users/index.html b/docs/firebase/auth/manage-users/index.html index b77a41cde2d..24d3145113a 100644 --- a/docs/firebase/auth/manage-users/index.html +++ b/docs/firebase/auth/manage-users/index.html @@ -13,7 +13,7 @@ - + @@ -36,7 +36,7 @@ the action fails (event.success will be false).

When this happens, re-authenticate the user by getting new sign-in credentials from the user and passing the credentials to reauthenticate.

For example:

var credential:AuthCredential = EmailAuthProvider.getEmailAuthCredential( "user@example.com", "password1234" );

FirebaseAuth.service.getCurrentUser().addEventListener(
FirebaseUserEvent.REAUTHENTICATE_COMPLETE,
reauthenticate_completeHandler );

FirebaseAuth.service.getCurrentUser().reauthenticate( credential );

You can use the FirebaseUserEvent.REAUTHENTICATE_COMPLETE event to listen for the completion of this method.

private function reauthenticate_completeHandler( event:FirebaseUserEvent ):void
{
FirebaseAuth.service.getCurrentUser().removeEventListener(
FirebaseUserEvent.REAUTHENTICATE_COMPLETE,
reauthenticate_completeHandler );
}

User Token

You may wish to authenticate a user on your server for actions in Firebase from your application. To do this you'll need the users authentication token.

FirebaseAuth.service.getCurrentUser().addEventListener( 
FirebaseUserEvent.GET_TOKEN_COMPLETE,
getToken_completeHandler );

FirebaseAuth.service.getCurrentUser().getToken( true );
private function getToken_completeHandler(event:FirebaseUserEvent ):void
{
if (event.success)
{
// Success means the event has a valid token in event.data
trace( event.data );
}

FirebaseAuth.service.getCurrentUser().removeEventListener(
FirebaseUserEvent.GET_TOKEN_COMPLETE,
getToken_completeHandler );
}
- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/anonymous/index.html b/docs/firebase/auth/provider/anonymous/index.html index b44df9ce716..9f33524940b 100644 --- a/docs/firebase/auth/provider/anonymous/index.html +++ b/docs/firebase/auth/provider/anonymous/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ you can check the message for more information to determine the issue.

private function completeHandler( event:FirebaseAuthEvent ):void
{
trace( "signInAnonymously(): complete: " + event.message );
if (event.success)
{
var user:FirebaseUser = FirebaseAuth.service.getCurrentUser();

trace( user.identifier );
}
else
{
trace( "ERROR::" + event.message );
}
FirebaseAuth.service.removeEventListener(
FirebaseAuthEvent.SIGNIN_ANONYMOUSLY_COMPLETE,
completeHandler );
}

You can also listen to the global FirebaseAuthEvent.AUTHSTATE_CHANGED event for the success of the signInAnonymously function, however to correctly process failed events you should use the above FirebaseAuthEvent.SIGNIN_ANONYMOUSLY_COMPLETE event.

- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/apple/index.html b/docs/firebase/auth/provider/apple/index.html index 8c69b3edea9..109e96cfe91 100644 --- a/docs/firebase/auth/provider/apple/index.html +++ b/docs/firebase/auth/provider/apple/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Sign in with Apple

You can let your users authenticate with Firebase using their Apple ID by using the Firebase SDK and the Apple Sign In extension to carry out the end-to-end OAuth 2.0 sign-in flow.

Important

To sign in with an Apple account, users must:

  • Have an Apple ID with two-factor authentication (2FA) enabled.
  • Be signed in to iCloud on an Apple device.

See How to use Sign in with Apple. You will also need to meet these requirements to test your integration with Sign In with Apple.

Setup

To sign in users using Apple, first configure Sign In with Apple on Apple's developer site, then enable Apple as a sign-in provider for your Firebase project.

Follow the guide in the:

iOS

For iOS devices you will need access to the AppleSignIn extension to perform the "Sign in with Apple".

The iOS authentication with Firebase is a two step process similar to many of the other providers. You will firstly perform the normal Sign in with Apple process and then authenticate with Firebase.

Sign in with Apple

To perform this step you will need to add the AppleSignIn extension.

Then to perform the actual sign in setup the standard AppleSignInOptions and call loginWithAppleId():

AppleSignIn.instance.addEventListener( AppleSignInErrorEvent.ERROR, errorHandler );
AppleSignIn.instance.addEventListener( AppleSignInEvent.SUCCESS, successHandler );

var options:AppleSignInOptions = new AppleSignInOptions()
.setRequestedScopes([
AppleSignInScopes.FULL_NAME,
AppleSignInScopes.EMAIL
]);

AppleSignIn.instance.loginWithAppleId( options );

function successHandler( event:AppleSignInEvent ):void
{
// Continue to Authenticate with Firebase
}

function errorHandler( event:AppleSignInErrorEvent ):void
{
// Handle the error as required by your application
trace( "errorHandler(): [" + event.errorID + "] :: " + event.text );
}

Authenticate with Firebase

Once you have successfully performed the Sign in with Apple you will need to use the Apple Id credentials to construct a Firebase OAuthCredential. You will need the ID Token and the raw nonce from the success event.

It is important to note that the credentials returned from the Apple Sign In ANE are base64 encoded so you will need to decode them before passing to Firebase

var identityToken:String = Base64.decode( event.appleIdCredential.identityToken );
var rawNonce:String = event.rawNonce;

Then use these values to create the OAuthCredential using apple.com as the provider id:

var credential:OAuthCredential =
OAuthProvider.getCredential( "apple.com" )
.setIdTokenWithRawNonce(
identityToken,
rawNonce
);

Once you have created the OAuthCredential object you call signInWithCredential() passing in this credential object:

var success:Boolean = FirebaseAuth.service.signInWithCredential( credential );

This may return false if your credential was invalid.

If successful you will receive the FirebaseAuthEvent.SIGNIN_WITH_CREDENTIAL_COMPLETE which will indicate the success of the sign in:

FirebaseAuth.service.addEventListener( FirebaseAuthEvent.SIGNIN_WITH_CREDENTIAL_COMPLETE, signInWithCredential_completeHandler );

FirebaseAuth.service.signInWithCredential( credential );


function signInWithCredential_completeHandler( event:FirebaseAuthEvent ):void
{
trace("signInWithCredential_completeHandler(): " + event.success );
}

Android

The AppleSignIn extension is not required for Android, the parts that we implemented in that ANE are replicated by Firebase. The easiest way to authenticate your users with Firebase using their Apple accounts is to handle the entire sign-in flow with the Firebase Android SDK.

To handle the sign-in flow with the Firebase Android SDK, follow these steps:

  1. Construct an instance of the OAuthProvider
var provider:OAuthProvider = new OAuthProvider( "apple.com" );
  1. Optional: Specify additional OAuth 2.0 scopes beyond the default that you want to request from the authentication provider using setScopes():
var provider:OAuthProvider = new OAuthProvider( "apple.com" )
.setScopes([ "email", "name" ]);
  1. Optional: If you want to display Apple's sign-in screen in a language other than English, set the locale parameter.
var provider:OAuthProvider = new OAuthProvider( "apple.com" )
.setScopes([ "email", "name" ])
.addCustomParameter("locale", "fr")
;
  1. Authenticate with Firebase using the OAuth provider object by calling startSignInWithProvider and awaiting the FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE. Note that unlike other FirebaseAuth operations, this will take control of your UI by opening a Custom Chrome Tab.
FirebaseAuth.service.startSignInWithProvider( provider );

This completes with the FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE event:

FirebaseAuth.service.addEventListener(
FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE,
startSignInWithProvider_completeHandler
);

FirebaseAuth.service.startSignInWithProvider( provider );

function startSignInWithProvider_completeHandler( event:FirebaseAuthEvent ):void
{
trace( "startSignInWithProvider_completeHandler():complete:" + event.success );
}

Next Steps

Once you have completed the authentication with Firebase ou should expect the normal FirebaseAuthEvent.AUTHSTATE_CHANGED event indicating that a user was authenticated and then you will be able to retrieve the user's details using the standard getCurrentUser() where one of the providers will be the Apple details.

var user:FirebaseUser = FirebaseAuth.service.getCurrentUser();
if (user != null)
{
log( "identifier: " + user.identifier );
log( "displayName: " + user.displayName );
log( "email: " + user.email );

for each (var info:UserInfo in user.providers)
{
log( "------------------" );
log( "\tprovider: " + info.providerId );
log( "\tidentifier: " + info.identifier );
log( "\tdisplayName: " + info.displayName );
log( "\temail: " + info.email );
log( "\tphone: " + info.phoneNumber );
}
}

Unlike other providers supported by Firebase Auth, Apple does not provide a photo URL.

Also, when the user chooses not to share their email with the app, Apple provisions a unique email address for that user (of the form xyz@privaterelay.appleid.com), which it shares with your app. If you configured the private email relay service, Apple forwards emails sent to the anonymized address to the user's real email address.

Apple only shares user information such as the display name with apps the first time a user signs in. Usually, Firebase stores the display name the first time a user signs in with Apple, which you can get with the above. However, if you previously used Apple to sign a user in to the app without using Firebase, Apple will not provide Firebase with the user's display name.

Example

The following example demonstrates how to use the above concepts across both Android and iOS using the auth state changed event to listen for the user authentication.

FirebaseAuth.service.addEventListener( FirebaseAuthEvent.AUTHSTATE_CHANGED, authState_changedHandler );

if (FirebaseAuth.service.implementation == "Android")
{
FirebaseAuth.service.addEventListener(
FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE,
startSignInWithProvider_completeHandler
);

var provider:OAuthProvider = new OAuthProvider( "apple.com" )
.setScopes([ "email", "name" ])
;

FirebaseAuth.service.startSignInWithProvider( provider );
}
else if (FirebaseAuth.service.implementation == "iOS")
{
AppleSignIn.instance.addEventListener( AppleSignInErrorEvent.ERROR, appleSignIn_errorHandler );
AppleSignIn.service.addEventListener( AppleSignInEvent.SUCCESS, appleSignIn_successHandler );

var options:AppleSignInOptions = new AppleSignInOptions()
.setRequestedScopes([
AppleSignInScopes.FULL_NAME,
AppleSignInScopes.EMAIL
]);

AppleSignIn.service.loginWithAppleId( options );
}


function startSignInWithProvider_completeHandler( event:FirebaseAuthEvent ):void
{
// End of the Android sign in process
trace( "startSignInWithProvider_completeHandler():complete:" + event.success );
}


function appleSignIn_successHandler( event:AppleSignInEvent ):void
{
var credential:OAuthCredential =
OAuthProvider.getCredential( "apple.com" )
.setIdTokenWithRawNonce(
Base64.decode( event.appleIdCredential.identityToken ),
event.rawNonce
);

FirebaseAuth.service.addEventListener(
FirebaseAuthEvent.SIGNIN_WITH_CREDENTIAL_COMPLETE,
signInWithCredential_completeHandler
);

FirebaseAuth.service.signInWithCredential( credential );
}

function appleSignIn_errorHandler( event:AppleSignInErrorEvent ):void
{
trace( "errorHandler(): [" + event.errorID + "] :: " + event.text );
}


function signInWithCredential_completeHandler( event:FirebaseAuthEvent ):void
{
// End of the iOS sign in process
trace("signInWithCredential_completeHandler(): " + event.success );
}


function authState_changedHandler( event:FirebaseAuthEvent ):void
{
// This will be fired on both iOS and Android when the user is authenticated
trace( "auth state changed: "+FirebaseAuth.service.isSignedIn() );
}
- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/custom-auth/index.html b/docs/firebase/auth/provider/custom-auth/index.html index 0cab6363cf0..3b7d5be4a7c 100644 --- a/docs/firebase/auth/provider/custom-auth/index.html +++ b/docs/firebase/auth/provider/custom-auth/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ to your authentication server. Your server checks the credentials and returns a custom token if they are valid.

After you receive the custom token from your authentication server, pass it to signInWithCustomToken to sign in the user:

FirebaseAuth.service.signInWithCustomToken( customToken );

This will dispatch FirebaseAuthEvent.SIGNIN_WITH_CUSTOMTOKEN_COMPLETE when complete and success will indicate whether the sign-in succeeded.

If sign-in succeeds, you can use the getCurrentUser method to get the user's account data.

- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/email-link/index.html b/docs/firebase/auth/provider/email-link/index.html index 19798c0f5b3..f9803686d53 100644 --- a/docs/firebase/auth/provider/email-link/index.html +++ b/docs/firebase/auth/provider/email-link/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ which they can click to sign in. In the process, the user's email address is also verified.

There are numerous benefits to signing in by email:

To sign in users by email link, you must first enable the Email provider and Email link sign-in method for your Firebase project:

  1. In the Firebase console, open the Auth section.
  2. On the Sign in method tab, enable the Email/Password provider. Note that email/password sign-in must be enabled to use email link sign-in.
  3. In the same section, enable Email link (passwordless sign-in) sign-in method.
  4. Click Save.

To initiate the authentication flow, present the user with an interface that prompts the user to provide their email address and then call sendSignInLinkToEmail() to request that Firebase send the authentication link to the user's email.

  1. Construct the ActionCodeSettings object, which provides Firebase with instructions on how to construct the email link. Set the following fields:

    • url: The deep link to embed and any additional state to be passed along. The link's domain has to be whitelisted in the Firebase Console list of authorized domains, which can be found by going to the Sign-in method tab (Authentication -> Sign-in method). The link will redirect the user to this URL if the app is not installed on their device and the app was not able to be installed.
    • androidPackageName and IOSBundleId: The apps to use when the sign-in link is opened on an Android or iOS device. Learn more on how to configure Firebase Dynamic Links to open email action links via mobile apps.
    • handleCodeInApp: Set to true. The sign-in operation has to always be completed in the app unlike other out of band email actions (password reset and email verifications). This is because, at the end of the flow, the user is expected to be signed in and their Auth state persisted within the app.
  2. Ask the user for their email.

  3. Send the authentication link to the user's email, and save the user's email in case the user completes the email sign-in on the same device.

var email:String = "some@email.com";

var actionCodeSettings:ActionCodeSettings = new ActionCodeSettings()
// URL you want to redirect back to. The domain (www.example.com) for this
// URL must be whitelisted in the Firebase Console.
.setUrl( "https://www.example.com/finishSignUp?cartId=1234" )
.setHandleCodeInApp( true )
.setIOSBundelId( "com.example.ios" )
.setAndroidPackageName(
"com.example.android",
true, /* installIfNotAvailable */
"1" /* minimumVersion */ );

FirebaseAuth.service.sendSignInLinkToEmail( Config.email, actionCodeSettings );

This process will dispatch a complete event when the process was completed with a success flag similar to other events in this extension:

FirebaseAuth.service.addEventListener(
FirebaseAuthEvent.SEND_SIGNIN_LINK_TO_EMAIL_COMPLETE,
sendSignInLinkToEmail_completeHandler );


function sendSignInLinkToEmail_completeHandler( event:FirebaseAuthEvent ):void
{
trace( "sendSignInLinkToEmail():complete:" + event.success );
}

At this point the user will need to check their email and click on the link in the email.

URL

For the URL we generally suggest you use your Firebase app url (https://PROJECT_ID.firebaseapp.com). This normally can be found by checking the Authorized Domains in the Firebase Console under Authentication > Sign in Method

Using this method and adding the Dynamic Links extension simplifies the development and integration required.

This guide will assume this approach however you can use whatever approach suits you needs to handle the url redirection.

Firebase Auth uses Firebase Dynamic Links when sending a link that is meant to be opened in a mobile application. In order to use this feature, Dynamic Links must be configured in the Firebase Console.

Follow the guide to add the Dynamic Links extension to your application:

Now you can listen for the user to click on the link in the email

FirebaseDynamicLinks.service.addEventListener( 
DynamicLinkEvent.RECEIVED,
dynamicLink_receivedHandler );

function dynamicLink_receivedHandler( event:DynamicLinkEvent ):void
{
trace( "dynamicLink_receivedHandler(): " + event.link );

// This could be the email link

}

After you receive the link as described above, verify that it is meant for email link authentication and complete the sign in.

You can check if a link is a "sign in with email link" by using the isSignInWithEmailLink() function:

if (FirebaseAuth.service.isSignInWithEmailLink( link ))
{
// This is a "sign in with email link"
}

You then can sign in the user using their email and the email link by calling the signInWithEmailLink() function:

if (FirebaseAuth.service.isSignInWithEmailLink( link ))
{
// Initiate the sign in process
FirebaseAuth.service.signInWithEmailLink( email, link );
}

The sign in process will dispatch an event once complete:

FirebaseAuth.service.addEventListener(
FirebaseAuthEvent.SIGNIN_WITH_EMAILLINK_COMPLETE,
signInWithEmailLink_completeHandler );

function signInWithEmailLink_completeHandler( event:FirebaseAuthEvent ):void
{
trace( "signInWithEmailLink():complete:" + event.success );
}

Of course you can use your global FirebaseAuthEvent.AUTHSTATE_CHANGED to listen for sign in success as well as this handler.

In case you support both password and link-based sign in with email, to differentiate the method of sign in for a password/link user, use fetchSignInMethodsForEmail(). This is useful for identifier-first flows where the user is first asked to provide their email and then presented with the method of sign-in:

FirebaseAuth.service.addEventListener(
FirebaseAuthMethodsEvent.FETCH_SIGNIN_METHODS_COMPLETE,
fetchSignInMethodsForEmail_completeHandler );

FirebaseAuth.service.fetchSignInMethodsForEmail( Config.email );

function fetchSignInMethodsForEmail_completeHandler( event:FirebaseAuthMethodsEvent ):void
{
trace( "fetchSignInMethodsForEmail():complete:" + event.success );
if (event.methods != null)
{
for each (var method:String in event.methods)
{
if (EmailAuthCredential.EMAIL_LINK_SIGN_IN_METHOD == method)
{
// User can sign in with email/link
}
else if (EmailAuthCredential.EMAIL_PASSWORD_SIGN_IN_METHOD == method)
{
// User can sign in with email/password
}
}
}

}

Note: email/password and email/link are considered the same EmailAuthProvider (same PROVIDER_ID) with different methods of sign-in.

- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/email/index.html b/docs/firebase/auth/provider/email/index.html index 35fb330941d..22f7bbb87c2 100644 --- a/docs/firebase/auth/provider/email/index.html +++ b/docs/firebase/auth/provider/email/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ not attempt to create the user if it does not exist.

Access the signed-in user with getCurrentUser().

Upon successful completion, this operation triggers an FirebaseAuthEvent.AUTHSTATE_CHANGED event and it will trigger a FirebaseAuthEvent.SIGNIN_WITH_EMAIL_COMPLETE on success or failure.

FirebaseAuth.service.addEventListener( 
FirebaseAuthEvent.SIGNIN_WITH_EMAIL_COMPLETE,
signInWithEmailAndPassword_completeHandler );

FirebaseAuth.service.signInWithEmailAndPassword( email, password );

The following handler can be used to determine the success or failure of the call.

private function signInWithEmailAndPassword_completeHandler( event:FirebaseAuthEvent ):void
{
trace( "signInWithEmailAndPassword(): complete: " + event.success +"::"+event.message );

FirebaseAuth.service.removeEventListener(
FirebaseAuthEvent.SIGNIN_WITH_EMAIL_COMPLETE,
signInWithEmailAndPassword_completeHandler );

if (event.success)
{
var user:FirebaseUser = FirebaseAuth.service.getCurrentUser();
trace( user.displayName );
}
}

Of course you can use your global FirebaseAuthEvent.AUTHSTATE_CHANGED to listen for sign in success as well as this handler.

- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/facebook/index.html b/docs/firebase/auth/provider/facebook/index.html index b807518e896..dab5f09bc63 100644 --- a/docs/firebase/auth/provider/facebook/index.html +++ b/docs/firebase/auth/provider/facebook/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ user's unique user ID from the auth variable, and use it to control what data a user can access. You can allow users to sign in to your app using multiple authentication providers by linking auth provider credentials to an existing user account.

To sign out a user, call signOut():

FirebaseAuth.service.signOut();
- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/github/index.html b/docs/firebase/auth/provider/github/index.html index b8d7fa5c7a3..bc8a56f05e7 100644 --- a/docs/firebase/auth/provider/github/index.html +++ b/docs/firebase/auth/provider/github/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/google-identity/index.html b/docs/firebase/auth/provider/google-identity/index.html index 86cbcbd3b15..a38c17df5fa 100644 --- a/docs/firebase/auth/provider/google-identity/index.html +++ b/docs/firebase/auth/provider/google-identity/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ user's unique user ID from the auth variable, and use it to control what data a user can access. You can allow users to sign in to your app using multiple authentication providers by linking auth provider credentials to an existing user account.

To sign out a user, call signOut:

FirebaseAuth.service.signOut();
- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/microsoft/index.html b/docs/firebase/auth/provider/microsoft/index.html index 70461363306..b00d844f3be 100644 --- a/docs/firebase/auth/provider/microsoft/index.html +++ b/docs/firebase/auth/provider/microsoft/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Authenticate Using Microsoft

You can let your users authenticate with Firebase using OAuth providers like Microsoft Azure Active Directory by integrating web-based generic OAuth Login into your app using the Firebase SDK to carry out the end to end sign-in flow.

Before you begin

To sign in users using Microsoft accounts (Azure Active Directory and personal Microsoft accounts), you must first enable Microsoft as a sign-in provider for your Firebase project:

  1. Add Firebase to your project.
  2. In the Firebase console, open the Auth section.
  3. On the Sign in method tab, enable the Microsoft provider.
  4. Add the Client ID and Client Secret from that provider's developer console to the provider configuration:
  • To register a Microsoft OAuth client, follow the instructions in Quickstart: Register an app with the Azure Active Directory v2.0 endpoint. Note that this endpoint supports sign-in using Microsoft personal accounts as well as Azure Active Directory accounts. Learn more about Azure Active Directory v2.0.
  • When registering apps with these providers, be sure to register the *.firebaseapp.com domain for your project as the redirect domain for your app.
  1. Click Save.
  2. If you haven't yet specified your app's SHA-1 fingerprint, do so from the Settings page of the Firebase console. Refer to Authenticating Your Client for details on how to get your app's SHA-1 fingerprint.

Handle the sign-in flow with the Firebase SDK

If you are building an Android app, the easiest way to authenticate your users with Firebase using their Microsoft accounts is to handle the entire sign-in flow with the Firebase SDK.

To handle the sign-in flow with the Firebase Android SDK, follow these steps:

  1. Construct an instance of an OAuthProvider with the provider ID microsoft.com.
var provider:OAuthProvider = new OAuthProvider( "microsoft.com" );
  1. Optional: Specify additional custom OAuth parameters that you want to send with the OAuth request.
// Force re-consent.
provider.addCustomParameter("prompt", "consent");

// Target specific email with login hint.
provider.addCustomParameter("login_hint", "user@firstadd.onmicrosoft.com");

For the parameters Microsoft supports, see the Microsoft OAuth documentation. Note that you can't pass Firebase-required parameters with setCustomParameters(). These parameters are client_id, response_type, redirect_uri, state, scope and response_mode.

To allow only users from a particular Azure AD tenant to sign into the application, either the friendly domain name of the Azure AD tenant or the tenant's GUID identifier can be used. This can be done by specifying the "tenant" field in the custom parameters object.

// Optional "tenant" parameter in case you are using an Azure AD tenant.
// eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or 'contoso.onmicrosoft.com'
// or "common" for tenant-independent tokens.
// The default value is "common".
provider.addCustomParameter("tenant", "TENANT_ID");
  1. Optional: Specify additional OAuth 2.0 scopes beyond basic profile that you want to request from the authentication provider.
provider.setScopes([ "mail.read", "calendars.read" ]);

To learn more, refer to the Microsoft permissions and consent documentation.

  1. Authenticate with Firebase using the OAuth provider object by calling startSignInWithProvider and awaiting the FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE. Note that unlike other FirebaseAuth operations, this will take control of your UI by opening a Custom Chrome Tab.
FirebaseAuth.service.startSignInWithProvider( provider );

This completes with the FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE event:

FirebaseAuth.service.addEventListener(
FirebaseAuthEvent.SIGNIN_WITH_PROVIDER_COMPLETE,
startSignInWithProvider_completeHandler
);

FirebaseAuth.service.startSignInWithProvider( provider );

function startSignInWithProvider_completeHandler( event:FirebaseAuthEvent ):void
{
trace( "startSignInWithProvider_completeHandler():complete:" + event.success );
}

Next Steps

Once you have completed the authentication with Firebase you should expect the normal FirebaseAuthEvent.AUTHSTATE_CHANGED event indicating that a user was authenticated and then you will be able to retrieve the user's details using the standard getCurrentUser() where one of the providers will be the Microsoft details.

var user:FirebaseUser = FirebaseAuth.service.getCurrentUser();
if (user != null)
{
log( "identifier: " + user.identifier );
log( "displayName: " + user.displayName );
log( "email: " + user.email );

for each (var info:UserInfo in user.providers)
{
log( "------------------" );
log( "\tprovider: " + info.providerId );
log( "\tidentifier: " + info.identifier );
log( "\tdisplayName: " + info.displayName );
log( "\temail: " + info.email );
log( "\tphone: " + info.phoneNumber );
}
}

Unlike other providers supported by Firebase Auth, Microsoft does not provide a photo URL and instead, the binary data for a profile photo has to be requested via Microsoft Graph API.

- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/phone/index.html b/docs/firebase/auth/provider/phone/index.html index 14bd008888f..fdc93c05a07 100644 --- a/docs/firebase/auth/provider/phone/index.html +++ b/docs/firebase/auth/provider/phone/index.html @@ -13,7 +13,7 @@ - + @@ -38,7 +38,7 @@ This new account is stored as part of your Firebase project, and can be used to identify a user across every app in your project, regardless of how the user signs in.

Example

The following example shows the complete sign in process, using a simple text input dialog (from the Dialog ANE) to gather the SMS code from the user.

FirebaseAuth.service.addEventListener( FirebaseAuthEvent.VERIFY_PHONE_NUMBER_FAILED, verifyPhoneNumber_failedHandler );
FirebaseAuth.service.addEventListener( FirebaseAuthEvent.VERIFY_PHONE_NUMBER_CODE_SENT, verifyPhoneNumber_codeSentHandler );
FirebaseAuth.service.addEventListener( FirebaseAuthEvent.SIGNIN_WITH_CREDENTIAL_COMPLETE, signInWithPhoneNumber_completeHandler );

FirebaseAuth.service.verifyPhoneNumber( phoneNumber, 60 );

var verificationId:String;

function verifyPhoneNumber_failedHandler( event:FirebaseAuthEvent ):void
{
// An error occurred
}

function verifyPhoneNumber_codeSentHandler( event:FirebaseAuthEvent ):void
{
// Here we should save the verification id somewhere persistent
// in case the application crashes or something else occurs while
// the user is getting the sms code from their message application.
//
// Then we should display an input for the sms code

verificationId = event.verificationId;

//
// Then we should display an input for the sms code

// Here we use a simple dialog from the Dialog ANE:
var dialogView:DialogView = Dialog.service.create(
new AlertBuilder(true)
.setTitle("Enter SMS Code")
.addTextField( "", "SMS Code" )
.addOption("OK", DialogAction.STYLE_POSITIVE)
.build()
);
dialogView.addEventListener( DialogViewEvent.CLOSED, dialogClosedHandler );
dialogView.show();
}

function dialogClosedHandler( event:DialogViewEvent ):void
{
var smsCode:String = event.values[0];

// Start the sign in with the user entered SMS code
signInWithPhoneNumber( verificationId, smsCode );
}


function signInWithPhoneNumber( verificationId:String, smsCode:String ):void
{
var credential:PhoneAuthCredential = PhoneAuthProvider.getCredential( verificationId, smsCode );
FirebaseAuth.service.signInWithCredential( credential );
}


function signInWithPhoneNumber_completeHandler( event:FirebaseAuthEvent ):void
{
trace( "signInWithPhoneNumber: complete: " + event.success );

if (event.success)
{
// You will now have a valid user
var user:FirebaseUser = FirebaseAuth.service.getCurrentUser();
}
}
- + \ No newline at end of file diff --git a/docs/firebase/auth/provider/twitter/index.html b/docs/firebase/auth/provider/twitter/index.html index f57a18120d9..0dc7cea21de 100644 --- a/docs/firebase/auth/provider/twitter/index.html +++ b/docs/firebase/auth/provider/twitter/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/firebase/changelog/index.html b/docs/firebase/changelog/index.html index 506b1fd6033..5e02353d3e8 100644 --- a/docs/firebase/changelog/index.html +++ b/docs/firebase/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.07.13 [v8.0.1]

fix(auth): correct package dependencies and update documentation (resolves #449)

2023.07.05 [v8.0.0]

feat(auth): add language functionality (resolves #447)

feat(auth): update auth sdk, android v22.0.0, ios v10.11.0
feat(core): update analytics sdk, android v21.3.0, ios v10.11.0
feat(crashlytics): update crashlytics sdk, android v18.3.7, ios v10.11.0
feat(database): update database sdk, android v20.2.2, ios v10.11.0
feat(dynamiclinks): update dynamiclinks sdk, android v21.1.0, ios v10.11.0
feat(firestore): update firestore sdk, android v24.6.1, ios v10.11.0
feat(performance): update performance sdk, android v20.3.3, ios v10.11.0
feat(remoteconfig): update remoteconfig sdk, android v21.4.0, ios v10.11.0
feat(storage): update storage sdk, android v20.2.1, ios v10.11.0

2023.01.20 [v7.3.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #435)
fix(crashlytics): ios add nil check for error in recordError (#429)
feat(auth): Add user reload functionality (resolves #430)

2022.08.03 [v7.2.3]

fix(build): rebuild with AIR 33.1.1.856 due to swc build issue in 889 (resolves #421)

2022.07.01 [v7.2.2]

feat(docs,version): update version references + docs for storage list files functionality

2022.06.23 [v7.2.1]

feat(ios): update ios sdk to v8.1.5 (#358)
feat(storage): add ability to list items and directories (resolves #414)

2022.04.29 [v7.1.1]

fix(firestore): critical fix for issue with processing data from queries (resolves #408) 

2022.04.29 [v7.1.0]

Firestore: Changed Date object operation from being converted to a string to being converted to and from a timestamp object (resolves #408)

2022.03.15 [v7.0.1]

Correct crashlytics package dependency

2022.03.10 [v7.0.0]

Update Firebase SDK
- Android BOM v29.0.4 (resolves #396, resolves #360, potential #362)

Updates for Android 31
Documentation update to use apm and changes for Android 31 (resolves #397)

DynamicLinks: Add ability to decode a short url using getDynamicLink function (resolves #399)
Remote Config: Add getByteArray implementation on Android (resolves #402)

2021.11.11 [v6.0.9]

Update Auth Facebook example with complete apm usage
Update Auth examples and documentation for Facebook auth provider (resolves #395)

2021.10.22 [v6.0.8]

Update builds that failed to be deployed correctly (resolves #390)

2021.09.17 [v6.0.8]

Added air package
Corrected issues with processing json responses causing delays and errors (resolves #370)
Corrected FCM documentation link (resolves #368)
Corrected conversion tool link (resolves #369)

2021.06.14 [v6.0.006]

Database: Resolved iOS crash with null param passed to child function (resolves #366)

2021.04.21 [v6.0.005]

Corrected issue with realtime database startAt query (resolves #361)

2021.01.26 [v6.0.003]

Corrected issue in remote config setConfigSettings on iOS (resolves #352)

2021.01.22 [v6.0.002]

Auth: Corrected documentation on manifest changes (resolves #350)
Firestore: Fixed crash on iOS when changing settings
Analytics: Updated event and param definitions

2021.01.20 [v6.0.0]

Updated Firebase SDK 
- Android v26.3.0
- iOS v7.4.0 (resolves #348)

2020.12.18 [v5.2.046]

Crashlytics: iOS updated to v6.30.0 migration from Fabric to Firebase (requires AIR update to 33.1.1.345) (resolves #317)
Crashlytics: Added checks for empty stack trace when reporting errors (resolves #337)
Analytics: Automatically convert deprecated setCurrentScreen function to event (#325)

2020.10.20 [v5.1.044]

Updated docs for Microsoft Auth and Crashlytics

2020.09.17 [v5.1.042]

Firestore: Added Blob handling (resolves #319)

2020.09.14 [v5.0.038]

Crashlytics: iOS rollback to fix issue with current release and AIR (resolves #317)

2020.09.01 [v5.0.036]

SDK update:
- iOS v6.30.0 (#301, resolves #275)
- Android v17.5.0

Auth
- Added Sign in with Apple (resolves #250)

Dynamic Links
- Updated dynamic link handling (#295)

Firebase Crashlytics (resolves #304)

2020.06.18 [v4.2.028]

Auth
- Added Email Link (password less) authentication (resolves #256)

Analytics
- Documentation on iOS debugging (#238)

2020.05.25 [v4.1.025]

SDK update:
- iOS v6.11.0 (resolves UIWebView issue)

2020.05.04 [v4.0.020]

Updated SDK:
- Android 17.4.0 (#275, #283)
Added error checking to analytics (resolves #280)
Firestore: Corrected issue with multiple queries on same (or similar) collection (resolves #271, resolves #284)

2020.03.30 [v4.0.015]

Corrected iOS build inclusion of incorrect frameworks (resolves #274)

2020.03.24 [v4.0.013]

Updated docs

2020.03.24 [v4.0.012]

Android X migration (resolves #268)
Major Android SDK update
New versioning system

2020.03.12 [v3.1.016]

Android: Update for slow setCurrentScreen call (resolves #266)

2019.12.11 [v3.1.013]

Updated SDK:
- iOS v6.2.0 (#246)

Removed deprecated Invites functionality
Removed deprecated Crash functionality

2019.09.06 [v3.0.003]

Android 64bit support (resolves #220)
Updated minimum iOS version to 9.0

2019.03.11 [v2.4.078]

Updated minimum iOS version to 8.0 (resolves #207)

2019.03.02 [v2.4.077]

Clearer GPS Requirement Documentation (resolves #201)
Embedded iOS bitcode

2019.01.24 [v2.4.074]

Updated documentation for latest ANEs (resolves #193)

2019.01.15 [v2.4.072]

iOS: Performance: Resolved invalid bundle packaging issue (resolves #186)

2018.12.12 [v2.4.070]

Firestore: Corrected issue with queries not returning document references in snapshots (resolves #179)

2018.11.27 [v2.4.069]

Updated SDK:
- iOS v5.13.0 (#164)
- Android v16.0.5 (#142, #162)

Updated to Google Play Services v16.0.5

2018.11.18 [v2.3.065]

Added Firestore implementation (resolves #111)
Crashlytics: Added custom error report (resolves #167)

2018.09.01 [v2.2.060]

Updated documentation

2018.09.01 [v2.2.059]

Updated SDK:
- iOS v5.6.0

Added Crashlytics implementation (resolves #60)

Core: Improved performance of logEvent call (resolves #166)
Storage: Resolved crash when uploading to unauthorised location (resolves #160)

2018.06.01 [v2.1.055]

Updated SDK:
- Android v16.0.1
- iOS v5.1.0

Storage : Add getDownloadUrl to storage reference

2018.04.20 [v2.0.043]

Database: updateChildren Android performance improvements (resolves #141)

2018.03.15 [v2.0.042]

Updated SDK: 
- Android v11.8.0
- iOS v4.10.1
- (resolves #137, #134, #116, #105)

Updates:
- Corrected docs formatting (resolves #106)

2017.12.17 [v1.9.029]

Updated documentation for Facebook Auth (resolves #126)

2017.11.24 [v1.9.029]

Corrected Database iOS build

2017.11.24 [v1.9.027]

Updated SDK: Android v11.0.4 iOS v4.6.0
Added Invites (resolves #5)
iOS: Fixed crash when no network connection (resolves #117)
Updated documentation

2017.09.02 [v1.8.019]

Database: Added getKey functionality (resolves #100)

2017.08.04 [v1.8.017]

Updated SDK: Android v11.0.4 iOS v4.0.4 
Added Performance Monitoring (resolves #58)
RemoteConfig: Added (resolves #87)

2017.07.14 [v1.7.029]

Database: Removed debug traces (resolves #86)

2017.07.10 [v1.7.027]

Updated SDK: Android v11.0.2 iOS v4.0.3 
Added Phone Auth (resolves #81)
Added Custom Auth (resolves #71)
Auth: Added more error information for better error handling (#84)

2017.06.27 [v1.6.019]

Dynamic Links implementation (resolves #4)

2017.06.19 [v1.5.003]

Database update to correctly handle invalid references (#61)

2017.06.16 [v1.5.001]

Updated SDK: iOS v4.0.2 
Fixed issue with incorrectly loading config files (#67)

2017.06.10 [v1.4.005]

RemoteConfig implementation (resolves #6)
Updated SDK: Android v11.0.0, iOS v4.0.1 (#57, #45, resolves #30)
Correct operation for '.info' properties (resolves #64)

2017.05.31 [v1.3.0]

Updated SDK: Android v10.2.6, iOS v4.0.0 (#30, #45, #57)

2017.05.17 [v1.2.011]

Database: Added onDisconnect functionality (resolves #55)

2017.03.23 [v1.1.011]

Minor framework updates

2017.03.23 [v1.1.011]

Analytics: Added additional functionality (resolves #52)

2017.03.15 [v1.1.009]

Database: Added once functionality (resolves #47)

2017.03.06 [v1.1.007]

Corrected release error (#39)

2017.03.06 [v1.1.007]

Database: Added ServerValue TIMESTAMP (resolves #34)

2017.03.06 [v1.1.003]

Implemented core default lib (resolves #39)
Corrected storage getBytes success event (resolves #42)
Corrected storage config documentation (resolves #41)
Updated config script (resolves #28)

2017.03.02 [v1.1.003]

Corrected build removing duplicate libraries (resolves #38)

2017.03.01 [v1.1.002]

Android Update for Google Play Services and Firebase v10.2.0

2017.02.28 [v1.1.0]

Storage: iOS implementation (resolves #18)
Auth: Changed photoUri reference to photoUrl for consistency (resolves #32)

2017.02.28 [v1.1.0]

Storage: iOS implementation (resolves #18)
Auth: Changed photoUri reference to photoUrl for consistency (resolves #32)

2017.02.20 [v1.0.0]

Updated documentation

2017.02.20 [v1.0.0]

Updated iOS SDK to v3.13 which now gives analytics on iOS (resolves #27)
Implementation of Crash Reporting v1.0 (resolves #26)

2017.02.09 [v1.0.0]

Updating documentation

2017.02.09 [v1.0.0]

Android Implementation of Storage (#18)

2017.02.03 [v1.0.0]

Realtime Databases complete implementation (resolves #1)

2017.01.30 [v..]

Realtime Databases for Android release + update to v10.0.1

2016.11.22 [v..]

Added Firebase Auth

2016.10.28 [v..]

Initial release
- + \ No newline at end of file diff --git a/docs/firebase/core/add-the-extensions/index.html b/docs/firebase/core/add-the-extensions/index.html index c91004e5e1d..42813fa7c2d 100644 --- a/docs/firebase/core/add-the-extensions/index.html +++ b/docs/firebase/core/add-the-extensions/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ to disable the automatic delegate proxy that Firebase implements on iOS. To do so you must add the following to your InfoAdditions:

<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>FirebaseAutomaticScreenReportingEnabled</key>
<false/>

Eg:

<iPhone>
<InfoAdditions><![CDATA[
<key>UIDeviceFamily</key>
<array>
<string>1</string>
<string>2</string>
</array>

<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>FirebaseAutomaticScreenReportingEnabled</key>
<false/>

<key>MinimumOSVersion</key>
<string>11.0</string>

]]></InfoAdditions>
<requestedDisplayResolution>high</requestedDisplayResolution>
<Entitlements>
<![CDATA[
]]>
</Entitlements>
</iPhone>

You may wish to add a minimum iOS version to restrict your application to the minimum Firebase version.

- + \ No newline at end of file diff --git a/docs/firebase/core/analytics/index.html b/docs/firebase/core/analytics/index.html index e8d961e157a..0dbe65cd9bf 100644 --- a/docs/firebase/core/analytics/index.html +++ b/docs/firebase/core/analytics/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Core - Analytics

Once you have configured the core Firebase project you can use the analytics features in your AIR application.

Log Events

var event:EventObject = new EventObject();

event.name = EventObject.ADD_TO_CART;
event.params[Params.PRICE] = 1.99;
event.params[Params.CURRENCY] = "USD";
event.params[Params.VALUE] = 88;

Firebase.service.analytics.logEvent( event );

Set User Properties

You can set a user id to identify your users.

Firebase.service.analytics.setUserID( userId ); 

You can set user properties to describe the users of your application and then use these properties to filter your reports.

Firebase.service.analytics.setUserProperty( name, value );

Debugging

You can enable the debug mode for analytics which will send events almost immediately to the Debug View on the console:

Android

You can debug your analytics events using adb and the Debug View in the firebase console.

Firstly make sure you've enabled developer mode on your Android device

Open up a terminal/console and use adb to enable debug analytic events:

adb shell setprop debug.firebase.analytics.app APPLICATION_PACKAGE

eg

adb shell setprop debug.firebase.analytics.app air.com.distriqt.test

Additionally you can check the logs to see if there are any errors. It helps to set logging to verbose:

adb shell setprop log.tag.FA VERBOSE

Then restart your application and watch the logs:

adb logcat

You should see something like:

12-06 10:16:45.251 28709 28709 I FA      : App measurement is starting up, version: 11020
12-06 10:16:45.251 28709 28709 I FA : To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
12-06 10:16:45.258 28709 28709 V FA : Collection enabled
12-06 10:16:45.259 28709 28709 V FA : App package, google app id: air.com.distriqt.test, 1:XXXXXXXXXXXXX:android:XXXXXXXXXXXXXX
12-06 10:16:45.259 28709 28709 I FA : Faster debug mode event logging enabled. To disable, run:
12-06 10:16:45.259 28709 28709 I FA : adb shell setprop debug.firebase.analytics.app .none.
12-06 10:16:45.259 28709 28709 D FA : Debug-level message logging enabled
12-06 10:16:45.264 28709 28709 V FA : Registered activity lifecycle callback

Check the app id is correct and watch for any errors when logging events.

iOS

With iOS you have to launch your application with a specific flag. This is not possible using AIR SDK, however using the libimobiledevice tools it is possible to launch an application on your device with this flag.

Firstly you will need to install these tools.

You can access installers in various locations but we suggest using homebrew:

brew install --HEAD usbmuxd
brew install --HEAD libimobiledevice
brew install --HEAD ideviceinstaller

We found you have to use the HEAD version to get it to work currently

Then to launch the application with the debugging FIRAnalyticsDebugEnabled flag:

idevicedebug run "com.distriqt.test" "-FIRAnalyticsDebugEnabled"

Replace com.distriqt.test with your application id

To later disable the debugging outputs, launch the application with the noFIRAnalyticsDebugEnabled flag:

idevicedebug run "com.distriqt.test" "-noFIRAnalyticsDebugEnabled"

Note: these flags have changed from the previous version of FIRDebugEnabled and FIRDebugDisabled

- + \ No newline at end of file diff --git a/docs/firebase/core/initialise/index.html b/docs/firebase/core/initialise/index.html index 1bce88c272e..1dd015ca56a 100644 --- a/docs/firebase/core/initialise/index.html +++ b/docs/firebase/core/initialise/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Core - Initialise

Application Configuration

You must perform the Firebase configuration somewhere early in your application.

This process involves calling initialiseApp which will load your configuration files (as required) and ensure the Firebase application is initialised appropriately based on the current platform.

if (Firebase.isSupported)
{
var success:Boolean = Firebase.service.initialiseApp();
if (!success)
{
// CHECK YOUR CONFIGURATION FILES
}
}

The call to initialiseApp returns a Boolean value indicating whether you have a configured Firebase application available.

If the call returns false, you should return to the Configuration Files section and ensure you have correctly setup all the appropriate options.

Checking the configuration

You can call getOptions() to return the current options loaded into the Firebase application.

This is useful if you are having issues with connecting your application to confirm you are correctly configuring your application.

var options:FirebaseOptions = Firebase.service.getOptions();

trace( options.toString() );

This may return null if the Firebase app has not been configured, either by resources, configuration file or manually.

- + \ No newline at end of file diff --git a/docs/firebase/core/introduction/index.html b/docs/firebase/core/introduction/index.html index 2f360559d73..759ff62dd36 100644 --- a/docs/firebase/core/introduction/index.html +++ b/docs/firebase/core/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Core - Introduction

About

Firebase Analytics is a free app measurement solution that provides insight on app usage and user engagement.

At the heart of Firebase is Firebase Analytics, a free and unlimited analytics solution. Analytics integrates across Firebase features and provides you with unlimited reporting for up to 500 distinct events that you can define using the Firebase SDK. Firebase Analytics reports help you understand clearly how your users behave, which enables you to make informed decisions regarding app marketing and performance optimizations.

YOUTUBE

https://firebase.google.com/docs/analytics/

Key capabilities

Unlimited ReportingFirebase Analytics provides unlimited reporting on up to 500 distinct events.
Audience SegmentationCustom audiences can be defined in the Firebase console based on device data, custom events, or user properties. These audiences can be used with other Firebase features when targeting new features or notifications.
- + \ No newline at end of file diff --git a/docs/firebase/crash/add-the-extensions/index.html b/docs/firebase/crash/add-the-extensions/index.html index 51db2fd2e19..e5ec91d90bc 100644 --- a/docs/firebase/crash/add-the-extensions/index.html +++ b/docs/firebase/crash/add-the-extensions/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Crash - Add the extensions

DEPRECATED

Please note that the Crash functionality has been removed from the latest Firebase SDK in favour of the Crashlytics functionality. You should update your applications to use the new Crashlytics implementation.

This documentation is only for legacy reference.

Required Extensions

You should have been through the setup of the Firebase Core before attempting to proceed with Crash Reporting.

Make sure you have added all the extensions required for the Firebase Core extension as outlined here.

Firebase Crash Reporting

The only required additional ANE is the Crash ANE located in this repository:

This ANE contains all the required libraries for the main Firebase Crash Reporting functionality.

Extension IDs

The following should be added to your extensions node in your application descriptor to identify all the required ANEs in your application:

<extensions>
<extensionID>com.distriqt.Firebase</extensionID>
<extensionID>com.distriqt.firebase.Crash</extensionID>

<extensionID>com.distriqt.Core</extensionID>

<extensionID>com.distriqt.playservices.Base</extensionID>
<extensionID>com.distriqt.playservices.AdsIdentifier</extensionID>

<extensionID>com.google.protobuflite</extensionID>
<extensionID>com.google.firebase.core</extensionID>

<extensionID>androidx.core</extensionID>

<extensionID>com.distriqt.CustomResources</extensionID>
</extensions>

Android

Manifest Additions

No additional manifest additions are required

- + \ No newline at end of file diff --git a/docs/firebase/crash/introduction/index.html b/docs/firebase/crash/introduction/index.html index 2c58d937d1d..82eca300449 100644 --- a/docs/firebase/crash/introduction/index.html +++ b/docs/firebase/crash/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ Crash Reporting should not contain information that personally identifies an individual to Google.

Here is an example of a log message that does not contain personally identifiable information:

FirebaseCrash.service.log("SQL database failed to initialize");

And here is another one that does contain personally identifiable information:

FirebaseCrash.service.log(user.getEmailAddress() + " purchased product " + product.getID());

If identifying a user is necessary to diagnose an issue, then you must use adequate obfuscation measures to render the data you send to Google anonymous.

- + \ No newline at end of file diff --git a/docs/firebase/crash/usage/index.html b/docs/firebase/crash/usage/index.html index f3f8ded57ca..cc7830ee872 100644 --- a/docs/firebase/crash/usage/index.html +++ b/docs/firebase/crash/usage/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ the forceCrash function.

FirebaseCrash.service.forceCrash();

This creates an error that will cause your application to crash. Your application may continue to operate on some operating systems, however you should consider the application unstable after calling this function.

- + \ No newline at end of file diff --git a/docs/firebase/crashlytics/add-the-extension/index.html b/docs/firebase/crashlytics/add-the-extension/index.html index 97caecd65ea..31fe14451e1 100644 --- a/docs/firebase/crashlytics/add-the-extension/index.html +++ b/docs/firebase/crashlytics/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Crashlytics - Add the extension

AIR SDK

The recent releases of the Crashlytics extension requires at least version 33.1.1.345 of the AIR SDK. Using anything less than this will mean you will not get crash reports delivered to the console on iOS!

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.firebase.Crashlytics

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.firebase.Crashlytics.ane # Firebase Crashlytics extension
| |____ com.distriqt.Firebase.ane # Firebase extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Android

On Android you will need to add a unique "build_id" to the values.xml resources file you created for your project Firebase configuration. Generate a random UUID and add the following line to the values.xml with your UUID:

<string name="com.crashlytics.android.build_id" translatable="false">f76fbceb-74da-4db8-bd6a-def417dd104e</string>

You can generate a random UUID here: https://www.uuidgenerator.net/version4

- + \ No newline at end of file diff --git a/docs/firebase/crashlytics/introduction/index.html b/docs/firebase/crashlytics/introduction/index.html index 9d46e18380b..54d9a79cde8 100644 --- a/docs/firebase/crashlytics/introduction/index.html +++ b/docs/firebase/crashlytics/introduction/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Crashlytics - Introduction

Get clear, actionable insight into app issues with this powerful crash reporting solution for Android and iOS.

About

Firebase Crashlytics is a lightweight, realtime crash reporter that helps you track, prioritize, and fix stability issues that erode your app quality. Crashlytics saves you troubleshooting time by intelligently grouping crashes and highlighting the circumstances that lead up to them.

Find out if a particular crash is impacting a lot of users. Get alerts when an issue suddenly increases in severity. Figure out which lines of code are causing crashes.

YOUTUBE

https://firebase.google.com/docs/crashlytics/

Key capabilities

Curated crash reportsCrashlytics synthesizes an avalanche of crashes into a manageable list of issues, provides contextual information, and highlights the severity and prevalence of crashes so you can pinpoint the root cause faster.
Cures for the common crashCrashlytics offers Crash Insights, helpful tips that highlight common stability problems and provide resources that make them easier to troubleshoot, triage, and resolve.
Integrated with AnalyticsCrashlytics can capture your app's errors as app_exception events in Analytics. The events simplify debugging by giving you access a list of other events leading up to each crash, and provide audience insights by letting you pull Analytics reports for users with crashes.
Realtime alertsGet realtime alerts for new issues, regressed issues, and growing issues that might require immediate attention.
- + \ No newline at end of file diff --git a/docs/firebase/crashlytics/testing/index.html b/docs/firebase/crashlytics/testing/index.html index fc153f7f5bb..bb8299c93cf 100644 --- a/docs/firebase/crashlytics/testing/index.html +++ b/docs/firebase/crashlytics/testing/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Crashlytics - Testing

Test your Firebase Crashlytics implementation

Force a crash to test your implementation

You don't have to wait for a crash to know that Crashlytics is working. You can call forceCrash() to force a crash:

FirebaseCrashlytics.service.forceCrash();

When testing, reopen your app after calling the forceCrash method to make sure Crashlytics has a chance to report the crash. The report should appear in the Firebase console within five minutes.

Enable Crashlytics debug logging

If your forced crash didn't crash, crashed before you wanted it to, or you're experiencing some other issue with Crashlytics, you can enable Crashlytics debug logging to track down the problem.

Enabling debug mode will result in more logs being output to the logs which you can access via this tutorial:

/docs/tutorials/device-logs

Android

To enable debug logging on your development device, set an adb shell flag before running your app:

adb shell setprop log.tag.FirebaseCrashlytics DEBUG

adb is a command line tool available in the AIR SDK

iOS

With iOS you have to launch your application with a specific flag. This is not possible using AIR SDK, however using the libimobiledevice tools it is possible to launch an application on your device with this flag.

Firstly you will need to install these tools.

You can access installers in various locations but we suggest using homebrew:

brew install --HEAD usbmuxd
brew install --HEAD libimobiledevice
brew install --HEAD ideviceinstaller

We found you have to use the HEAD version to get it to work currently

Then to launch the application with the debugging FIRDebugEnabled flag:

idevicedebug run "com.distriqt.test" "-FIRDebugEnabled"
- + \ No newline at end of file diff --git a/docs/firebase/crashlytics/uploading-dsyms/index.html b/docs/firebase/crashlytics/uploading-dsyms/index.html index 5b993572d7a..b0e03e2e0b9 100644 --- a/docs/firebase/crashlytics/uploading-dsyms/index.html +++ b/docs/firebase/crashlytics/uploading-dsyms/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Crashlytics - Uploading dSYMs

On Android your crash logs will appear in the dashboard in around 5 minutes however you will not see your iOS logs unless you upload the debugging information file generated for your iOS IPA.

All the debug information for your iOS application is contained in a dSYM file.

Firebase Crashlytics automatically processes your debug symbol (.dSYM) files to give you deobfuscated, human-readable crash reports. You can no longer manually upload dSYMs through the console and instead have to upload them using a script.

caution

If you don't upload a dSYM for each version of your application there will be a warning displayed about missing dSYMs in the console and detailed information for any crashes of that version will not be shown in the console.

Generating a dSYM for your AIR application

dSYM directory should be generated by AIR alongside your IPA. If not you may have to check your applications build setup and environment to ensure AIR can generate the debugging symbols.

danger

Currently the dSYM directory will only be produced by the AIR SDK on macOS build systems. We encourage you to use a macOS machine to build your iOS applications.

Uploading

Once you have located your dSYM you will need to use the upload-symbols command line utility to upload the data to Firebase.

Copy the scripts/upload-symbols utility from the repository to a location on your machine and open a Terminal in that location. Then run the following command:

./upload-symbols -gsp PATH/TO/YOUR/GoogleService-Info.plist -p ios PATH/TO/YOUR/APPNAME.app.dSYM

You will need to pass the GoogleService-Info.plist location to identify your application and the path to your dSYM.

- + \ No newline at end of file diff --git a/docs/firebase/crashlytics/usage/index.html b/docs/firebase/crashlytics/usage/index.html index bfe640d6948..d1f3f9fcfd2 100644 --- a/docs/firebase/crashlytics/usage/index.html +++ b/docs/firebase/crashlytics/usage/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Crashlytics - Usage

Usage

In order to enable collection of crash reports you simply need to call enableCollection() at some point in your application after having initialised your Firebase app.

Firebase.service.initialiseApp();

FirebaseCrashlytics.service.enableCollection();

Customise Crash Reports

Enable opt-in reporting

By default, Firebase Crashlytics automatically collects crash reports for all your app's users. To give users more control over the data they send, you can enable opt-in reporting instead.

To do that, you have to disable automatic collection and initialize Crashlytics only for opt-in users.

Then you can ask your user to opt-in as required only calling the crashlytics function enableCollection() after the user agrees:

FirebaseCrashlytics.service.enableCollection();

To turn off automatic collection use the following methods dependent on your platform:

Android

Turn off automatic collection with a meta-data tag in your manifest additions, with in the application tag:

<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />

iOS

Turn off automatic collection with a new key to your InfoAdditions:

<key>FirebaseCrashlyticsCollectionEnabled</key>
<false/>

Add custom logs

To give yourself more context for the events leading up to a crash, you can add custom Crashlytics logs to your app. Crashlytics associates the logs with your crash data and makes them visible in the Firebase console.

FirebaseCrashlytics.service.log( "a log message" );

To avoid slowing down your app, Crashlytics limits logs to 64kB. Crashlytics deletes older log entries if a session's logs go over that limit.

Add custom keys

Custom keys help you get the specific state of your app leading up to a crash. You can associate arbitrary key/value pairs with your crash reports, and see them in the Firebase console.

There are several methods to set keys. Each handles a different data type:

FirebaseCrashlytics.service.setIntValue( 1 /* int value */, key );

FirebaseCrashlytics.service.setNumericValue( 1.0 /* Number value */, key );

FirebaseCrashlytics.service.setBooleanValue( true /* Boolean value */, key );

FirebaseCrashlytics.service.setStringValue( "a value" /* String value */, key );

The key value is a String.

Set user IDs

To diagnose an issue, it’s often helpful to know which of your users experienced a given crash. Crashlytics includes a way to anonymously identify users in your crash reports.

To add user IDs to your reports, assign each user a unique identifier in the form of an ID number, token, or hashed value:

FirebaseCrashlytics.service.setUserIdentifier( "user123456789" );

If you ever need to clear a user identifier after you set it, reset the value to a blank string. Clearing a user identifier does not remove existing Crashlytics records. If you need to delete records associated with a user ID, contact Firebase support.

Log non-fatal exceptions

In addition to automatically reporting your app’s crashes, Crashlytics lets you log non-fatal exceptions.

You do this by calling the recordError() method, passing an Error object:

var e:Error = ...;

FirebaseCrashlytics.service.recordError( e );

All logged exceptions appear as non-fatal issues in the Firebase console.

Crashlytics only stores the most recent 8 exceptions in a given app session. If your app throws more than 8 exceptions in a session, older exceptions are lost.

Manage Crash Insights data

Crash Insights helps you resolve issues by comparing your anonymized stack traces to traces from other Firebase apps and letting you know if your issue is part of a larger trend. For many issues, Crash Insights even provides resources to help you debug the crash.

Crash Insights uses aggregated crash data to identify common stability trends. If you’d prefer not to share your app's data, you can opt-out of Crash Insights from the Crash Insights menu at the top of your Crashlytics issue list in the Firebase console.

- + \ No newline at end of file diff --git a/docs/firebase/database/add-the-extensions/index.html b/docs/firebase/database/add-the-extensions/index.html index 2775630f078..2cca04f8e6f 100644 --- a/docs/firebase/database/add-the-extensions/index.html +++ b/docs/firebase/database/add-the-extensions/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Database - Add the extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.firebase.Database

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.firebase.Database.ane # Firebase Database extension
| |____ com.distriqt.Firebase.ane # Firebase extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/firebase/database/configure-database-rules/index.html b/docs/firebase/database/configure-database-rules/index.html index 310b56da16e..e6c1adfe4da 100644 --- a/docs/firebase/database/configure-database-rules/index.html +++ b/docs/firebase/database/configure-database-rules/index.html @@ -13,7 +13,7 @@ - + @@ -42,7 +42,7 @@ means anyone can read or write to your database. You should configure more secure rules before launching your app.

// These rules give anyone, even people who are not users of your app,
// read and write access to your database
{
"rules": {
".read": true,
".write": true
}
}

User

Here's an example of a rule that gives each authenticated user a personal node at /users/$user_id where $user_id is the ID of the user obtained through Authentication. This is a common scenario for any apps that have data private to a user.

// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}

It is essential that you configure these rules correctly before launching your app to ensure that your users can only access the data that they are supposed to.

More Information

For more information read the Database Rules Guide

- + \ No newline at end of file diff --git a/docs/firebase/database/delete-data/index.html b/docs/firebase/database/delete-data/index.html index 4ca279fa175..be56dcaa694 100644 --- a/docs/firebase/database/delete-data/index.html +++ b/docs/firebase/database/delete-data/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ the location of that data.

You can also delete by specifying null as the value for another write operation such as setValue() or updateChildren(). You can use this technique with updateChildren() to delete multiple children in a single API call.

- + \ No newline at end of file diff --git a/docs/firebase/database/disconnect/index.html b/docs/firebase/database/disconnect/index.html index 18875743586..1473ac20fc5 100644 --- a/docs/firebase/database/disconnect/index.html +++ b/docs/firebase/database/disconnect/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ app if it is invalid. The server then monitors the connection. If at any point the connection times out, or is actively closed by the Realtime Database client, the server checks security a second time (to make sure the operation is still valid) and then invokes the event.

Cancel

An onDisconnect event can also be canceled by calling cancel():

presenceRef.onDisconnect().cancel();
- + \ No newline at end of file diff --git a/docs/firebase/database/initialise/index.html b/docs/firebase/database/initialise/index.html index 0162331b1ab..a569aaaec08 100644 --- a/docs/firebase/database/initialise/index.html +++ b/docs/firebase/database/initialise/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/firebase/database/introduction/index.html b/docs/firebase/database/introduction/index.html index 298305ac7d0..d0619bf3da2 100644 --- a/docs/firebase/database/introduction/index.html +++ b/docs/firebase/database/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ tables or records. When you add data to the JSON tree, it becomes a node in the existing JSON structure with an associated key. You can provide your own keys, such as user IDs or semantic names, or they can be provided for you using push().

Best practices for data structure:

Read more about structuring your database here

- + \ No newline at end of file diff --git a/docs/firebase/database/lists/index.html b/docs/firebase/database/lists/index.html index 010ed957b59..d27240f4434 100644 --- a/docs/firebase/database/lists/index.html +++ b/docs/firebase/database/lists/index.html @@ -13,7 +13,7 @@ - + @@ -67,7 +67,7 @@ 600:

var query:Query = FirebaseDatabase.service.getReference( "list" ).startAt( 600, "count" );

How query data is ordered

This section explains how data is sorted by each of the order-by methods in the Query class.

orderByChild

When using orderByChild(), data that contains the specified child key is ordered as follows:

orderByKey

When using orderByKey() to sort your data, data is returned in ascending order by key.

orderByValue

When using orderByValue(), children are ordered by their value. The ordering criteria are the same as in orderByChild(), except the value of the node is used instead of the value of a specified child key.

- + \ No newline at end of file diff --git a/docs/firebase/database/offline/index.html b/docs/firebase/database/offline/index.html index 5bc826a76b3..cb1a786479b 100644 --- a/docs/firebase/database/offline/index.html +++ b/docs/firebase/database/offline/index.html @@ -13,7 +13,7 @@ - + @@ -48,7 +48,7 @@ most applications. If the cache outgrows its configured size, the Firebase Realtime Database purges data that has been used least recently. Data that is kept in sync is not purged from the cache.

- + \ No newline at end of file diff --git a/docs/firebase/database/read-data-and-change-events/index.html b/docs/firebase/database/read-data-and-change-events/index.html index 4dd21c93baa..f0fa2f395cf 100644 --- a/docs/firebase/database/read-data-and-change-events/index.html +++ b/docs/firebase/database/read-data-and-change-events/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ function to handle the result.

var ref:DatabaseReference = FirebaseDatabase.service.getReference( "test" );

ref.once( function( value:Object ):void
{
if (value != null)
{
trace( JSON.stringify( value ) );
}
else
{
// There was an error
}
});

The once function takes a Function as a parameter which will be called when the value has been read. This function should have one parameter of type Object which will be the resulting value of the read operation. This value may be null if an error occurred.

- + \ No newline at end of file diff --git a/docs/firebase/database/transactions/index.html b/docs/firebase/database/transactions/index.html index 0cdf836ec14..b9d4bf4c5fa 100644 --- a/docs/firebase/database/transactions/index.html +++ b/docs/firebase/database/transactions/index.html @@ -13,7 +13,7 @@ - + @@ -36,7 +36,7 @@ null data. Even if there is existing data in your remote database, it may not be locally cached when the transaction function is run, resulting in null for the initial value.

- + \ No newline at end of file diff --git a/docs/firebase/database/write-data/index.html b/docs/firebase/database/write-data/index.html index 272d3337e94..5532f25e318 100644 --- a/docs/firebase/database/write-data/index.html +++ b/docs/firebase/database/write-data/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ helps construct the correct parameters to pass to the updateChildren function.

It's usage is quite straight forward, simply construct an instance of the builder, then call update for each value update you intend to perform passing the path to the value and the new value.

var ref:DatabaseReference = FirebaseDatabase.service.getReference( "test" );

ref.updateChildren(
new UpdateChildrenBuilder()
.update( "/children_test/numericValue", 100 )
.update( "/children_test/stringValue", "some string" )
.build()
);
- + \ No newline at end of file diff --git a/docs/firebase/dynamiclinks/add-the-extension/index.html b/docs/firebase/dynamiclinks/add-the-extension/index.html index 8a1546df33c..dff42f54ab1 100644 --- a/docs/firebase/dynamiclinks/add-the-extension/index.html +++ b/docs/firebase/dynamiclinks/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ such as accessing Safari saved passwords and activity continuation.

To do this, log into the member center and open your App IDs

Select your App ID and select "Edit". You need to enable the "Associated Domains" service as below:

Note: You will need to regenerate and download your provisioning profiles after making this change.

Info Additions and Entitlements

You will firstly need to add any custom url scheme to your info additions, by adding the following and replacing APP_SCHEME with your applications custom url scheme:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>APP_SCHEME</string>
</array>
</dict>
</array>

You need to add the associated domain to your iOS Entitlements section, replacing APP_CODE below with your Dynamic Links domain.

<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:APP_CODE.app.goo.gl</string>
</array>

If you want to receive Dynamic Links with a fully-custom domain you will need to add the FirebaseDynamicLinksCustomDomains key to your info additions and specify your app's Dynamic Links URL prefixes:

<key>FirebaseDynamicLinksCustomDomains</key>
<array>
<string>https://example.com/link</string>
<string>https://example.com/promos</string>
</array>

Firstly add a custom iOS configuration file by running:

apm generate config ios

Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the CFBundleURLTypes and FirebaseDynamicLinksCustomDomains (if required) replacing APP_SCHEME as required:

<plist version="1.0">
<dict>

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>APP_SCHEME</string>
</array>
</dict>
</array>

<key>FirebaseDynamicLinksCustomDomains</key>
<array>
<string>https://example.com/link</string>
<string>https://example.com/promos</string>
</array>

</dict>
</plist>

Edit the config/ios/Entitlements.xml file that was generated to resemble the following, replacing APP_CODE as required:

<plist version="1.0">
<dict>

<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:APP_CODE.app.goo.gl</string>
</array>

</dict>
</plist>

Once you have added this configuration run the steps above to update / generate your application descriptor.

- + \ No newline at end of file diff --git a/docs/firebase/dynamiclinks/create-dynamic-links/index.html b/docs/firebase/dynamiclinks/create-dynamic-links/index.html index a3119fd154e..8bef603202c 100644 --- a/docs/firebase/dynamiclinks/create-dynamic-links/index.html +++ b/docs/firebase/dynamiclinks/create-dynamic-links/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ setContent | Google Play analytics parameters. These parameters (utm_source, utm_medium, utm_campaign, utm_term, utm_content) are passed on to the Play Store as well as appended to the link payload. |

See the GoogleAnalyticsParametersBuilder class for more.

Itunes Connect Analytics Parameters

| setProviderToken setAffiliateToken setCampaignToken | iTunes Connect analytics parameters. These parameters (pt, at, ct) are passed to the App Store. |

See the ItunesConnectAnalyticsParametersBuilder class for more.

Social Meta Tag Parameters
setTitleThe title to use when the Dynamic Link is shared in a social post
setDescriptionThe description to use when the Dynamic Link is shared in a social post
setImageUrlThe URL to an image related to this link

See the SocialMetaTagParametersBuilder class for more.

- + \ No newline at end of file diff --git a/docs/firebase/dynamiclinks/initialise/index.html b/docs/firebase/dynamiclinks/initialise/index.html index da69c72acb1..22c035f9145 100644 --- a/docs/firebase/dynamiclinks/initialise/index.html +++ b/docs/firebase/dynamiclinks/initialise/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

DynamicLinks - Initialise

Setting Scheme

On iOS you must set the deepLinkURLScheme in the extension to correctly handle opened links on versions of iOS that use custom url scheme.

This is the same url scheme (APP_SCHEME) that you added to the info additions previously when adding the extension

The easiest way to do this is set as below, before calling initialiseApp():

Firebase.service.deepLinkURLScheme = "APP_SCHEME";
Firebase.service.initialiseApp();

If you are passing your own FirebaseOptions to initialiseApp you can specify the scheme as part of the options:

var options:FirebaseOptions = new FirebaseOptions();
// Other options
options.deepLinkURLScheme = "APP_SCHEME";

Firebase.service.initialiseApp( options );

Note: You cannot use these two methods together

Example

To match the example scheme added in the iOS info additions example:

Firebase.service.deepLinkURLScheme = "distriqt";
Firebase.service.initialiseApp();
- + \ No newline at end of file diff --git a/docs/firebase/dynamiclinks/introduction/index.html b/docs/firebase/dynamiclinks/introduction/index.html index 0d5f6c6b8c4..d1b230650e7 100644 --- a/docs/firebase/dynamiclinks/introduction/index.html +++ b/docs/firebase/dynamiclinks/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ the links you want to open, depending on the user's platform and whether your app is installed.

When a user opens one of your Dynamic Links, if your app isn't yet installed, the user is sent to the Play Store or App Store to install your app (unless you specify otherwise), and your app opens. You can then retrieve the link that was passed to your app and handle the link as appropriate for your app.

- + \ No newline at end of file diff --git a/docs/firebase/dynamiclinks/receive-dynamic-links/index.html b/docs/firebase/dynamiclinks/receive-dynamic-links/index.html index ec63d355e50..1482f311957 100644 --- a/docs/firebase/dynamiclinks/receive-dynamic-links/index.html +++ b/docs/firebase/dynamiclinks/receive-dynamic-links/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

DynamicLinks - Receive Dynamic Links

Receiving dynamic links is simply a matter of listening for the DynamicLinkEvent.RECEIVED event.

When you add a listener for this event the extension will check for any dynamic links that may have started your application and dispatch them, so you should be prepared to
receive an event shortly after adding the listener:

FirebaseDynamicLinks.service.addEventListener( DynamicLinkEvent.RECEIVED, dynamicLink_receivedHandler );

The DynamicLinkEvent contains a data parameter which will be an instance of the PendingDynamicLinkData class. The PendingDynamicLinkData contains information about the link including the link parameter and additional information such as the matchType.

function dynamicLink_receivedHandler( event:DynamicLinkEvent ):void
{
trace( "dynamicLink_receivedHandler(): " + event.data.link );
}

Initialising Core callbacks

In order to receive events from start up you will need to ensure you call Core.init() before initialising any of the Firebase functionality.

- + \ No newline at end of file diff --git a/docs/firebase/dynamiclinks/testing/index.html b/docs/firebase/dynamiclinks/testing/index.html index 2e0bd12ecd5..befea36e59c 100644 --- a/docs/firebase/dynamiclinks/testing/index.html +++ b/docs/firebase/dynamiclinks/testing/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ or click on a link from a page.

It should display an "Open App" button if your application is installed which you can click to launch your application, and if you have setup a custom scheme correctly it should automatically redirect to your application.

- + \ No newline at end of file diff --git a/docs/firebase/fcm/introduction/index.html b/docs/firebase/fcm/introduction/index.html index 5c78831a81b..09ec11137c6 100644 --- a/docs/firebase/fcm/introduction/index.html +++ b/docs/firebase/fcm/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ powerful built-in targeting and analytics, you can use Notifications. For deployments with more complex messaging requirements, FCM is the right choice.

AIR Integration

Our highly tested Push Notifications ANE includes Firebase Cloud Messaging and Firebase In-App Messaging.

We chose to integrate it into our existing ANE to allow you to easily switch between push notification services, including APNS, GCM, FCM and OneSignal.

This means that you can easily integrate FCM in your application using that extension in combination with the core Firebase ANE. The core and config Firebase ANEs are required to include the neccessary SDK and configure your application for Firebase.

Follow the guide in the Push Notifications ANE wiki to get started with Firebase Cloud Messaging:

- + \ No newline at end of file diff --git a/docs/firebase/firestore/add-data/index.html b/docs/firebase/firestore/add-data/index.html index 18850fce121..37a13915b74 100644 --- a/docs/firebase/firestore/add-data/index.html +++ b/docs/firebase/firestore/add-data/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Add Data

Add data

Cloud Firestore stores data in Documents, which are stored in Collections. Cloud Firestore creates collections and documents implicitly the first time you add data to the document. You do not need to explicitly create collections or documents.

There are several ways to write data to Cloud Firestore:

  • Set the data of a document within a collection, explicitly specifying a document identifier.
  • Add a new document to a collection. In this case, Cloud Firestore automatically generates the document identifier.
  • Create an empty document with an automatically generated identifier, and assign data to it later.

This guide explains how to use the setDocument(), add(), or update() methods to write data to individual documents in Cloud Firestore.

Set a document

To create or overwrite a single document, use the setDocument() method:

var city:Object = {
name: "Los Angeles",
state: "CA",
country: "USA"
};

var document:DocumentReference = FirebaseFirestore.service.collection( "cities" ).document( "LA" );

document.addEventListener( DocumentReferenceEvent.SET_SUCCESS, successHandler );
document.addEventListener( DocumentReferenceEvent.SET_ERROR, errorHandler );
document.setDocument( city );

The setDocument() call will dispatch one of two events:

  • DocumentReferenceEvent.SET_SUCCESS: The document has been correctly set with the new data
  • DocumentReferenceEvent.SET_ERROR: There was an error setting the data to the document

You should ensure you remove the event listeners at this point to ensure the extension can correctly clean up memory usage of unused document references.

function successHandler( event:DocumentReferenceEvent ):void
{
event.currentTarget.removeEventListener( DocumentReferenceEvent.SET_SUCCESS, successHandler );
event.currentTarget.removeEventListener( DocumentReferenceEvent.SET_ERROR, errorHandler );

trace( "Set Document: Success" );
}

function errorHandler( event:DocumentReferenceEvent ):void
{
event.currentTarget.removeEventListener( DocumentReferenceEvent.SET_SUCCESS, successHandler );
event.currentTarget.removeEventListener( DocumentReferenceEvent.SET_ERROR, errorHandler );

trace( "Get Document Error: " + event.message );
}

Alternatively you can add a success and failure listener directly:

document.setDocument( city )
.addOnSuccessListener( function( snapshot:DocumentSnapshot ):void {
// Document was successfully set
})
.addOnFailureListener( function( message:String ):void {
// Error occurred
});

If the document does not exist, it will be created. If the document does exist, its contents will be overwritten with the newly provided data, unless you specify that the data should be merged into the existing document, as follows:

document.setDocument( city, SetOptions.merge() );

If you're not sure whether the document exists, pass the option to merge the new data with any existing document to avoid overwriting entire documents.

Data types

Cloud Firestore lets you write a variety of data types inside a document, including strings, booleans, numbers, dates, null, and nested arrays and objects. Cloud Firestore always stores numbers as doubles, regardless of what type of number you use in your code.

var data:Object = {
stringExample: "Hello world!",
booleanExample: true,
numberExample: 3.14159265,
dateExample: new Date(),
nullExample: null,
arrayExample: [ 1, 2, 3 ],
nestedData: {
a: 5,
b: true
}
};

Blob

You can use a Blob (com.distriqt.extension.firebase.firestore.Blob) to add ByteArray style data to your documents.

The Blob data type inherits from a ByteArray and handles conversion to and from the Firestore Blob format. So you can simply use the standard ByteArray functions to store data and then add it to your document.

For example, construct a Blob and write 2 bytes to it:

var bytes:Blob = new Blob();
bytes.writeByte(0xa0);
bytes.writeByte(0x7f);

Then use this as a value in your data object and pass it to setDocument():

var data:Object = {
title: "Some data",
byteData: bytes
};

document.setDocument( data );

Custom objects

Not currently supported

Add a document

When you use setDocument() to create a document, you must specify an ID for the document to create. For example:

FirebaseFirestore.service.collection( "cities" ).document( "LA" ).setDocument(data);

But sometimes there isn't a meaningful ID for the document, and it's more convenient to let Cloud Firestore auto-generate an ID for you. You can do this by calling add():

var collection:CollectionReference = FirebaseFirestore.service.collection( "cities" );

collection.addEventListener( CollectionReferenceEvent.ADD_SUCCESS, successHandler );
collection.addEventListener( CollectionReferenceEvent.ADD_ERROR, errorHandler );
collection.add( data );

function successHandler( event:CollectionReferenceEvent ):void
{
event.currentTarget.removeEventListener( CollectionReferenceEvent.ADD_SUCCESS, successHandler );
event.currentTarget.removeEventListener( CollectionReferenceEvent.ADD_ERROR, errorHandler );

trace( "Add Success: document.getId() = " + event.document.getId() );
trace( "Add Success: document.getPath() = " + event.document.getPath() );
}

function errorHandler( event:CollectionReferenceEvent ):void
{
event.currentTarget.removeEventListener( CollectionReferenceEvent.ADD_SUCCESS, successHandler );
event.currentTarget.removeEventListener( CollectionReferenceEvent.ADD_ERROR, errorHandler );

trace( "Add Error: " + event.message );
}

In some cases, it can be useful to create a document reference with an auto-generated ID, then use the reference later. For this use case, you can call document():

var document:DocumentReference = FirebaseFirestore.service.collection( "cities" ).document();

// ... later
document.set( data );

Behind the scenes, .add(...) and .document().setDocument(...) are completely equivalent, so you can use whichever is more convenient.

Update a document

To update some fields of a document without overwriting the entire document, use the update() method:

var changes:Object = {
population: 4018000
};

var document:DocumentReference = FirebaseFirestore.service.collection( "cities" ).document( "LA" );

document.addEventListener( DocumentReferenceEvent.UPDATE_SUCCESS, successHandler );
document.addEventListener( DocumentReferenceEvent.UPDATE_ERROR, errorHandler );
document.update( changes );


function successHandler( event:DocumentReferenceEvent ):void
{
event.currentTarget.removeEventListener( DocumentReferenceEvent.UPDATE_SUCCESS, successHandler );
event.currentTarget.removeEventListener( DocumentReferenceEvent.UPDATE_ERROR, errorHandler );

trace( "Update Success" );
}

function errorHandler( event:DocumentReferenceEvent ):void
{
event.currentTarget.removeEventListener( DocumentReferenceEvent.UPDATE_SUCCESS, successHandler );
event.currentTarget.removeEventListener( DocumentReferenceEvent.UPDATE_ERROR, errorHandler );

trace( "Update Error: " + event.message );
}

You can also add server timestamps to specific fields in your documents, to track when an update was received by the server:

var changes:Object = {
population: 4018000,
timestamp: FieldValue.serverTimestamp()
};

var document:DocumentReference = FirebaseFirestore.service.collection( "cities" ).document( "LA" );

document.update( changes );
- + \ No newline at end of file diff --git a/docs/firebase/firestore/add-the-extension/index.html b/docs/firebase/firestore/add-the-extension/index.html index 381e8b39812..a81c0353c26 100644 --- a/docs/firebase/firestore/add-the-extension/index.html +++ b/docs/firebase/firestore/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ These client libraries aren't packaged with this ANE as they are used by multiple ANEs and separating them will avoid conflicts, allowing you to use multiple ANEs in the one application.

This ANE requires the following Google Play Services:

You must include the above native extensions in your application along with this extension, and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Square ANEs

Due to several of our ANE's using the Square open source libraries the libraries have been separated into a separate ANEs allowing you to avoid conflicts and duplicate definitions. This means that you need to include the some of the square native extensions in your application along with this extension.

You will add these extensions as you do with any other ANE, and you need to ensure it is packaged with your application.

This ANE requires the following Square extensions:

You can access these extensions here: https://github.com/distriqt/ANE-SquareLibs.

Guava

Add the com.google.guava extension which adds support for Google Guava libraries in the application. This extension is available in the Android support repository:

gRPC

Add the io.grpc extension which adds support for gRPC libraries in the application. This extension is available in the Android support repository:

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Create a Cloud Firestore project

  1. Open the Firebase Console and create a new project.

  2. In the Database section, click the Get Started button for Cloud Firestore.

  3. Select a starting mode for your Cloud Firestore Security Rules:

  1. Click Enable.
- + \ No newline at end of file diff --git a/docs/firebase/firestore/delete-data/index.html b/docs/firebase/firestore/delete-data/index.html index b50b8e69806..18567af6725 100644 --- a/docs/firebase/firestore/delete-data/index.html +++ b/docs/firebase/firestore/delete-data/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Delete data

Delete documents

To delete a document, use the deleteDocument() method:

FirebaseFirestore.service.collection("cities").document("DC")
.deleteDocument();

When you delete a document, Cloud Firestore does not automatically delete the documents within its subcollections. You can still access the subcollection documents by reference. For example, you can access the document at path /mycoll/mydoc/mysubcoll/mysubdoc even if you delete the ancestor document at /mycoll/mydoc.

Non-existent ancestor documents appear in the console, but they do not appear in query results and snapshots.

If you want to delete a document and all the documents within its subcollections, you must do so manually. For more information, see Delete Collections.

Delete fields

To delete specific fields from a document, use the FieldValue.deleteValue() method when you update a document:

var document:DocumentReference = FirebaseFirestore.service.collection("cities").document("DC");

var updates:Object = {
captial: FieldValue.deleteValue()
};

document.update( updates );

Delete collections

To delete an entire collection or subcollection in Cloud Firestore, retrieve all the documents within the collection or subcollection and delete them. If you have larger collections, you may want to delete the documents in smaller batches to avoid out-of-memory errors. Repeat the process until you've deleted the entire collection or subcollection.

Deleting a collection requires coordinating an unbounded number of individual delete requests. If you need to delete entire collections, do so only from a trusted server environment. While it is possible to delete a collection from a mobile/web client, doing so has negative security and performance implications.

To learn more about one recommended approach to deleting collections in production, see Deleting Collections and Subcollections.

- + \ No newline at end of file diff --git a/docs/firebase/firestore/enable-offline-data/index.html b/docs/firebase/firestore/enable-offline-data/index.html index 74467518f46..c7baf882927 100644 --- a/docs/firebase/firestore/enable-offline-data/index.html +++ b/docs/firebase/firestore/enable-offline-data/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Enable offline data

Cloud Firestore supports offline data persistence. This feature caches a copy of the Cloud Firestore data that your app is actively using, so your app can access the data when the device is offline. You can write, read, listen to, and query the cached data. When the device comes back online, Cloud Firestore synchronizes any local changes made by your app to the data stored remotely in Cloud Firestore.

Note: Offline persistence is supported only in Android, iOS, and web apps.

To use offline persistence, you don't need to make any changes to the code that you use to access Cloud Firestore data. With offline persistence enabled, the Cloud Firestore client library automatically manages online and offline data access and synchronizes local data when the device is back online.

Configure offline persistence

When you initialize Cloud Firestore, you can enable or disable offline persistence:

  • For Android and iOS, offline persistence is enabled by default. To disable persistence, set the isPersistenceEnabled option to false.
var settings:FirebaseFirestoreSettings = FirebaseFirestore.service.getFirestoreSettings();
settings.isPersistenceEnabled = false;

FirebaseFirestore.service.setFirestoreSettings( settings );
- + \ No newline at end of file diff --git a/docs/firebase/firestore/get-data/index.html b/docs/firebase/firestore/get-data/index.html index 869979c6bde..965a01596f0 100644 --- a/docs/firebase/firestore/get-data/index.html +++ b/docs/firebase/firestore/get-data/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ or document will result in the object not being removed from memory.

Source Options

For platforms with offline support, you can set the source option to control how a get call uses the offline cache.

By default, a get call will attempt to fetch the latest document snapshot from your database. On platforms with offline support, the client library will use the offline cache if the network is unavailable or if the request times out.

You can specify the source option in a getDocument() call to change the default behavior. You can fetch from only the database and ignore the offline cache, or you can fetch from only the offline cache. For example:

FirebaseFirestore.service.document("path")
.getDocument( Source.CACHE )
.addOnSuccessListener( function( snapshot:DocumentSnapshot ):void
{
// Document found in the offline cache and exists should be true
if (event.snapshot.exists())
{
trace( "Document data: " + JSON.stringify( event.snapshot.getData() ) );
}
else
{
trace( "Get Document: Does not exist" );
}
})
.addOnFailureListener( function( message:String ):void
{
trace( "get document :: failed :: " + message );
});

Get multiple documents from a collection

You can also retrieve multiple documents with one request by querying documents in a collection. For example, you can use whereEqualTo() to query for all of the documents that meet a certain condition, then use query() to retrieve the results.

As with most of the functionality in this extension you can either use success and failure listeners or event listeners to handle the responses.

Using Success and Failure Listeners

The following example shows how to retrieve the result of the query using success and failure listeners. The listeners should be added after the query() call using the addOnQuerySuccessHandler and addOnQueryFailureListener functions:

FirebaseFirestore.service.collection("users")
.whereEqualTo( "born", 1980 )
.query()
.addOnQuerySuccessHandler( function( snapshot:QuerySnapshot ):void
{
trace( "addOnQuerySuccessHandler" );
})
.addOnQueryFailureListener( function( message:String ):void
{
trace( "addOnQueryFailureListener: " + message );
});

Using Event Listeners

The following example shows how to retrieve the result of the query using event listeners:

var query:Query = FirebaseFirestore.service.collection("users")
.whereEqualTo( "born", 1980 );

query.addEventListener( QueryEvent.SUCCESS, querySuccessHandler );
query.addEventListener( QueryEvent.ERROR, queryErrorHandler );

query.query();

function querySuccessHandler( event:QueryEvent ):void
{
trace( "querySuccessHandler" );
event.currentTarget.removeEventListener( QueryEvent.SUCCESS, querySuccessHandler );
event.currentTarget.removeEventListener( QueryEvent.ERROR, queryErrorHandler );
}

function queryErrorHandler( event:QueryEvent ):void
{
trace( "queryErrorHandler: " + event.message );
event.currentTarget.removeEventListener( QueryEvent.SUCCESS, querySuccessHandler );
event.currentTarget.removeEventListener( QueryEvent.ERROR, queryErrorHandler );
}

Note: You need to ensure you remove event listeners after the result in order to allow the references to get garbage collected at the appropriate time. Leaving event listeners attached to a query, collection or document will result in the object not being removed from memory.

Get all documents in a collection

In addition, you can retrieve all documents in a collection by omitting the whereEqualTo() filter entirely and just referencing the collection.

FirebaseFirestore.service.collection("users")
.query()
.addOnQuerySuccessHandler( function( snapshot:QuerySnapshot ):void
{
trace( "addOnQuerySuccessHandler" );
})
.addOnQueryFailureListener( function( message:String ):void
{
trace( "addOnQueryFailureListener: " + message );
});

List subcollections of a document

The getCollections() method of the Cloud Firestore server client libraries lists all subcollections of a document reference.

Retrieving a list of collections is not possible with the mobile/web client libraries. You should only look up collection names as part of administrative tasks in trusted server environments. If you find that you need this capability in the mobile/web client libraries, consider restructuring your data so that subcollection names are predictable.

- + \ No newline at end of file diff --git a/docs/firebase/firestore/get-realtime-updates/index.html b/docs/firebase/firestore/get-realtime-updates/index.html index 1078ede67b6..e39b7970ae4 100644 --- a/docs/firebase/firestore/get-realtime-updates/index.html +++ b/docs/firebase/firestore/get-realtime-updates/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Get realtime updates

You can listen to document updates by adding a listener for the DocumentReference.SNAPSHOT_EVENT or by calling the addSnapshotListener() method.

Adding this listener to the document will create a snapshot event immediately with the current contents of the single document. Then, each time the contents change, another event will be dispatched with the updates to the document snapshot.

var document:DocumentReference = FirebaseFirestore.service.collection("cities").document("SF");
document.addSnapshotListener( snapshotEventHandler );

function snapshotEventHandler( event:DocumentReferenceEvent ):void
{
var snapshot:DocumentSnapshot = event.snapshot;
if (event.message != "")
{
trace( "Error fetching document: " + event.message );
}
else
{
if (snapshot != null && snapshot.exists())
{
trace( JSON.stringify( snapshot.getData() ) );
}
}
}

Events for local changes

Local writes in your app will invoke snapshot listeners immediately. This is because of an important feature called "latency compensation." When you perform a write, your listeners will be notified with the new data before the data is sent to the backend.

Retrieved documents have a metadata.hasPendingWrites property that indicates whether the document has local changes that haven't been written to the backend yet. You can use this property to determine the source of events received by your snapshot listener:

function snapshotEventHandler( event:DocumentReferenceEvent ):void 
{
var snapshot:DocumentSnapshot = event.snapshot;
if (event.message != null && event.message != "")
{
trace( "Error fetching document: " + event.message );
}
else
{
var source:String = snapshot.getMetadata().hasPendingWrites ? "Local" : "Server";
// ...
}
}

Events for metadata changes

When listening for changes to a document, collection, or query, you can pass options to control the granularity of events that your listener will receive.

By default, listeners are not notified of changes that only affect metadata. Consider what happens when your app writes a new document:

  • A change event is immediately fired with the new data. The document has not yet been written to the backend so so the "pending writes" flag is true.
  • The document is written to the backend.
  • The backend notifies the client of the successful write. There is no change to the document data, but there is a metadata change because the "pending writes" flag is now false.

If you want to receive snapshot events when the document or query metadata changes, pass a listen options object when attaching your listener:

document.addSnapshotListener( snapshotEventHandler, MetadataChanges.INCLUDE );

Listen to multiple documents in a collection

As with documents, you can use addSnapshotListener() instead of query() to listen to the results of a query. This creates a query snapshot. For example, to listen to the documents with state CA:

FirebaseFirestore.service.collection("cities")
.whereEqualTo("state", "CA")
.addSnapshotListener( querySnapshotEventHandler );

function querySnapshotEventHandler( event:QueryEvent ):void
{
if (event.message != null && event.message != "")
{
trace( "Error with query: " + event.message );
}
else
{
for each (var doc:DocumentSnapshot in event.snapshot.getDocuments())
{
// ... list cities in CA
}
}
}

The snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified).

Important: As explained above under Events for local changes, you will receive events immediately for your local writes. Your listener can use the metadata.hasPendingWrites field on each document to determine whether the document has local changes that have not yet been written to the backend.

View changes between snapshots

It is often useful to see the actual changes to query results between query snapshots, instead of simply using the entire query snapshot. For example, you may want to maintain a cache as individual documents are added, removed, and modified.

FirebaseFirestore.service.collection("cities")
.whereEqualTo("state", "CA")
.addSnapshotListener( querySnapshotEventHandler );

function querySnapshotEventHandler( event:QueryEvent ):void
{
if (event.message != null && event.message != "")
{
trace( "Error with query: " + event.message );
}
else
{
for each (var docChange:DocumentChange in event.snapshot.getDocumentChanges())
{
switch (docChange.changeType)
{
case DocumentChange.ADDED:
// New city
break;
case DocumentChange.MODIFIED:
// Nodified city
break;
case DocumentChange.REMOVED:
// Removed city
break;
}
}
}
}

Important: The first query snapshot contains added events for all existing documents that match the query. This is because you're getting a set of changes that bring your query snapshot current with the initial state of the query. This allows you, for instance, to directly populate your UI from the changes you receive in the first query snapshot, without needing to add special logic for handling the initial state.

The initial state can come from the server directly, or from a local cache. If there is state available in a local cache, the query snapshot will be initially populated with the cached data, then updated with the server's data when the client has caught up with the server's state.

Detach a listener

When you are no longer interested in listening to your data, you must detach your listener so that your event callbacks stop getting called. This allows the client to stop using bandwidth to receive updates.

You can use the removeSnapshotListener() function to remove your handler and stop updates.

FirebaseFirestore.service.collection("cities").document("SF")
.removeSnapshotListener( snapshotEventHandler );
- + \ No newline at end of file diff --git a/docs/firebase/firestore/introduction/index.html b/docs/firebase/firestore/introduction/index.html index 2f5949a25b3..3230e1fdaef 100644 --- a/docs/firebase/firestore/introduction/index.html +++ b/docs/firebase/firestore/introduction/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Introduction

Cloud Firestore

Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform. Like Firebase Realtime Database, it keeps your data in sync across client apps through realtime listeners and offers offline support for mobile and web so you can build responsive apps that work regardless of network latency or Internet connectivity. Cloud Firestore also offers seamless integration with other Firebase and Google Cloud Platform products, including Cloud Functions.

YOUTUBE

https://firebase.google.com/docs/storage/

Key capabilities

FlexibilityThe Cloud Firestore data model supports flexible, hierarchical data structures. Store your data in documents, organized into collections. Documents can contain complex nested objects in addition to subcollections.
Expressive queryingIn Cloud Firestore, you can use queries to retrieve individual, specific documents or to retrieve all the documents in a collection that match your query parameters. Your queries can include multiple, chained filters and combine filtering and sorting. They're also indexed by default, so query performance is proportional to the size of your result set, not your data set.
Realtime updatesLike Realtime Database, Cloud Firestore uses data synchronization to update data on any connected device. However, it's also designed to make simple, one-time fetch queries efficiently.
Offline supportCloud Firestore caches data that your app is actively using, so the app can write, read, listen to, and query data even if the device is offline. When the device comes back online, Cloud Firestore synchronizes any local changes back to Cloud Firestore.
Designed to scaleCloud Firestore brings you the best of Google Cloud Platform's powerful infrastructure: automatic multi-region data replication, strong consistency guarantees, atomic batch operations, and real transaction support. We've designed Cloud Firestore to handle the toughest database workloads from the world's biggest apps.

How does it work?

Cloud Firestore is a cloud-hosted, NoSQL database that your iOS, Android, and web apps can access directly via native SDKs. Cloud Firestore is also available in native Node.js, Java, Python, and Go SDKs, in addition to REST and RPC APIs.

Following Cloud Firestore's NoSQL data model, you store data in documents that contain fields mapping to values. These documents are stored in collections, which are containers for your documents that you can use to organize your data and build queries. Documents support many different data types, from simple strings and numbers, to complex, nested objects. You can also create subcollections within documents and build hierarchical data structures that scale as your database grows. The Cloud Firestore data model supports whatever data structure works best for your app.

Additionally, querying in Cloud Firestore is expressive, efficient, and flexible. Create shallow queries to retrieve data at the document level without needing to retrieve the entire collection, or any nested subcollections. Add sorting, filtering, and limits to your queries or cursors to paginate your results. To keep data in your apps current, without retrieving your entire database each time an update happens, add realtime listeners. Adding realtime listeners to your app notifies you with a data snapshot whenever the data your client apps are listening to changes, retrieving only the new changes.

Protect access to your data in Cloud Firestore with Firebase Authentication and Cloud Firestore Security Rules for Android, iOS, and JavaScript, or Identity and Access Management (IAM) for server-side languages.

Next Steps

- + \ No newline at end of file diff --git a/docs/firebase/firestore/order-and-limit-data/index.html b/docs/firebase/firestore/order-and-limit-data/index.html index 580cd6f7a75..9790847f483 100644 --- a/docs/firebase/firestore/order-and-limit-data/index.html +++ b/docs/firebase/firestore/order-and-limit-data/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Order and limit data

Cloud Firestore provides powerful query functionality for specifying which documents you want to retrieve from a collection. These queries can also be used with either query() or addSnapshotListener(), as described in Get Data.

Order and limit data

By default, a query retrieves all documents that satisfy the query in ascending order by document ID. You can specify the sort order for your data using orderBy(), and you can limit the number of documents retrieved using limit().

For example, you could query for the first 3 cities alphabetically with:

var query:Query = citiesRef.orderBy("name").limit(3);

You could also sort in descending order to get the last 3 cities:

var query:Query = citiesRef.orderBy( "name", QueryDirection.DESCENDING ).limit(3);

You can also order by multiple fields. For example, if you wanted to order by state, and within each state order by population in descending order:

var query:Query = citiesRef.orderBy("state").orderBy("population", QueryDirection.DESCENDING);

You can combine where() filters with orderBy() and limit(). In the following example, the queries define a population threshold, sort by population in ascending order, and return only the first few results that exceed the threshold:

citiesRef.whereGreaterThan("population", 100000).orderBy("population").limit(2);

However, if you have a filter with a range comparison (<, <=, >, >=), your first ordering must be on the same field:

Valid: Range filter and orderBy on the same field

citiesRef.whereGreaterThan("population", 100000).orderBy("population");

Invalid: Range filter and first orderBy on different fields

citiesRef.whereGreaterThan("population", 100000).orderBy("country");
- + \ No newline at end of file diff --git a/docs/firebase/firestore/paginate-data-with-query-cursors/index.html b/docs/firebase/firestore/paginate-data-with-query-cursors/index.html index 88b52198b42..7f3a1ad83ef 100644 --- a/docs/firebase/firestore/paginate-data-with-query-cursors/index.html +++ b/docs/firebase/firestore/paginate-data-with-query-cursors/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Paginate data with query cursors

With query cursors in Cloud Firestore, you can split data returned by a query into batches according to the parameters you define in your query.

Query cursors define the start and end points for a query, allowing you to:

  • Return a subset of the data.
  • Paginate query results.

However, to define a specific range for a query, you should use the where() method described in Simple Queries.

Add a simple cursor to a query

Use the startAt() or startAfter() methods to define the start point for a query. The startAt() method includes the start point, while the startAfter() method excludes it.

For example, if you use startAt(A) in a query, it returns the entire alphabet. If you use startAfter(A) instead, it returns B-Z.

// Get all cities with a population >= 1,000,000, ordered by population,
db.collection("cities")
.orderBy("population")
.startAt(1000000);

Similarly, use the endAt() or endBefore() methods to define an end point for your query results.

// Get all cities with a population <= 1,000,000, ordered by population,
db.collection("cities")
.orderBy("population")
.endAt(1000000);

Paginate a query

NOT YET AVAILABLE Coming soon

Paginate queries by combining query cursors with the limit() method. For example, use the last document in a batch as the start of a cursor for the next batch.

var first:Query = FirebaseFirestore.service.collection("users")
.orderBy("born")
.limit(5);

first.query()
.addOnQuerySuccessHandler( function( snapshot:QuerySnapshot ):void
{
// Get the last visible document
var lastVisible:DocumentSnapshot = snapshot.getDocuments()[ snapshot.size - 1 ];

var next:Query = FirebaseFirestore.service.collection("users")
.orderBy("born")
.startAtSnapshot(lastVisible)
.limit(5);

// Use the query for pagination
// ...
});

Set multiple cursor conditions

To add more granularity to your cursor's start or end point, you can specify multiple conditions in the cursor clause. This is particularly useful if your data set includes fields where the first condition in a cursor clause would return multiple results. Use multiple conditions to further specify the start or end point and reduce ambiguity.

For example, in a data set containing all the cities named "Springfield" in the United States, there would be multiple start points for a query set to start at "Springfield":

Cities
NameState
SpringfieldMassachusetts
SpringfieldMissouri
SpringfieldWisconsin

To start at a specific Springfield, you could add the state as a secondary condition in your cursor clause.

// Will return all Springfields
FirebaseFirestore.service.collection("cities")
.orderBy("name")
.orderBy("state")
.startAt("Springfield");
// Will return "Springfield, Missouri" and "Springfield, Wisconsin"
FirebaseFirestore.service.collection("cities")
.orderBy("name")
.orderBy("state")
.startAt("Springfield", "Missouri");
- + \ No newline at end of file diff --git a/docs/firebase/firestore/perform-simple-and-compound-queries/index.html b/docs/firebase/firestore/perform-simple-and-compound-queries/index.html index 4bf4e0e3c3f..a431fa32e79 100644 --- a/docs/firebase/firestore/perform-simple-and-compound-queries/index.html +++ b/docs/firebase/firestore/perform-simple-and-compound-queries/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Perform simple and compound queries

Cloud Firestore provides powerful query functionality for specifying which documents you want to retrieve from a collection. These queries can also be used with either query() or addSnapshotListener(), as described in Get Data and Get Realtime Updates.

Simple queries

The following query returns all cities with state CA:

// Create a reference to the cities collection
var citiesRef:CollectionReference = FirebaseFirestore.service.collection("cities");

// Create a query against the collection.
var query:Query = citiesRef.whereEqualTo("state", "CA");

The following query returns all the capital cities:

var query:Query = FirebaseFirestore.service.collection("cities").whereEqualTo("capital", true);

There are several variants of the where... method each take two parameters, a field to filter on and a value.

Some example filters:

citiesRef.whereEqualTo("state", "CA");
citiesRef.whereLessThan("population", 100000);
citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco");

Compound queries

You can also chain multiple where... methods to create more specific queries (logical AND). However, to combine the equality operator (==) with a range or array-contains clause (<, <=, >, >=, or array_contains), make sure to create a composite index.

citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver");
citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000);

You can only perform range comparisons (<, <=, >, >=) on a single field.

Valid: Range filters on only one field

citiesRef.whereGreaterThanOrEqualTo("state", "CA")
.whereLessThanOrEqualTo("state", "IN");
citiesRef.whereEqualTo("state", "CA")
.whereGreaterThan("population", 1000000);

Invalid: Range filters on different fields:

citiesRef.whereGreaterThanOrEqualTo("state", "CA").whereGreaterThan("population", 100000);

Query limitations

Cloud Firestore does not support the following types of queries:

  • Queries with range filters on different fields, as described in the previous section.
  • Single queries across multiple collections or subcollections. Each query runs against a single collection of documents. For more information about how your data structure affects your queries, see Choose a Data Structure.
  • Logical OR queries. In this case, you should create a separate query for each OR condition and merge the query results in your app.
  • Queries with a != clause. In this case, you should split the query into a greater-than query and a less-than query. For example, although the query clause where("age", "!=", "30") is not supported, you can get the same result set by combining two queries, one with the clause where("age", "<", "30") and one with the clause where("age", ">", 30).
- + \ No newline at end of file diff --git a/docs/firebase/firestore/transactions-and-batched-writes/index.html b/docs/firebase/firestore/transactions-and-batched-writes/index.html index 5a75988613f..1739bbb03f8 100644 --- a/docs/firebase/firestore/transactions-and-batched-writes/index.html +++ b/docs/firebase/firestore/transactions-and-batched-writes/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Firestore - Transactions and batched writes

Cloud Firestore supports atomic operations for reading and writing data. In a set of atomic operations, either all of the operations succeed, or none of them are applied. There are two types of atomic operations in Cloud Firestore:

  • Transactions: a transaction is a set of read and write operations on one or more documents.
  • Batched Writes: a batched write is a set of write operations on one or more documents.

Each transaction or batch of writes can write to a maximum of 500 documents. For additional limits related to writes, see Quotas and Limits.

Updating data with transactions

Using the Cloud Firestore client libraries, you can group multiple operations into a single transaction. Transactions are useful when you want to update a field's value based on its current value, or the value of some other field. You could increment a counter by creating a transaction that reads the current value of the counter, increments it, and writes the new value to Cloud Firestore.

A transaction consists of any number of getDocument() operations followed by any number of write operations such as setDocument(), update(), or deleteDocument(). In the case of a concurrent edit, Cloud Firestore runs the entire transaction again. For example, if a transaction reads documents and another client modifies any of those documents, Cloud Firestore retries the transaction. This feature ensures that the transaction runs on up-to-date and consistent data.

Transactions never partially apply writes. All writes execute at the end of a successful transaction.

When using transactions, note that:

  • Read operations must come before write operations.
  • A function calling a transaction (transaction function) might run more than once if a concurrent edit affects a document that the transaction reads.
  • Transaction functions should not directly modify application state.
  • Transactions will fail when the client is offline.

The following example shows how to create and run a transaction:

var transaction:Transaction = FirebaseFirestore.service.runTransaction(
function( transaction:Transaction ):void
{
trace( "apply( transaction )" );

// Perform transaction operations - may be called multiple times to re-run the transaction

// You must call finish or abort to complete the transaction
transaction.finish();
}
);

transaction.addEventListener( TransactionEvent.SUCCESS, successHandler );
transaction.addEventListener( TransactionEvent.FAILED, failedHandler );


function successHandler( event:TransactionEvent ):void
{
trace( "success" );

event.currentTarget.removeEventListener( TransactionEvent.SUCCESS, successHandler );
event.currentTarget.removeEventListener( TransactionEvent.FAILED, failedHandler );
}

function failedHandler( event:TransactionEvent ):void
{
trace( "failed: " + event.message );

event.currentTarget.removeEventListener( TransactionEvent.SUCCESS, successHandler );
event.currentTarget.removeEventListener( TransactionEvent.FAILED, failedHandler );
}

Example

This example loads a "user", updates the user's first name and increments a count property, returning the new count in the event

var user:DocumentReference = FirebaseFirestore.service.document( "users/12345" );

var transaction:Transaction = FirebaseFirestore.service.runTransaction(
function( transaction:Transaction ):void
{
// Read the user document reference
transaction.getDocument( user, function( snapshot:DocumentSnapshot, message:String ):void
{
if (snapshot == null)
{
// Error
transaction.abort();
}
else
{
// Get the user's current count
var currentCount:Number = snapshot.getData().count;
var newCount:Number = currentCount + 1;

// Change the first name with a setDocument merge
var data:Object = { first: "James" };
transaction.setDocument( user, data, SetOptions.merge(), function( snapshot:DocumentSnapshot, message:String ):void
{
// Update count
transaction.update( user, { count: newCount }, function( snapshot:DocumentSnapshot, message:String ):void
{
// Finish the transaction
transaction.finish();
});
});
}
});
}
);

Note: the setDocument() and update() calls probably could be combined in this example, but we just wanted to demonstrate the functionality.

Passing information out of transactions

Do not modify application state inside of your transaction functions. Doing so will introduce concurrency issues, because transaction functions can run multiple times and are not guaranteed to run on the UI thread. Instead, pass information you need out of your transaction functions. The following example builds on the previous example to show how to pass information out of a transaction:

var user:DocumentReference = FirebaseFirestore.service.document( "users/12345" );

var transaction:Transaction = FirebaseFirestore.service.runTransaction(
function( transaction:Transaction ):void
{
// Read the user document reference
transaction.getDocument( user, function( snapshot:DocumentSnapshot, message:String ):void
{
if (snapshot == null)
{
// Error
transaction.abort();
}
else
{
// Get the user's current count
var currentCount:Number = snapshot.getData().count;
var newCount:Number = currentCount + 1;

// Change the first name with a setDocument merge
var data:Object = { first: "James" };
transaction.setDocument( user, data, SetOptions.merge(), function( snapshot:DocumentSnapshot, message:String ):void
{
// Update count
transaction.update( user, { count: newCount }, function( snapshot:DocumentSnapshot, message:String ):void
{
// Finish the transaction - returning the new count
transaction.finish( newCount );
});
});
}
});
}
);

transaction.addEventListener( TransactionEvent.SUCCESS, successHandler );
transaction.addEventListener( TransactionEvent.FAILED, failedHandler );


function successHandler( event:TransactionEvent ):void
{
trace( "success" );

// event.data will contain the Object passed to finish
var count:Number = Number(event.data);

event.currentTarget.removeEventListener( TransactionEvent.SUCCESS, successHandler );
event.currentTarget.removeEventListener( TransactionEvent.FAILED, failedHandler );
}

function failedHandler( event:TransactionEvent ):void
{
trace( "failed: " + event.message );

event.currentTarget.removeEventListener( TransactionEvent.SUCCESS, successHandler );
event.currentTarget.removeEventListener( TransactionEvent.FAILED, failedHandler );
}

Transaction failure

A transaction can fail for the following reasons:

  • The transaction contains read operations after write operations. Read operations must always come before any write operations.
  • The transaction read a document that was modified outside of the transaction. In this case, the transaction automatically runs again. The transaction is retried a finite number of times.

A failed transaction returns an error and does not write anything to the database. You do not need to roll back the transaction; Cloud Firestore does this automatically.

Batched writes

If you do not need to read any documents in your operation set, you can execute multiple write operations as a single batch that contains any combination of set(), update(), or delete() operations. A batch of writes completes atomically and can write to multiple documents.

Batched writes are also useful for migrating large data sets to Cloud Firestore. A batched write can contain up to 500 operations and batching operations together reduces connection overhead resulting in faster data migration.

Batched writes have fewer failure cases than transactions and use simpler code. They are not affected by contention issues, because they don't depend on consistently reading any documents. Batched writes execute even when the user's device is offline. The following example shows how to build and commit a batch of writes:

var batch:WriteBatch = FirebaseFirestore.service.batch();

batch.addEventListener( WriteBatchEvent.SUCCESS, successHandler );
batch.addEventListener( WriteBatchEvent.FAILED, failedHandler );

var ref:DocumentReference = FirebaseFirestore.service.document( "document/path" );

batch.setDocument( ref, { name: "Hector" } );

batch.update( ref, { count: 10000 } );

batch.commit();



function successHandler( event:WriteBatchEvent ):void
{
trace( "success" );

event.currentTarget.removeEventListener( WriteBatchEvent.SUCCESS, successHandler );
event.currentTarget.removeEventListener( WriteBatchEvent.FAILED, failedHandler );
}

function failedHandler( event:WriteBatchEvent ):void
{
trace( "failed: " + event.message );

event.currentTarget.removeEventListener( WriteBatchEvent.SUCCESS, successHandler );
event.currentTarget.removeEventListener( WriteBatchEvent.FAILED, failedHandler );
}
- + \ No newline at end of file diff --git a/docs/firebase/index.html b/docs/firebase/index.html index 7487108cc6e..4722d2adf2f 100644 --- a/docs/firebase/index.html +++ b/docs/firebase/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ integrating Google services tightly with your AIR application.

This extension is to bring access Google's Firebase infrastructure to your AIR application.

The simple API allows you to quickly integrate Firebase in your AIR application. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

We provide complete guides to get you up and running with Firebase as quickly and easily as possible.

Features:

Documentation

Latest documentation can be found in the wiki

Quick Example:

Firebase.initialiseApp();

// Log an event to analytics
var event:EventObject = new EventObject();
event.name = EventObject.ADD_TO_CART;
event.params[Params.PRICE] = 1.99;

Firebase.service.analytics.logEvent( event );

More information here:

com.distriqt.Firebase

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/firebase/invites/add-the-extension/index.html b/docs/firebase/invites/add-the-extension/index.html index 29110b0f37f..99c1f18d3fc 100644 --- a/docs/firebase/invites/add-the-extension/index.html +++ b/docs/firebase/invites/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -37,7 +37,7 @@ such as accessing Safari saved passwords and activity continuation.

To do this, log into the member center and open your App IDs

Select your App ID and select "Edit". You need to enable the "Associated Domains" service as below:

Note: You will need to regenerate and download your provisioning profiles after making this change.

Info Additions and Entitlements

You will firstly need to add any custom url scheme to your info additions, by adding the following and replacing APP_SCHEME with your applications custom url scheme:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>APP_SCHEME</string>
</array>
</dict>
</array>

You need to add the associated domain to your iOS Entitlements section, replacing APP_CODE below with your Dynamic Links domain.

<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:APP_CODE.app.goo.gl</string>
</array>

For example:

<iPhone>
<InfoAdditions><![CDATA[

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>distriqt</string>
</array>
</dict>
</array>

]]></InfoAdditions>
<requestedDisplayResolution>high</requestedDisplayResolution>
<Entitlements><![CDATA[

<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:abc123.app.goo.gl</string>
</array>

]]></Entitlements>
</iPhone>
- + \ No newline at end of file diff --git a/docs/firebase/invites/dynamic-links/index.html b/docs/firebase/invites/dynamic-links/index.html index a55c74597ba..73353d6106b 100644 --- a/docs/firebase/invites/dynamic-links/index.html +++ b/docs/firebase/invites/dynamic-links/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Invites - Dynamic Links

DEPRECATED

Please note that the Invites functionality has been removed from the latest Firebase SDK. You should update your applications to use dynamic links directly in combination with your own share functionality. You can use the Share ANE as a starting point.

This documentation is only for legacy reference.

As invites are built ontop of dynamic links the functionality of dynamic links had to be integrated into the Invites extension.

This means that you cannot include both extensions in the same project however all the dynamic links functionality is replicated in the invites extension.

Any functionality available through the FirebaseDynamicLinks.service is also available through FirebaseInvites.service.dynamicLinks.

For example, to create a dynamic link:

FirebaseInvites.service.dynamicLinks.addEventListener( ShortDynamicLinkEvent.LINK_CREATED, dynamicLinkCreatedHandler );
FirebaseInvites.service.dynamicLinks.addEventListener( ShortDynamicLinkEvent.ERROR, dynamicLinkErrorHandler );

var builder:DynamicLinkBuilder = new DynamicLinkBuilder()
.setLink( "https://example.com" )
.setDynamicLinkDomain( "abc123.app.goo.gl" )
.setAndroidParameters( new AndroidParametersBuilder().build() )
.setIosParameters( new IosParametersBuilder( "com.example.ios" ).build() );

FirebaseInvites.service.dynamicLinks.createShortDynamicLink( builder.build() );

The imports will stay the same:

import com.distriqt.extension.firebase.dynamiclinks.DynamicLink;
import com.distriqt.extension.firebase.dynamiclinks.builders.AndroidParametersBuilder;
import com.distriqt.extension.firebase.dynamiclinks.builders.DynamicLinkBuilder;
import com.distriqt.extension.firebase.dynamiclinks.builders.GoogleAnalyticsParametersBuilder;
import com.distriqt.extension.firebase.dynamiclinks.builders.IosParametersBuilder;
import com.distriqt.extension.firebase.dynamiclinks.builders.ItunesConnectAnalyticsParametersBuilder;
import com.distriqt.extension.firebase.dynamiclinks.builders.SocialMetaTagParametersBuilder;
import com.distriqt.extension.firebase.dynamiclinks.events.DynamicLinkEvent;
import com.distriqt.extension.firebase.dynamiclinks.events.ShortDynamicLinkEvent;

Similarly listening for links:

FirebaseInvites.service.dynamicLinks.addEventListener( DynamicLinkEvent.RECEIVED, dynamicLink_receivedHandler );

function dynamicLink_receivedHandler( event:DynamicLinkEvent ):void
{
trace( "dynamicLink_receivedHandler(): " + event.link );
}

In this way you can still have access to all the normal dynamic links functionality with the Invites extension.

- + \ No newline at end of file diff --git a/docs/firebase/invites/initialise/index.html b/docs/firebase/invites/initialise/index.html index 485b60490b2..3ec4151a1e2 100644 --- a/docs/firebase/invites/initialise/index.html +++ b/docs/firebase/invites/initialise/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ This is the same url scheme (APP_SCHEME) that you added to the info additions previously when adding the extension

The easiest way to do this is set as below, before calling initialiseApp():

Firebase.service.deepLinkURLScheme = "APP_SCHEME";
Firebase.service.initialiseApp();

If you are passing your own FirebaseOptions to initialiseApp you can specify the scheme as part of the options:

var options:FirebaseOptions = new FirebaseOptions();
// Other options
options.deepLinkURLScheme = "APP_SCHEME";

Firebase.service.initialiseApp( options );

Note: You cannot use these two methods together

- + \ No newline at end of file diff --git a/docs/firebase/invites/introduction/index.html b/docs/firebase/invites/introduction/index.html index b5c3fec701e..501c8738d15 100644 --- a/docs/firebase/invites/introduction/index.html +++ b/docs/firebase/invites/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ Store or App Store if they need to install your app; then, your app opens and can retrieve and handle the link.

Google Identity

On iOS Invites require that you have signed in your user using Google Identity. This means that you will need to integrate the Google Identity ANE in order to get invites on iOS.

Android does not require this addition.

- + \ No newline at end of file diff --git a/docs/firebase/invites/invitations/index.html b/docs/firebase/invites/invitations/index.html index 4857070d23d..fedbe05098e 100644 --- a/docs/firebase/invites/invitations/index.html +++ b/docs/firebase/invites/invitations/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ The options include things such as the dialog title, message content and application ids on other platforms. If you wish to use invitations to launch your application it is important you specify the deep link to use for the invitation.

var options:InviteOptions = new InviteOptions();

options.title = "Invite Test";
options.message = "Check this out!";
options.deepLink = "distriqt://invite";

FirebaseInvites.service.sendInvite( options );

The dialog will dispatch one of three events:

FirebaseInvites.service.addEventListener( InviteEvent.SENDINVITE_COMPLETE, inviteSentHandler );
FirebaseInvites.service.addEventListener( InviteEvent.SENDINVITE_CANCELLED, inviteErrorHandler );
FirebaseInvites.service.addEventListener( InviteEvent.SENDINVITE_FAILED, inviteErrorHandler );

function inviteSentHandler( event:InviteEvent ):void
{
trace( "sendInvite(): sent: " + event.invitationIds.join(",") );
}

function inviteSentHandler( event:InviteEvent ):void
{
trace( "sendInvite(): error: " + event.type );
}

If you are using iOS and haven't logged in your user through Google Identity you will not be able to send invitations.

Receive Invitiations

If you have correctly set the deep link to launch your application then you can listen for the InviteEvent.RECEIVED event which will get dispatched whenever an invitation is received by your application.

This will include invitations at launch. These will be dispatched immediately after you register your listener for the event.

FirebaseInvites.service.addEventListener( InviteEvent.RECEIVED, invite_receivedHandler );

function invite_receivedHandler( event:InviteEvent ):void
{
trace( "invite_receivedHandler(): " + event.invitationIds.join(",") );
}

The event will contain a single invitation id that was received by the user.

- + \ No newline at end of file diff --git a/docs/firebase/migrating-to-v4/index.html b/docs/firebase/migrating-to-v4/index.html index 8de705c1041..d8bf472a193 100644 --- a/docs/firebase/migrating-to-v4/index.html +++ b/docs/firebase/migrating-to-v4/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Migrating to v4

Version 4 brings a major update of the Firebase extensions and with it a series of changes.

The main changes you will need to do are for the Android implementation.

AndroidX

Firstly migrate all AndroidSupport extensions to AndroidX. AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

You should remove any android support ANEs you are using and replace them with the androidx equivalents. Check the documentation on the extensions you are using to confirm which of the new extensions you will need.

Firebase update

Now that we have access to AndroidX we have been able to update the Android Firebase libraries to the latest releases. The migration to AndroidX has been holding back this development.

This means that there has been many changes to the manifest and extension dependency of the ANEs.

  • Firstly you will need to add the com.google.firebase.core extension. This extension contains all the common core Firebase functionality that is needed across any extensino that utilises Firebase, including Firebase Messaging (in the Push Notifications extension) and all the Firebase collection extensions.

  • Then check the "Add the Extension" page for each of the Firebase components you use. There have been a lot of manifest changes, in particular around the ComponentDiscoveryService.

As always, if you have any problems during the migration, please contact support through the github issue tracker and we will help you through the migration.

- + \ No newline at end of file diff --git a/docs/firebase/migrating-to-v6/index.html b/docs/firebase/migrating-to-v6/index.html index 0b5d6a6a2ae..68ae8c87da9 100644 --- a/docs/firebase/migrating-to-v6/index.html +++ b/docs/firebase/migrating-to-v6/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to v6

Version 6 brings a major update of the Firebase extensions and with it a series of changes.

Auth

Firebase Auth requires some changes to the manifest additions.

You will need to replace the following:

<!-- FIREBASE AUTH -->
<activity
android:name="com.google.firebase.auth.internal.FederatedSignInActivity"
android:excludeFromRecents="true"
android:exported="true"
android:launchMode="singleTask"
android:permission="com.google.firebase.auth.api.gms.permission.LAUNCH_FEDERATED_SIGN_IN"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />

with this:

<!-- FIREBASE AUTH -->
<activity
android:name="com.google.firebase.auth.internal.GenericIdpActivity"
android:excludeFromRecents="true"
android:exported="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="firebase.auth"
android:path="/"
android:scheme="genericidp" />
</intent-filter>
</activity>
<activity
android:name="com.google.firebase.auth.internal.RecaptchaActivity"
android:excludeFromRecents="true"
android:exported="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="firebase.auth"
android:path="/"
android:scheme="recaptcha" />
</intent-filter>
</activity>
<service
android:name="com.google.firebase.auth.api.fallback.service.FirebaseAuthFallbackService"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.auth.api.gms.service.START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>

Remote Config

Remote config extension has been updated and the API brought inline with the Firebase SDK.

The changes include:

  • The fetch() method has been removed and the newer fetchAndActivate() method added.

  • The ability to change the settings has been updated to utilise the FirebaseRemoteConfigSettings class through the setConfigSettings() function.

  • Retrieving the instance info also includes the current settings, FirebaseRemoteConfigInfo.settings retrieved through the call to getInfo().

- + \ No newline at end of file diff --git a/docs/firebase/performance/add-the-extension/index.html b/docs/firebase/performance/add-the-extension/index.html index 858ad3a0dcd..5aaa7a6c1d6 100644 --- a/docs/firebase/performance/add-the-extension/index.html +++ b/docs/firebase/performance/add-the-extension/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Performance - Add the extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.firebase.Performance

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.firebase.Performance.ane # Firebase Performance extension
| |____ com.distriqt.Firebase.ane # Firebase extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/firebase/performance/disable-monitoring/index.html b/docs/firebase/performance/disable-monitoring/index.html index 3a6ae99bae4..4b298822966 100644 --- a/docs/firebase/performance/disable-monitoring/index.html +++ b/docs/firebase/performance/disable-monitoring/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ so it provides an ideal way to let you disable Performance Monitoring in deployed instances of your app. Simply use a remote config variable to pass to the setPerformanceCollectionEnabled function.

- + \ No newline at end of file diff --git a/docs/firebase/performance/introduction/index.html b/docs/firebase/performance/introduction/index.html index 3f44fee63ad..c822170c5e7 100644 --- a/docs/firebase/performance/introduction/index.html +++ b/docs/firebase/performance/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ improved so that you can use that information to fix performance issues.

Performance Monitoring is currently in beta release

YOUTUBE

https://firebase.google.com/docs/perf-mon/

Key capabilities

RealAutomatically measure app startup time, HTTP/S network requests, and moreWhen you integrate the Performance Monitoring SDK into your iOS or Android app, you don't need to write any code before your app starts monitoring several critical aspects of app performance: startup time, activity while in the foreground, activity while in the background, and HTTP/S network requests.
Gain insight into situations where app performance could be improvedOptimizing the performance of your app can be challenging when you don't know exactly why it is falling short of user expectations. That's why Performance Monitoring lets you see performance metrics broken down by country, device, app version, and OS level.
Customize Performance Monitoring for your appYou can create traces to capture your app's performance in specific situations, like when you load a new screen. And, you can create counters to count events that you define (like cache hits) during those traces.

How does it work?

Performance Monitoring is available for iOS and Android apps that include the Performance Monitoring SDK. Performance Monitoring monitors traces and HTTP/S network requests in your app.

A trace is a report of performance data captured between two points in time in your app. When installed, the Performance Monitoring SDK automatically provides app start traces, which measure the time between when the user opens the app and when the app is responsive. It also provides app in foreground traces and app in background traces to give you insight into how your app performs when in the foreground or when idle. To learn more about these types of traces, see Firebase Performance Monitoring Automatic Traces.

You can also configure custom traces. A custom trace is a report of performance data associated with some of the code in your app. You define the beginning and end of a custom trace using the APIs provided by the Performance Monitoring SDK. A custom trace can be further configured to record counters for performance-related events that occur within its scope. For example, you could create a counter for the number of cache hits and misses or the number of times that the UI becomes unresponsive for a noticeable period of time.

An HTTP/S network request is a report that captures the time between when your app issues a request to a service endpoint and when the response from that endpoint is complete. For any endpoint that your app makes a request to, the SDK will capture several metrics:

Response time: Time between when the request is made and when the response is fully received Payload size: Byte size of the network payload downloaded and uploaded by the app Success rate: Percentage of successful responses compared to total responses (to measure network or server failures)

User data

Performance Monitoring does not permanently store any personally identifiable information (such as names, email addresses, or phone numbers). While monitoring HTTP/S network requests, Performance Monitoring uses URLs (not including URL parameters) to build aggregated and anonymous URL patterns that are eventually persisted and shown in the Firebase console.

For a full list of data collected by Performance Monitoring, see Data collection.

- + \ No newline at end of file diff --git a/docs/firebase/performance/traces/index.html b/docs/firebase/performance/traces/index.html index a1493de8ed7..b803934308b 100644 --- a/docs/firebase/performance/traces/index.html +++ b/docs/firebase/performance/traces/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Performance - Traces

Automatic Traces

A trace is a report of performance data captured between two points in time in your app. When installed, the Performance Monitoring SDK automatically provides the following types of traces:

App start traces, which measure the time between when the user opens the app and when the app is responsive. App in background traces, which measure the time when the app is running in the background. App in foreground traces, which measure the time when the app is running in the foreground and available to the user.

Automatic Trace Definitions

Trace NameiOSAndroid
App startStarts when the application loads the first Object to memory and stops after the first successful run loop that occurs after the application receives the UIApplicationDidBecomeActiveNotification notification.Starts when the app's FirebasePerfProvider ContentProvider completes its onCreate method and stops when the first activity's onResume() method is called.
App in backgroundStarts when the application receives the UIApplicationWillResignActiveNotification notification and stops when it receives the UIApplicationDidBecomeActiveNotification notification.Starts when the last activity to leave the foreground has its onStop() method called and stops when the first activity to reach the foreground has its onResume() method called.
App in foregroundStarts when the application receives the UIApplicationDidBecomeActiveNotification notification and stops when it receives the UIApplicationWillResignActiveNotification notification.Starts when the first activity to reach the foreground has its onResume() method called and stops when the last activity to leave the foreground has its onStop() method called.

Custom Traces

A custom trace is a report of performance data associated with some of the code in your app.

You can have multiple custom traces in your app, and it is possible to have more than one custom trace running at a time. Each custom trace can have one or more counters to count performance-related events in your app, and those counters are associated with the traces that create them.

  1. Add the following imports:
import com.distriqt.extension.firebase.performance.FirebasePerformance;
import com.distriqt.extension.firebase.performance.metrics.Trace;
  1. Just before the code where you want to start a trace in your app, add the following line of code to start a trace called test_trace:
var testTrace:Trace = FirebasePerformance.service.newTrace( "test_trace" );
testTrace.start();
  1. Optional To count performance-related events that occur in your app (such as cache hits and misses), add a line of code similar to the following each time that the event occurs, using a string other than item_counter to name that event if you are counting a different type of event:
testTrace.incrementCounter( "item_counter" );
  1. Just after the code where you want to stop your trace, add the following line of code:
testTrace.stop();

Check the Firebase console for Performance Monitoring results

Results should appear in the Performance Monitoring section of the Firebase console within 12 hours.

- + \ No newline at end of file diff --git a/docs/firebase/remoteconfig/add-the-extensions/index.html b/docs/firebase/remoteconfig/add-the-extensions/index.html index 9033e4b3242..d1c993c475b 100644 --- a/docs/firebase/remoteconfig/add-the-extensions/index.html +++ b/docs/firebase/remoteconfig/add-the-extensions/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

RemoteConfig - Add the extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.firebase.RemoteConfig

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.firebase.RemoteConfig.ane # Firebase RemoteConfig extension
| |____ com.distriqt.Firebase.ane # Firebase extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/firebase/remoteconfig/initialise/index.html b/docs/firebase/remoteconfig/initialise/index.html index abb3d3f351f..e82e5d6d3b4 100644 --- a/docs/firebase/remoteconfig/initialise/index.html +++ b/docs/firebase/remoteconfig/initialise/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/firebase/remoteconfig/introduction/index.html b/docs/firebase/remoteconfig/introduction/index.html index c71373e9825..f99063fb2d6 100644 --- a/docs/firebase/remoteconfig/introduction/index.html +++ b/docs/firebase/remoteconfig/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ console to override in-app default values for all app users or for segments of your user base. Your app controls when updates are applied, and it can frequently check for updates and apply them with a negligible impact on performance.

YOUTUBE

https://firebase.google.com/docs/remote-config/

Key capabilities

Quickly roll out changes to your app's user baseYou can make changes to your app's default behavior and appearance by changing service-side parameter values. For example, you could change your app's layout or color theme to support a seasonal promotion, with no need to publish an app update.
Customize your app for segments of your user baseYou can use Remote Config to provide variations on your app's user experience to different segments of your user base by app version, by Google Analytics for Firebase audience, by language, and more.
Run A/B tests to improve your appYou can use Remote Config random percentile targeting with Google Analytics for Firebase to A/B test improvements to your app across different segments of your user base so that you can validate improvements before rolling them out to your entire user base.

How does it work?

Remote Config includes a client library that handles important tasks like fetching parameter values and caching them, while still giving you control over when new values are activated so that they affect your app's user experience. This lets you safeguard your app experience by controlling the timing of any changes.

The Remote Config client library get methods provide a single access point for parameter values. Your app gets service-side values using the same logic it uses to get in-app default values, so you can add the capabilities of Remote Config to your app without writing a lot of code.

To override in-app default values, you use the Firebase console to create parameters with the same names as the parameters used in your app. For each parameter, you can set a service-side default value to override the in-app default value, and you can also create conditional values to override the in-app default value for app instances that meet certain conditions. This graphic shows how parameter values are prioritized in the service and in your app:

To learn more about parameters, conditions, and how Remote Config resolves conflicts between conditional values, see Remote Config Parameters and Conditions.

- + \ No newline at end of file diff --git a/docs/firebase/remoteconfig/set-initial-values/index.html b/docs/firebase/remoteconfig/set-initial-values/index.html index 4a395b80994..938c6451188 100644 --- a/docs/firebase/remoteconfig/set-initial-values/index.html +++ b/docs/firebase/remoteconfig/set-initial-values/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

RemoteConfig - Set Initial Values

Set Initial Values

It's helpful if you setup some initial values in the console to get started.

  1. In the Firebase console, open your project.
  2. Select Remote Config from the menu to view the Remote Config dashboard.
  3. On first visit you should see the following screen:

  1. Click "Add your first parameter"
  2. Define parameters with the same names as the parameters that you defined in your app. For each parameter, you can set a default value (which will eventually override the corresponding in-app default value), and you can also set conditional values. To learn more, see Remote Config Parameters and Conditions.

For example:

Getting some initial values into the system will help you to identify connection issues early.

- + \ No newline at end of file diff --git a/docs/firebase/remoteconfig/usage/index.html b/docs/firebase/remoteconfig/usage/index.html index 32f8bc193e0..636cf9aaa8b 100644 --- a/docs/firebase/remoteconfig/usage/index.html +++ b/docs/firebase/remoteconfig/usage/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ behaves predictably before it fetches values from the Remote Config service.

Setting defaults is a matter of constructing your default values and then calling the setDefaults method:

var defaultValues:Object = {
welcome_message: "Default welcome message",
welcome_message_caps: true
};

FirebaseRemoteConfig.service.setDefaults( defaultValues );

The default values object must be a simple object, basically a key/value set. The values in the object must be of simple data types (int, Number, String etc) Anything more complex will cause issues.

Get Parameters

Now you can get parameter values from the Remote Config object. If you set values in the Remote Config service, fetch them, and then activate them, those values are available to your app. Otherwise, you get the in-app parameter values configured using setDefaults(). To get these values, call the method listed below that maps to the data type expected by your app, providing the parameter key as an argument:

For example, to retrieve the "welcome message" above:

var welcomeMessage:String = FirebaseRemoteConfig.service.getString( "welcome_message" );

Set parameter values in the service (as needed)

  1. In the Firebase console, open your project.
  2. Select Remote Config from the menu to view the Remote Config dashboard.
  3. Define parameters with the same names as the parameters that you defined in your app. For each parameter, you can set a default value (which will eventually override the corresponding in-app default value), and you can also set conditional values. To learn more, see Remote Config Parameters and Conditions.

Fetch and activate values

To fetch parameter values from the Remote Config service, call the fetchAndActivate() method. Any values that you set in the Remote Config service are fetched and cached in the Remote Config object.

FirebaseRemoteConfig.service.fetchAndActivate();

Once complete the extension will automatically activate the new values and dispatch a complete event.

FirebaseRemoteConfig.service.addEventListener( FirebaseRemoteConfigEvent.FETCH_COMPLETE, fetch_completeHandler );
private function fetch_completeHandler( event:FirebaseRemoteConfigEvent ):void
{
// New values available here
}

Throttling

If an app fetches too many times in a short time period, fetch calls are throttled.

During app development, you might want to fetch and activate configs very frequently (many times per hour) to let you rapidly iterate as you develop and test your app. To accommodate rapid iteration on a project with up to 10 developers, you can temporarily set a FirebaseRemoteConfigSettings object with a low minimum fetch interval (setMinimumFetchIntervalInSeconds) in your app.

The default minimum fetch interval for Remote Config is 12 hours, which means that configs won't be fetched from the backend more than once in a 12 hour window, regardless of how many fetch calls are actually made.

To set the minimum fetch interval to a custom value, use:

var settings:FirebaseRemoteConfigSettings = new FirebaseRemoteConfigSettings()
.setMinimumFetchIntervalInSeconds( 5 );

FirebaseRemoteConfig.service.setConfigSettings( settings );

This value is in seconds so the above would allow updates to fetch calls every 5 seconds.

caution

Keep in mind that this setting should be used for development only, not for an app running in production. If you're just testing your app with a small 10-person development team, you are unlikely to hit the hourly service-side quota limits. But if you pushed your app out to thousands of test users with a very low minimum fetch interval, your app would probably hit this quota.

Next Steps

To learn more about using Remote Config in your app, see the Remote Config Frequently Asked Questions on fetching and activating parameter values, developer mode and throtting, and fetch timing.

- + \ No newline at end of file diff --git a/docs/firebase/setup/configuration-files/index.html b/docs/firebase/setup/configuration-files/index.html index 694a737fb8f..16f60534a44 100644 --- a/docs/firebase/setup/configuration-files/index.html +++ b/docs/firebase/setup/configuration-files/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Setup - Configuration Files

There are two ways to configure an application.

  • Using a packaged plist file on iOS and packaged resources on Android;
  • Manual configuration passing in values at runtime.

The first method is the preferred method as it ensures your application is always correctly configured.

The second method will rely on a function call from your code which can be delayed and may cause some errors in background and initialisation operations particular with analytics. You may find Analytics doesn't work at all using the manual method.

We highly suggest you use the first method whenever possible. It does require slightly more work however it ensures your application is always running with the correct configuration.

Configuration Files

The first step in configuring your application is to get the configuration files from the Firebase console.

Once you have created your project in the console you will be able to navigate to the manage settings page and download the latest configuration file.

These files contain configuration details such as keys and identifiers, for the services you have enabled in your applications.

  • iOS: GoogleService-Info.plist
  • Android: google-services.json

Ideally you should be able to automatically configure your application using the configuration files downloaded from the Firebase console. However there are some slight complications that we will explain in the following sections.

iOS

For an iOS project this configuration file takes the form of an xml plist file called GoogleService-Info.plist.

Download this file and place it in the root of your application package and ensure it is packaged with your iOS AIR application.

This is all that is required for iOS and packaging this file with your application ensures your application is using the first method mentioned above.

Android

For an Android project this configuration file takes the form of a json file called google-services.json.

When an Android developer adds this file to his application part of the build process constructs resources file values.xml from this json file and packages them in their application.

As we don't have this option we have to manually convert this json file to the xml resources.

Create values.xml

We need to create the values.xml file from the details in the google-services.json file.

To create your values file (res/values/values.xml) you can either:

  • use the conversion tool available here;
  • create it manually by copying the example below;

Complete values.xml example:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="google_app_id" translatable="false">1:1035469437089:android:73a4fb8297b2cd4f</string>
<string name="gcm_defaultSenderId" translatable="false">1035469437089</string>
<string name="default_web_client_id" translatable="false">337894902146-e4uksm38sne0bqrj6uvkbo4oiu4hvigl.apps.googleusercontent.com</string>
<string name="ga_trackingId" translatable="false">UA-65557217-3</string>
<string name="firebase_database_url" translatable="false">https://example-url.firebaseio.com</string>
<string name="google_api_key" translatable="false">AIzbSyCILMsOuUKwN3qhtxrPq7FFemDJUAXTyZ8</string>
<string name="google_crash_reporting_api_key" translatable="false">AIzbSyCILMsOuUKwN3qhtxrPq7FFemDJUAXTyZ8</string>
<string name="google_storage_bucket" translatable="false">XXX</string>
<string name="project_id" translatable="false">mydemoapp</string>
</resources>

The values from your google-services.json file coincide with the values in your values.xml file as per the table below:

Field NameJson value
google_app_id{YOUR_CLIENT}/client_info/mobilesdk_app_id
gcm_defaultSenderIdproject_info/project_number
default_web_client_id{YOUR_CLIENT}/oauth_client/client_id (client_type == 3)
ga_trackingId{YOUR_CLIENT}/services/analytics-service/analytics_property/tracking_id
firebase_database_urlproject_info/firebase_url
google_api_key{YOUR_CLIENT}/api_key/current_key
google_crash_reporting_api_key{YOUR_CLIENT}/api_key/current_key
google_storage_bucketproject_info/storage_bucket
project_idproject_info/project_id

Package Resources

Now that you have your values.xml you need to package it with your AIR application.

If you are using a recent version of AIR then you can specify a directory to add to the build and AIR will include the resources automatically:

If you are using an older version of AIR you must create an custom resources ANE and add that extension to your application:

Location

Whichever method you use it is important that the values.xml file is places at values/values.xml in your resources directory.

Alternative: Loaded Configuration

This method is a manual configuration method which is the same as the manual configuration in the next section however the values are read directly from the json file if you package it with your Android application.

This method requires that you package the google-services.json at the root level of your application. When you call initialiseApp(), the extension will look for this file and if found will read the values appropriate for your application.

See the notes on the manual configuration below as all the points there apply to this method.

Manual Configuration

caution

This method while appearing simple is not advised.

Firebase has issues with some aspects of it's functionality when initialised in this manner. Particularly it seems that Analytics will fail and you will get error messages about a missing google_app_id. This appears to be well known and no current solution is available.

As we understand this process is provided to be able to access a secondary Firebase project in an application.

If you wish you can manually setup your application.

To do this you create an instance of the FirebaseOptions class and set the details for your application. You can locate these in the configuration files downloaded above.

var options:FirebaseOptions = new FirebaseOptions();
options.apiKey = google_api_key;
options.clientID = default_web_client_id;
options.databaseURL = firebase_database_url
options.gcmSenderID = gcm_defaultSenderId;
options.googleAppID = google_app_id;

Firebase.service.initialiseApp( options );

If you are using manual configuration on Android it is important that you remove the FirebaseInitProvider from your manifest. This provider is the code responsible for initialising Firebase using your resources, if you aren't providing the configuration resources then this will fail.

i.e. remove the following:

<!-- common -->
<provider
android:authorities="APPLICATION_PACKAGE.firebaseinitprovider"
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:exported="false"
android:initOrder="100" />

Further information

- + \ No newline at end of file diff --git a/docs/firebase/setup/create-a-firebase-project/index.html b/docs/firebase/setup/create-a-firebase-project/index.html index 85fd7bdb03f..7fa35a8c828 100644 --- a/docs/firebase/setup/create-a-firebase-project/index.html +++ b/docs/firebase/setup/create-a-firebase-project/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ For example if you have a package that starts with a numeric value: com.4real.test this will be accepted as an AIR application id but is not a valid java package name. AIR will convert it to something like air.com.A4real.test. You will have to confirm this package name matches exactly!

info

We highly suggest using a valid java package name for your application ID, this means:

  • Lower case only
  • No packages starting with numeric values (numeric values within a package name are acceptable: com.this1.is.okay)
  • No punctuation marks (an underscore is the only accepted punctuation)
  1. At the end, you'll download a google-services.json file. You can download this file again at any time.
- + \ No newline at end of file diff --git a/docs/firebase/storage/add-the-extensions/index.html b/docs/firebase/storage/add-the-extensions/index.html index 2b6ea625ed0..3daaa8adfdd 100644 --- a/docs/firebase/storage/add-the-extensions/index.html +++ b/docs/firebase/storage/add-the-extensions/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Storage - Add the extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

Add the Extension

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.firebase.Firestore

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.firebase.Firestore.ane # Firebase Firestore extension
| |____ com.distriqt.Firebase.ane # Firebase extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

- + \ No newline at end of file diff --git a/docs/firebase/storage/delete-files/index.html b/docs/firebase/storage/delete-files/index.html index 347524d1e70..9b2c600baeb 100644 --- a/docs/firebase/storage/delete-files/index.html +++ b/docs/firebase/storage/delete-files/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Storage - Delete Files

Delete Files

To delete a file, first create a reference. to that file. Then call the deleteReference() method on that reference.

var reference:StorageReference = FirebaseStorage.service.getReference().child( "images/test.png" );

reference.addEventListener( StorageReferenceEvent.DELETE_SUCCESS, deleteHandler );
reference.addEventListener( StorageReferenceEvent.DELETE_ERROR, deleteHandler );

reference.deleteReference();

Then you will receive either a success or error event:

private function reference_deleteHandler( event:StorageReferenceEvent ):void 
{
trace( event.type );

// Remove listeners
var reference:StorageReference = StorageReference(event.currentTarget);
reference.removeEventListener( StorageReferenceEvent.DELETE_SUCCESS, reference_deleteHandler );
reference.removeEventListener( StorageReferenceEvent.DELETE_ERROR, reference_deleteHandler );
}
- + \ No newline at end of file diff --git a/docs/firebase/storage/download-files/index.html b/docs/firebase/storage/download-files/index.html index 26423c4ad77..ebfa9fca299 100644 --- a/docs/firebase/storage/download-files/index.html +++ b/docs/firebase/storage/download-files/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ events raise pause and progress state changes respectively. Canceling a download causes the download to fail with an error indicating that the download was canceled.

// Pause the download
task.pause();

// Resume the download
task.resume();

// Cancel the download
task.cancel();
- + \ No newline at end of file diff --git a/docs/firebase/storage/file-metadata/index.html b/docs/firebase/storage/file-metadata/index.html index 890055ecf24..931b23da80f 100644 --- a/docs/firebase/storage/file-metadata/index.html +++ b/docs/firebase/storage/file-metadata/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Storage - File Metadata

File Metadata

After uploading a file to Firebase Storage reference, you can also get the file metadata, for example to view or update the content type. Files can also store custom key/value pairs with additional file metadata.

Get File Metadata

File metadata contains common properties such as name, size, and contentType (often referred to as MIME type) in addition to some less common ones like contentDisposition and timeCreated. This metadata can be retrieved from a Firebase Storage reference using the getMetadata() method.

var reference:StorageReference = FirebaseStorage.service.getReference().child( "images/test.png" );
reference.getMetadata();

This will dispatch one of two events when the process is complete,

  • StorageReferenceEvent.GET_METADATA_SUCCESS: if metadata was successfully retrieved
  • StorageReferenceEvent.GET_METADATA_ERROR: if there was an error
reference.addEventListener( StorageReferenceEvent.GET_METADATA_SUCCESS, getMetadata_successHandler );
reference.addEventListener( StorageReferenceEvent.GET_METADATA_ERROR, getMetadata_errorHandler );
function getMetadata_successHandler( event:StorageReferenceEvent ):void 
{
// getMetadata success
}

function getMetadata_errorHandler( event:StorageReferenceEvent ):void
{
// getMetadata error
trace( event.errorMessage );
}

Get Download Url

If you wish to retrieve a download URL to share the file you can call the getDownloadUrl() function which will asynchronously retrieve a long lived download URL with a revokable token. This can be used to share the file with others, but can be revoked by a developer in the Firebase Console if desired.

reference.getDownloadUrl();

This will dispatch one of two events when the process is complete,

  • StorageReferenceEvent.GET_DOWNLOAD_URL_SUCCESS: if url was successfully retrieved
  • StorageReferenceEvent.GET_DOWNLOAD_URL_ERROR: if there was an error
reference.addEventListener( StorageReferenceEvent.GET_DOWNLOAD_URL_SUCCESS, getDownloadUrl_successHandler );
reference.addEventListener( StorageReferenceEvent.GET_DOWNLOAD_URL_ERROR, getDownloadUrl_errorHandler );
function getDownloadUrl_successHandler( event:StorageReferenceEvent ):void 
{
// getDownloadUrl success
trace( event.url );
}

function getDownloadUrl_errorHandler( event:StorageReferenceEvent ):void
{
// getDownloadUrl error
trace( event.errorMessage );
}
- + \ No newline at end of file diff --git a/docs/firebase/storage/introduction/index.html b/docs/firebase/storage/introduction/index.html index 82f0b2b032e..79cfd52e6ff 100644 --- a/docs/firebase/storage/introduction/index.html +++ b/docs/firebase/storage/introduction/index.html @@ -13,7 +13,7 @@ - + @@ -39,7 +39,7 @@ and provides a declarative security language that lets you set access controls on individual files or groups of files, so you can make files as public or private as you want.

- + \ No newline at end of file diff --git a/docs/firebase/storage/list-files/index.html b/docs/firebase/storage/list-files/index.html index 9ed68f2f178..98d8f90930a 100644 --- a/docs/firebase/storage/list-files/index.html +++ b/docs/firebase/storage/list-files/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Storage - List Files

Cloud Storage for Firebase allows you to list the contents of your Cloud Storage bucket. The SDKs return both the items and the prefixes of objects under the current Cloud Storage reference.

Projects that use the List API require Cloud Storage for Firebase Rules version 2. If you have an existing Firebase project, follow the steps in the Security Rules Guide.

note

The List API is only allowed for Rules version 2. In Rules version 2, allow read is the shorthand for allow get, list.

List all files

You can use listAll() to fetch all results for a directory. This is best used for small directories as all results are buffered in memory. The operation also may not return a consistent snapshot if objects are added or removed during the process.

var ref:StorageReference = FirebaseStorage.service.getReference();
ref.addEventListener( StorageReferenceListEvent.SUCCESS, listSuccessHandler );
ref.addEventListener( StorageReferenceListEvent.ERROR, listErrorHandler );
ref.listAll();


function listSuccessHandler( event:StorageReferenceListEvent ):void
{
// Contains a list of "prefixes" - similar concept to sub directories
for each (var prefix:String in event.prefixes)
{
}

// Contains a list of "items" - each represents a storage item (or file)
for each (var item:String in event.items)
{
// Can retrieve a reference to the file as below:
var ref:StorageReference = FirebaseStorage.service.getReference( item );
}
}

Paginate list results

The list() API places a limit on the number of results it returns. list() provides a consistent pageview and exposes a pageToken that allows control over when to fetch additional results.

var ref:StorageReference = FirebaseStorage.service.getReference();
ref.addEventListener( StorageReferenceListEvent.SUCCESS, listSuccessHandler );
ref.addEventListener( StorageReferenceListEvent.ERROR, listErrorHandler );
ref.list( 10 );


function listSuccessHandler( event:StorageReferenceListEvent ):void
{
// Process page of results - similar to listAll, this contains "prefixes" and "items"
// ...

// Recurse onto next page
if (event.pageToken)
{
// Continue pagination by calling list again with the pageToken
ref.list( 10, event.pageToken );
}
}

The pageToken encodes the path and version of the last item returned in the previous result. In a subsequent request using the pageToken, items that come after the pageToken are shown

Handle Errors

list() and listAll() fail if you haven't upgraded the Security Rules to version 2. Upgrade your Security Rules if you see this error:

Listing objects in a bucket is disallowed for rules_version = "1".
Please update storage security rules to rules_version = "2" to use list.

Other possible errors may indicate the user does not have the right permission. More information on errors can be found in the Handle Errors.

function listErrorHandler( event:StorageReferenceListEvent ):void 
{
trace( event.errorMessage );
}
- + \ No newline at end of file diff --git a/docs/firebase/storage/references/index.html b/docs/firebase/storage/references/index.html index fced1e0cff6..bd0ffab86ab 100644 --- a/docs/firebase/storage/references/index.html +++ b/docs/firebase/storage/references/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ getParent() navigates up one level, while getRoot() navigates all the way to the top.

// Parent allows us to move our reference to point to
// imagesRef now points to 'images'
var parentReference:StorageReference = reference.getParent();

// Root allows us to move all the way back to the top of our bucket
// rootRef now points to the root
var rootReference:StorageReference = reference.getRoot();

Along with child() these can all be chained together:

var earthReference:StorageReference = reference.getParent().child( "earth.jpg" );

Reference Properties

You can inspect references to better understand the files they point to using the getPath(), getName(), and getBucket() methods. These methods get the file's full path, name and bucket.

// Reference's path is: "images/space.jpg"
// This is analogous to a file path on disk
reference.getPath();

// Reference's name is the last segment of the full path: "space.jpg"
// This is analogous to the file name
reference.getName();

// Reference's bucket is the name of the storage bucket that the files are stored in
reference.getBucket();
- + \ No newline at end of file diff --git a/docs/firebase/storage/upload-files/index.html b/docs/firebase/storage/upload-files/index.html index 02504cc99db..d3f665ae80f 100644 --- a/docs/firebase/storage/upload-files/index.html +++ b/docs/firebase/storage/upload-files/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ upload causes the upload to fail with an error indicating that the upload was canceled.

// Pause the upload
task.pause();

// Resume the upload
task.resume();

// Cancel the upload
task.cancel();

Monitor Upload Progress

An upload task dispatches UploadTaskEvents to indicate completion, progress, and errors:

task.addEventListener( UploadTaskEvent.SUCCESS, uploadSuccessHandler );
task.addEventListener( UploadTaskEvent.ERROR, uploadErrorHandler );

Events are dispatched with a UploadTaskSnapshot object. This object is an immutable view of the task at the time the event occurred.

private function uploadSuccessHandler( event:UploadTaskEvent ):void 
{
// event.snapshot contains details about the completed upload
}

private function uploadErrorHandler( event:UploadTaskEvent ):void
{
// Handle unsuccessful uploads
// event.errorMessage contains the reason for the error
}
- + \ No newline at end of file diff --git a/docs/flurry/add-the-extension/index.html b/docs/flurry/add-the-extension/index.html index b43261764b3..e2f113d23c0 100644 --- a/docs/flurry/add-the-extension/index.html +++ b/docs/flurry/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ will avoid conflicts, allowing you to use multiple extensions in the one application.

This extension requires the following Google Play Services:

You must include the above native extensions in your application along with this extension, and you need to ensure they are packaged with your application.

You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (Flurry.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/flurry/analytics-events/index.html b/docs/flurry/analytics-events/index.html index 844facfd49d..da0db4fee0f 100644 --- a/docs/flurry/analytics-events/index.html +++ b/docs/flurry/analytics-events/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ representing any properties you'd like to attach to this event. In the example below we log a screen click and use the coordinates of the click as properties. The properties must be simple data types that can be converted into strings.

Flurry.service.analytics.logEvent( "click", { x: event.stageX, y: event.stageY } );

Example

Simple example of initialisation and logging a startup event.

try
{
trace( "Flurry Supported: " + Flurry.isSupported );
if (Flurry.isSupported)
{
var config:FlurryAnalyticsConfig = new FlurryAnalyticsConfig();

Flurry.service.analytics.initialiseWithKeys(
"IOS_FLURRY_KEY",
"ANDROID_FLURRY_KEY",
config );

trace( "Flurry Version: " + Flurry.service.version );
trace( "Flurry Agent Version: " + Flurry.service.analytics.getFlurryAgentVersion() );

Flurry.service.analytics.startSession();
Flurry.service.analytics.logEvent( "startup" );
}
}
catch (e:Error)
{
trace( "ERROR::"+e.message );
}

Revenue Analytics

Revenue Analytics within Flurry allows you to track your In App Purchase (IAP) Revenue from transactions that occur within your iOS app or Android app in order to determine if your app is producing revenue from in app purchases at the levels you expect.

To log a purchase call the logPayment() method passing the details of the purchase:

var payment:PaymentData = new PaymentData( "candy", "yummy_candy", 1, 2.99, "USD", "123456789" );

Flurry.service.analytics.logPayment( payment );
- + \ No newline at end of file diff --git a/docs/flurry/analytics-sessions/index.html b/docs/flurry/analytics-sessions/index.html index ead3234777b..c59d996b663 100644 --- a/docs/flurry/analytics-sessions/index.html +++ b/docs/flurry/analytics-sessions/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ session each time your application is activated. Make sure you only add the activation handler after you've initialised the Flurry extension, or else implement a check to make sure this process has been performed.

var config:FlurryAnalyticsConfig = new FlurryAnalyticsConfig();
Flurry.service.analytics.initialiseWithKeys( "IOS_FLURRY_KEY", "ANDROID_FLURRY_KEY", config );
Flurry.service.analytics.startSession();

addEventListener( Event.ACTIVATE, activateHandler );
addEventListener( Event.DEACTIVATE, deactivateHandler );


function activateHandler( event:Event ):void
{
if (Flurry.isSupported)
{
Flurry.service.analytics.startSession();
}
}

function deactivateHandler( event:Event ):void
{
if (Flurry.isSupported)
{
Flurry.service.analytics.endSession();
}
}
- + \ No newline at end of file diff --git a/docs/flurry/analytics-standard-events/index.html b/docs/flurry/analytics-standard-events/index.html index befb2c6676a..1f8f443b40f 100644 --- a/docs/flurry/analytics-standard-events/index.html +++ b/docs/flurry/analytics-standard-events/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Analytics Standard Events

Events track standardized actions that users take within your app – for example, making a purchase, adding a social comment, or clicking on an Ad. This helps you understand how users interact with your app.

Please Note: You must initiate the session with one of the startSession method variants prior to logging any standard events. Any events logged prior to session initialization will not be recorded.

note

You can track up to 1000 unique standard events per session. Once one single session hits the 1000 standard event limit, no further events would be tracked. Note that this limit is shared with other types of events such as the custom event.

To log a standard event use the logStandardEvent() method and pass the event name and event parameters.

var status:int = Flurry.service.analytics.logStandardEvent(
FlurryEvent.TUTORIAL_STARTED,
new FlurryEventParams()
.putString( FlurryEventParams.TUTORIAL_NAME, "introduction" )
);

The return value is the status of the event logging and will be one of the values in the FlurryEventRecordStatus class. A success is indicated by the FlurryEventRecordStatus.RECORDED value (1).

Event Names

Like a custom event, a standard event also has a two-level structure. The highest level is the specific action.

Flurry SDK defines 58 standardized event names, and they are categorized in advertising, gaming, content, commerce, membership, onboarding, registration, search, social, media, and privacy.

These event names are defined in the FlurryEvent class, eg FlurryEvent.PURCHASED.

Event Parameters

The second level in the standard event structure is the event parameter, which will be an instance of the FlurryEventParams class.

In order for SDK to log a standard event, you might want to put the standardized parameters as well as your own defined parameters together. There will be recommended standardized parameter keys and mandatory standardized parameter keys defined for each standard event name.

For instance, to log FlurryEvent.PURCHASED event name, SDK suggests to include FlurryEventParams.ITEM_COUNT, FlurryEventParams.TOTAL_AMOUNT, FlurryEventParams.ITEM_ID, FlurryEventParams.SUCCESS, FlurryEventParams.ITEM_NAME, FlurryEventParams.ITEM_TYPE, FlurryEventParams.CURRENCY_TYPE and FlurryEventParams.TRANSACTION_ID parameters, in which FlurryEventParams.TOTAL_AMOUNT is also a mandatory parameter that is indicated by the SDK.

See the docs on standard events for details on the required parameters for each event:

https://developer.yahoo.com/flurry/docs/analytics/standard_events/

There are a total of 42 standardized parameter keys that each can only be mapped to its corresponding data value - String, Boolean, int, Number. So when you assemble your FlurryEventParams object with the standardized parameters, you will need to use the public APIs specified in FlurryEventParams class to map them correctly.

Param NameDataType
AD_TYPEString
LEVEL_NAMEString
LEVEL_NUMBERint
CONTENT_NAMEString
CONTENT_TYPEString
CONTENT_IDString
CREDIT_NAMEString
CREDIT_TYPEString
CREDIT_IDString
IS_CURRENCY_SOFTBoolean
CURRENCY_TYPEString
PAYMENT_TYPEString
ITEM_NAMEString
ITEM_TYPEString
ITEM_IDString
ITEM_COUNTint
ITEM_CATEGORYString
ITEM_LIST_TYPEString
PRICENumber
TOTAL_AMOUNTNumber
ACHIEVEMENT_IDString
SCOREint
RATINGString
TRANSACTION_IDString
SUCCESSBoolean
IS_ANNUAL_SUBSCRIPTIONBoolean
SUBSCRIPTION_COUNTRYString
TRIAL_DAYSint
PREDICTED_LTVString
GROUP_NAMEString
TUTORIAL_NAMEString
STEP_NUMBERint
USER_IDString
METHODString
QUERYString
SEARCH_TYPEString
SOCIAL_CONTENT_NAMEString
SOCIAL_CONTENT_IDString
LIKE_TYPEString
MEDIA_NAMEString
MEDIA_TYPEString
MEDIA_IDString
DURATIONint

Example

Here is an example of logging a purchase event using the new standard event protocol:

var status:int = Flurry.service.analytics.logStandardEvent(
FlurryEvent.PURCHASED,
new FlurryEventParams()
.putNumber( FlurryEventParams.TOTAL_AMOUNT, 34.99 )
.putBoolean( FlurryEventParams.SUCCESS, true )
.putString( FlurryEventParams.ITEM_NAME, "bool 1" )
.putString( "note", "This is an awesome book to purchase !!!" )
);

Like a custom event, each standard event can also have up to 10 parameters, and each parameter can have an infinite number of values associated with it. For example, for the "note" parameter, there may be 1,000 possible values who wrote an article.

- + \ No newline at end of file diff --git a/docs/flurry/changelog/index.html b/docs/flurry/changelog/index.html index 88b82ce0ee0..341774522a3 100644 --- a/docs/flurry/changelog/index.html +++ b/docs/flurry/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.18 [v7.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
feat(android): Move to new permissions request process

2022.12.02 [v7.0.0]

feat(sdk): update sdk versions, android: v14.0.0, ios: v12.1.1 (resolves #24)

2022.03.08 [v6.3.0]

Update Flurry SDK 
- Android v13.1.0
- iOS v11.4.0

2022.02.05 [v6.2.10]

Update docs to use apm
Update air package dependencies
Android 31 updates

2021.08.30 [v6.2.9]

Released AIR Package (apm)
Added standard events (resolves #21)
SDK Update:
- Android v13.0.0
- iOS v11.3.0

2021.05.31 [v6.1.004]

SDK Update:
- Android v12.13.0

Added revenue tracking (resolves #20)

2021.04.07 [v6.0.006]

SDK Update:
- iOS v11.2.0
- Android v12.11.0

New configuration process
Added User Properties (resolves #19)

2020.03.22 [v5.0.011]

Android X migration (resolves #18)

2019.08.16 [v4.0.004]

Android 64bit support (resolves #17)
Updated minimum iOS version to 9.0

2018.11.02 [v3.4.021]

Added setReportLocation functionality (resolves #15)
SDK Update:
- iOS v9.2.3
- Android v11.2.0
Removed application key requirement

2018.02.17 [v3.3.012]

iOS SDK update to v8.3.4
Android SDK update to v8.2.0
Corrected error reporting (resolves #13)

2017.11.27 [v3.2.009]

Updated SDK: Android v8.1.0, iOS v8.3.1 (resolves #12)

2017.07.10 [v3.1.006]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.02.02 [v3.1.005]

Updated SDK to iOS v7.9.2, Android v6.8.0 (resolves #11)

2017.01.10 [v3.0.030]

Updating changelog location

2016.12.21 [v3.0.030]

Updating documentation

2016.11.18 [v3.0.030]

Updated SDK to iOS v7.8.1, Android v6.7.0 (resolves #8)

2016.04.21

SDK Update: Android v6.3.0, iOS v7.6.0 (resolves #5)

2016.02.28

Upgraded SDK - Android: v6.2.0 - iOS: v7.5.1 (resolves #4)
Added setAppVersion, setSessionContinueSeconds, setCrashReportingEnabled functions

2015.06.15

Removed debug code from AS lib
iOS: Updated to latest common lib
Android: Windows: Fix for bug in AIR packager resulting in missing resources
Android: x86 Support

2015.05.15

SDK Update to 5.5.0 (Android) and 6.4.0 (iOS)

2015.03.15

Initial release v1.0
- + \ No newline at end of file diff --git a/docs/flurry/index.html b/docs/flurry/index.html index 936608500c5..c4a17d9b39c 100644 --- a/docs/flurry/index.html +++ b/docs/flurry/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Flurry

This extension gives you the ability to access the Access to the Flurry Analytics service from Yahoo (https://developer.yahoo.com/analytics/).

Flurry is a mobile app analytics platform that empowers product, development and growth experts to build better apps that users love.

The simple API allows you to quickly integrate Flurry access in your AIR application in just a few lines of code. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

We provide complete guides to get you up and running with asset selection quickly and easily.

Features

  • Access to Flurry Analytics from Android and iOS devices
  • Track events and user information
  • User Properties
  • Single API interface - your code works across iOS and Android with no modifications
  • Sample project code and ASDocs reference

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

Flurry.service.analytics.logEvent( "startup" );

More information here:

com.distriqt.Flurry

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/flurry/initialise-the-extension/index.html b/docs/flurry/initialise-the-extension/index.html index 7f9bfe87821..a3291dacafe 100644 --- a/docs/flurry/initialise-the-extension/index.html +++ b/docs/flurry/initialise-the-extension/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Initialise the Extension

To use the analytics service you must pass in your Flurry keys that you created through the Flurry website and a configuration instance to set various configuration options (FlurryAnalyticsConfig).

var config:FlurryAnalyticsConfig = new FlurryAnalyticsConfig()
.setLogEnabled(true)
.setCrashReportingEnabled(true)
.setSessionContinueSeconds( 6 )
;

Flurry.service.analytics.initialise( "FLURRY_KEY", config );

(If you don't supply a configuration then the defaults will be used).

If you are cross compiling both iOS and Android you can use the initialiseWithKeys function to initialise both platforms.

Flurry.service.analytics.initialiseWithKeys( 
"IOS_FLURRY_KEY",
"ANDROID_FLURRY_KEY",
config
);
- + \ No newline at end of file diff --git a/docs/flurry/migrating-to-v6/index.html b/docs/flurry/migrating-to-v6/index.html index 5558f7bce98..257d65cb5bb 100644 --- a/docs/flurry/migrating-to-v6/index.html +++ b/docs/flurry/migrating-to-v6/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to v6.0

v6.0 brings the current release of Flurry (as at April 2021):

  • Android v12.11.0
  • iOS v11.2.0

This update has changed some of the functionality and added User Properties.

Manifest

You now need to add the following to your application node in your manifest additions:

<provider
android:name="com.flurry.android.agent.FlurryContentProvider"
android:authorities="APPLICATION_PACKAGE.FlurryContentProvider"
android:exported="false" />
danger

You need to replace APPLICATION_PACKAGE with your applications package name, generally your air application id prefixed by air.

API Changes

In order to update you will need to remove any calls to:

  • setLogEnabled(): Moved to FlurryAnalyticsConfig
  • setSessionContinueSeconds(): Moved to FlurryAnalyticsConfig
  • setCrashReportingEnabled(): Moved to FlurryAnalyticsConfig
  • setLocation(): This was previously deprecated and has now been removed. Location tracking is done automatically.

Configuration

There are several options that are now required at initialisation time, (logging etc) so there is a new class FlurryAnalyticsConfig that can be passed in at initialisation time:

var config:FlurryAnalyticsConfig = new FlurryAnalyticsConfig()
.setLogEnabled(true)
.setCrashReportingEnabled(true)
.setSessionContinueSeconds( 6 )
;

Flurry.service.analytics.initialise( "FLURRY_KEY", config );
- + \ No newline at end of file diff --git a/docs/flurry/user-properties/index.html b/docs/flurry/user-properties/index.html index 57b60361b2a..e67ec12769d 100644 --- a/docs/flurry/user-properties/index.html +++ b/docs/flurry/user-properties/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

User Properties

User Properties allow you to label your users based on preferences, behaviors or attributes unique to your app.

info

For details on the different types and using User Properties see the official documentation.

Client Side API

The user properties state is on the server, and the SDK is a pass thru agent for client state change requests. There are 4 groups of operations (set, add, remove, flag).

  • For (set, add), the fist parameter is a key, and the second parameter is a value.
  • For (remove), the first parameter is a key, and the second parameter is a value, or omitted to remove all values.
  • For (flag), the first parameter is a key and there is no second parameter.

Set

Sets and replaces (if any exist) the value(s) for the property.

Flurry.service.analytics.userProperties.setValue( "key", "value" );

Add

Adds a User Property value(s). Adding values already included in the state has no effect and does not error.

Flurry.service.analytics.userProperties.addValue( "key", "value" );

Remove

Removes a specific User Property value(s) or removes all values. Removing values not already included in the state has no effect and does not error.

// Removes the value from the property
Flurry.service.analytics.userProperties.removeValue( "key", "value" );

or remove all values from the property:

Flurry.service.analytics.userProperties.remove( "key" );

Flag

Exactly set, or replace if any previously exists, any value for the property to a single true state Implies that value is boolean and should only be flagged and cleared.

// Sets key to true
Flurry.service.analytics.userProperties.flag( "key" );
- + \ No newline at end of file diff --git a/docs/forcetouch/add-the-extension/index.html b/docs/forcetouch/add-the-extension/index.html index b7a35cf60a4..4409660e3ba 100644 --- a/docs/forcetouch/add-the-extension/index.html +++ b/docs/forcetouch/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Add the Extension

The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

However you can choose to install it manually, as you would have done in the past.

AIR SDK

This ANE currently requires at least AIR 33+. This is required in order to support versions of Android > 9.0 (API 28) and iOS 13. We always recommend using the most recent build with AIR especially for mobile development where the OS changes rapidly.

Install

info

Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

Setup APM

Install APM

If you haven't installed apm follow the install guide on airsdk.dev.

Setup an APM project

You will need an APM project for your application.

There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

apm init

Check your github token

We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

To do this create a token using this guide from github and then set it in your apm config using:

apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you don't do this correctly you may find the install will fail.

Install the extension

Install the extension by running:

apm install com.distriqt.ForceTouch

This will download and install the extension, required assets, and all dependencies.

Once complete apm will have created something like the following file structure:

.
|____ ane
| |____ com.distriqt.ForceTouch.ane # ForceTouch extension
| |____ [dependencies]
|____ apm_packages # cache directory - ignore
|____ project.apm # apm project file
  • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
info

We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (ForceTouch.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/forcetouch/app-shortcuts/index.html b/docs/forcetouch/app-shortcuts/index.html index a84e044a230..65d0535aaa4 100644 --- a/docs/forcetouch/app-shortcuts/index.html +++ b/docs/forcetouch/app-shortcuts/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ dynamically added items. As such, if you use 2 static shortcuts in your descriptor, you can only add 2 additional dynamic shortcuts to your app.

Dynamic Shortcuts

You can add shortcut items programmatically in your application, these are called dynamic shortcuts.

To do this you construct an instance of an ApplicationShortcut and then call addDynamicShortcut() with this item as a parameter.

For example:

var shortcut:ApplicationShortcut = new ApplicationShortcut()
.setIdentifier( "com.distriqt.test.item1" )
.setTitle( "Item 1" );

ForceTouch.service.shortcuts.addDynamicShortcut( shortcut );

The minimum amount of data on a shortcut is an identifier, and a title, but we also suggest setting an icon.

A shortcut has the following pieces of information:

Note: Your identifier must be unique. If a shortcut with the same identifier already exists then the addDynamicShortcut() function will return false and the shortcut will not be added. You should decide if you need to remove the shortcut and update it.

For example if you always want to update a shortcut:

var success:Boolean = ForceTouch.service.shortcuts.addDynamicShortcut( shortcut );
if (!success)
{
ForceTouch.service.shortcuts.removeDynamicShortcut( shortcut.identifier );
ForceTouch.service.shortcuts.addDynamicShortcut( shortcut );
}

Icons

Icons are handled differently on iOS and Android. They are optional but highly recommended!

On iOS you must select one of the predefined iOS system icons from the ShortcutIconType class.

You set the icon using the setIcon() function and specifying the type, eg:

var shortcut:ApplicationShortcut = new ApplicationShortcut()
.setIdentifier( "com.distriqt.test.item1" )
.setTitle( "Item 1" )

.setIcon( ShortcutIconType.Alarm );

On Android, you provide BitmapData representing your icon to display, eg using an embedded asset:

[Embed(source="alarm_clock.png")]
public var AlarmIcon:Class;

var alarmIcon:Bitmap = new AlarmIcon() as Bitmap;

var shortcut:ApplicationShortcut = new ApplicationShortcut()
.setIdentifier( "com.distriqt.test.item1" )
.setTitle( "Item 1" )

.setIconBitmap( alarmIcon.bitmapData );

Removing Dynamic Shortcuts

To remove a dynamic shortcut simply call removeDynamicShortcut() with the identifier of the item to remove.

For example, to remove the previous example:

ForceTouch.service.shortcuts.removeDynamicShortcut( "com.distriqt.test.item1" );

Events

To listen for shortcut events you must add the SHORTCUT_SELECTED event listener to the shortcuts interface as below:

ForceTouch.service.shortcuts.addEventListener(
ApplicationShortcutEvent.SHORTCUT_SELECTED,
shortcutSelectedHandler
);

When your shortcut is selected your handler will be triggered and you will receive the information associated with the selected shortcut. The event item property will contain an ApplicationShortcut instance where the identifier and userInfo are valid (other fields will be invalid, i.e. title/subtitle/icons).

If your application is running in the background, it will be brought to the foreground.

function shortcutSelectedHandler( event:ApplicationShortcutEvent ):void
{
trace( "Shortcut selected: " + event.item.identifier );
// event.item.userInfo is an object which contains any custom data.
}

If your application wasn't running, it will be launched and brought to the foreground.

This event will be dispatched after the first time you call addEventListener() for the SHORTCUT_SELECTED event, so you should be prepared to handle this event as soon as you add the listener.

Static Shortcuts

iOS

The ForceTouch extension supports static shortcut items on iOS. If included, these items are always present in the shortcut menu for your app.

Firstly add a custom iOS configuration file by running:

apm generate config ios

Edit the config/ios/InfoAdditions.xml file that was generated add the content below as required.

This is an example of how to add static shortcut items in your descriptor:

<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemTitle</key>
<string>Static Shortcut 1</string>
<key>UIApplicationShortcutItemType</key>
<string>com.distriqt.test.static_shortcut_1</string>
<key>UIApplicationShortcutItemIconFile</key>
<string>open-favorites</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>key1</key>
<string>value1</string>
</dict>
</dict>
<dict>
<key>UIApplicationShortcutItemTitle</key>
<string>Static Shortcut 2</string>
<key>UIApplicationShortcutItemType</key>
<string>com.distriqt.test.static_shortcut_2</string>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeCompose</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>key2</key>
<string>value2</string>
</dict>
</dict>
</array>
- + \ No newline at end of file diff --git a/docs/forcetouch/changelog/index.html b/docs/forcetouch/changelog/index.html index b1306d0cd43..5658c3a56a8 100644 --- a/docs/forcetouch/changelog/index.html +++ b/docs/forcetouch/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.18 [v3.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2022.02.05 [v3.1.48]

Update docs to use apm
Update air package dependencies
Android 31 updates

2021.10.05 [v3.1.47]

Add air package
Remove ios minimum version flag
Add android x64

2020.05.13 [v3.1.046]

Updated shortcuts.isSupported on iOS 13 + devices without force touch (resolves #13)

2020.04.06 [v3.0.045]

Android implementation of application shortcuts and pressure events

2020.03.22 [v2.0.026]

Android X migration (resolves #12)

2019.07.01 [v1.1.022]

Updated minimum iOS version to 8.0 
Embedded iOS bitcode
Removed application keys

2018.12.06 [v1.0.020]

Corrected issue with shortcut actions when in background (resolves #8)

2017.09.29 [v1.0.012]

Updates to the iOS App Delegate overrides to work better with other ANEs

2017.07.10 [v1.0.010]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2016.12.28 [v1.0.009]

Update for latest SDK + documentation

2015.11.18

Initial release of ForceTouch ANE
- + \ No newline at end of file diff --git a/docs/forcetouch/force-touch-events/index.html b/docs/forcetouch/force-touch-events/index.html index f8fb70b3700..1ab2b51d5cf 100644 --- a/docs/forcetouch/force-touch-events/index.html +++ b/docs/forcetouch/force-touch-events/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Force Touch Events

Listening for Events

// Enable listeners for the force touch events
ForceTouch.service.addEventListener( ForceTouchEvent.MAX_PRESS, touchMaxPressHandler );
ForceTouch.service.addEventListener( ForceTouchEvent.PRESS, touchPressHandler );
ForceTouch.service.addEventListener( ForceTouchEvent.ENDED, touchEndHandler );
ForceTouch.service.enableForceTouch();
private function touchPressHandler( event:ForceTouchEvent ):void
{
trace("X position: " + event.x);
trace("Y position: " + event.y);
trace("Pressure: " + event.pressure);
}


private function touchMaxPressHandler( event:ForceTouchEvent ):void
{
trace("Max force touch registered!");
}


private function touchEndHandler( event:ForceTouchEvent ):void
{
trace("Force touch ended");
}
- + \ No newline at end of file diff --git a/docs/forcetouch/index.html b/docs/forcetouch/index.html index c6f2b82d231..9345174b8a0 100644 --- a/docs/forcetouch/index.html +++ b/docs/forcetouch/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ extension gives access to pressure events and application shortcuts for Android 25+ and iOS 9+ "3D touch" enabled devices.

The simple API allows you to quickly integrate pressure events and application shortcuts in your AIR application in just a few lines of code. We provide complete guides and asdocs to get you up and running quickly and easily.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

var shortcut:ApplicationShortcut = new ApplicationShortcut()
.setIdentifier( "com.distriqt.test.news" )
.setTitle( "News" );

ForceTouch.service.shortcuts.addDynamicShortcut( shortcut );

ForceTouch.service.shortcuts.addEventListener(
ApplicationShortcutEvent.SHORTCUT_SELECTED,
shortcutSelectedHandler
);


function shortcutSelectedHandler( event:ApplicationShortcutEvent ):void
{
// process shortcut
}

More information here:

com.distriqt.ForceTouch

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/gameservices/access-point/index.html b/docs/gameservices/access-point/index.html index 0f9bb37a398..fd1faa3c222 100644 --- a/docs/gameservices/access-point/index.html +++ b/docs/gameservices/access-point/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Access Point

Access Point

You can add an access point to your game that provides a way for players to manage their profile, and view leaderboards, and achievements.

The access point initially shows player highlights, like how many achievements they’ve earned and where they stand in leaderboards. Then the access point collapses into the player’s avatar and remains on your game’s screen. When the player taps or clicks the avatar, GameKit displays the dashboard so players can drill down into the details of their Game Center data, including more highlights and statistics. You can choose where to display the access point, and select the highlights to display.

Support

To check whether the access point is supported on the current service and device check the isSupported property:

if (GameServices.service.accessPoint.isSupported)
{
// Access point is available
}

This will return false on unsupported situations such as iOS versions lower than 14.

Configure the Access Point

You can place the access point in a corner of the screen and choose whether to show highlights when the access point first appears, such as the number of achievements or the player’s rank on the default leaderboard.

Start by constructing an AccessPointOptions instance and setting the required location and whether to showHighlights:

var options:AccessPointOptions = new AccessPointOptions()
.setLocation( AccessPointOptions.LOCATION_TOP_LEADING )
.setShowHighlights( true )
;

Then when you are ready to display the access point, call activate():

GameServices.service.accessPoint.activate( options );

You can hide the access point by calling deactivate():

GameServices.service.accessPoint.deactivate();

This is useful during game intros or places where you don't want the screen obstructed.

Game Center

To give your players a consistent experience, see Access Point in the Human Interface Guidelines.

Adapt Your Game to the Access Point

You can retrieve the frame occupied by the access point at any time using the getFrame() method:

var frame:Rectangle = GameServices.service.accessPoint.getFrame();

Additionally you can listen for the AccessPointEvent.FRAME_CHANGED event which will be dispatched any time the displayed area occupied by the access point changes.

GameServices.service.accessPoint.addEventListener( 
AccessPointEvent.FRAME_CHANGED,
frameChangedHandler );

function frameChangedHandler( evnet:AccessPointEvent ):void
{
var frame:Rectangle = GameServices.service.accessPoint.getFrame();

// make changes to your UI as required
}
- + \ No newline at end of file diff --git a/docs/gameservices/achievements/index.html b/docs/gameservices/achievements/index.html index bbab61d1270..54de5b0c618 100644 --- a/docs/gameservices/achievements/index.html +++ b/docs/gameservices/achievements/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Achievements

Achievements can be a great way to increase your users' engagement within your game. You can implement achievements in your game to encourage players to experiment with features they might not normally use, or to approach your game with entirely different play styles. Achievements can also be a fun way for players to compare their progress with each other and engage in light-hearted competition.

An Achievement

An achievement is made up of a series of pieces of information that describe and identify the achievement. It is represented by the Achievement class and includes:

  • id: A unique string that is generated by the game service.
  • name: A short name of the achievement (for example, "Master Pieman").
  • state: The current state of the achievement for the current signed in player
  • type: The type of the achievement, generally either standard or incremental
  • points: The number of points or XP the player earns by completing this achievement

States

Achievements can be in one of three different states, defined in the AchievementState class:

  • STATE_UNLOCKED: Unlocked state means that the achievement has been unlocked or earnt by the player
  • STATE_REVEALED: Revealed state means that the achievement has been shown to the player but not yet unlocked
  • STATE_HIDDEN: Hidden state means that the achievement is hidden from the player

The state variable on an Achievement object describes the state of the achievement for the current logged in user.

Types

Achievements can be designated as standard or incremental, indicated by the type variable on an Achievement object. These types are defined in the AchievementType class:

  • TYPE_STANDARD: A standard type achievement
  • TYPE_INCREMENTAL: An incremental achievement, meaning that it requires several steps to unlock the achievement. (All iOS achievements are of this type)

Generally, an incremental achievement involves a player making gradual progress towards earning the achievement over a longer period of time. As the player makes progress towards the incremental achievement, you can report the player's partial progress to the games services. The service keeps track of the progress information, alerts the game when the player has met the criteria necessary to unlock that achievement, and tells the player how far along they are towards meeting that goal.

Incremental achievements are cumulative across game sessions, and progress cannot be removed or reset from within the game. For example, "Win 50 games" would qualify as an incremental achievement. "Win 3 games in a row" would not, as the player's progress would be reset when they lose a game. "Have 5,000 poker chips" would not qualify either, as a player could gain and lose chips as they play. For the latter two achievements, it's up to you to track the player's "Wins in a row" state or chip total and to unlock standard achievements when the player earns them.

Points

Achievements have a point value associated with them. The player's score must be a multiple of 5 and a game can never have a total of more than 1000 points for all of its achievements (although it can have less). In addition, no single achievement can have more than 200 points.

Creating Achievements

Usage

To access the achievements functionality you will be using the functionality defined in the Achievements interface accessed by GameServices.service.achievements.

You must have a signed in player in order to access the achievements functionality.

Generally it is good practice to define the achievement IDs as static strings in your application. This reduces the requirement for you to load an achievement from the service. Most of the calls do not require usage of the Achievement object but just specify the ID.

Supported

Checking for support of achievements can be done via the isSupported flag on the Achievements interface:

if (GameServices.service.achievements.isSupported)
{
// Achievements functionality is supported
}

Some services may not implement achievements or may not support the user's current device (operating system or version). You should check this flag before attempting to use the achievements functionality.

Unlocking Achievements

When your player has satisfied your game requirements for an achievement and you want the player to be rewarded for this achievement you will be unlocking the achievement for the player.

To unlock an achievement use the achievementUnlock function passing the achievement ID as the parameter:

GameServices.service.achievements.achievementUnlock( "my_achievement_id" );

If the achievement has already been unlocked, this will have no effect.

Incremental Achievements

If the achievement is an incremental achievement you should update the number of steps instead of calling achievementUnlock.

To update the number of steps you can call either achievementStepsIncrement() or achievementStepsSet(). achievementStepsIncrement will increment the current number of steps by the specified amount and is useful if you aren't tracking the current number of steps in your game. achievementStepsSet sets an achievement to have at least the given number of steps completed (you cannot decrease the number of steps and any calls to this function with a smaller number of steps will have no effect).

Once the achievement reaches the maximum number of steps the achievement will be automatically unlocked, and any further operations will have no effect.

Revealing Achievements

If you are using hidden achievements in your game you can reveal them to the player at the appropriate point in your application by calling the achievementReveal() function and passing the achievement id of interest:

GameServices.service.achievements.achievementReveal( "my_hidden_achievement_id" );

Revealing means that the achievement will now be shown to the player, once revealed an achievement cannot be hidden again.

If the achievement has already been revealed, this will have no effect.

Load Achievements

If you need to load the information about the player's achievements, for example, you may wish to construct your own UI for the player you can load the achievements and their current state by calling loadAchievements().

GameServices.service.achievements.loadAchievements();

This call is asynchronous and you will need to listen to the AchievementEvent.ACHIEVEMENTS_LOADED and AchievementEvent.ACHIEVEMENTS_ERROR events for the result of the call:

GameServices.service.achievements.addEventListener( AchievementEvent.ACHIEVEMENTS_LOADED, achievementsLoaded );
GameServices.service.achievements.addEventListener( AchievementEvent.ACHIEVEMENTS_ERROR, achievementsError );
GameServices.service.achievements.loadAchievements();


function achievementsLoaded( event:AchievementEvent ):void
{
// event.data will contain an Array of Achievement objects
}

function achievementsError( event:AchievementEvent ):void
{
// an error occurred loading the achievements
}

Displaying Achievements UI

To show a player's achievements, call displayAchievementsUI().

GameServices.service.achievements.displayAchievementsUI();

Your game will then display the default achievements UI, for example, Google Play Games on Android:

Game Center on iOS:

Game Center Achievements

You can also listen for the AchievementEvent.ACHIEVEMENTS_UI_CLOSED event to be informed about the user closing the native achievements UI:

GameServices.service.achievements.addEventListener( AchievementEvent.ACHIEVEMENTS_UI_CLOSED, uiClosedHandler );
GameServices.service.achievements.displayAchievementsUI();

function uiClosedHandler( event:AchievementEvent ):void
{
// ui closed .. resume your game
}
- + \ No newline at end of file diff --git a/docs/gameservices/auth-utilities/index.html b/docs/gameservices/auth-utilities/index.html index 1e5775504b1..91b4465443d 100644 --- a/docs/gameservices/auth-utilities/index.html +++ b/docs/gameservices/auth-utilities/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ on behalf of a specified user account.

To retrieve a token you call the getToken function with the scopes you require. The scopes define how the token can be consumed, ie. the services that you will have access to.

For example:

if (GameServices.service.authUtil.isSupported)
{
GameServices.service.authUtil.addEventListener( AuthUtilEvent.AUTH_TOKEN_SUCCESS, authTokenSuccessHandler );
GameServices.service.authUtil.addEventListener( AuthUtilEvent.AUTH_TOKEN_ERROR, authTokenErrorHandler );

GameServices.service.authUtil.getToken();
}

Then your event handlers:

private function authTokenSuccessHandler( event:AuthUtilEvent ):void
{
trace( "AUTH UTIL TOKEN: " + JSON.stringify( event.data ));
}

private function authTokenErrorHandler( event:AuthUtilEvent ):void
{
trace( "AUTH UTIL ERROR: " + event.data );
}

Google Play Game Services

With Google Play Game Services this process will retrieve the current Google user's Server Auth Code and the ID Token from the GoogleSignInAccount.

If available the following will be returned in the event.data object:

You will get an error event if you haven't specified the serverClientId in your service.

Once you have the auth code you can send the server auth code to your backend server to exchange for access and refresh tokens. Use the access token to call the Google Play Games Services API on behalf of the player and, optionally, store the refresh token to acquire a new access token when the access token expires.

Game Center

For GameCenter this returns the Identity Verification Signature from the generateIdentityVerificationSignatureWithCompletionHandler function.

The following will be returned in the event.data object:

More information.

- + \ No newline at end of file diff --git a/docs/gameservices/changelog/index.html b/docs/gameservices/changelog/index.html index 6736b30a723..e99d70e8310 100644 --- a/docs/gameservices/changelog/index.html +++ b/docs/gameservices/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.08.17 [v8.3.0]

feat(android): Huawei Game Service v6.10.0.300 integration (sign in, leaderboards, achievements) (resolves #225)
fix(gamecenter): fix crash if called initialise multiple times
feat(docs): update docs to separate services and add documentation for huawei

2023.07.05 [v8.2.0]

feat(android): update to google game services v23.1.0
feat(android): air background thread handling
feat(gamecenter, docs, airpackage): add game center capability setup process and addition to entitlements (resolves #233)

2023.01.27 [v8.1.1]

fix(air): reverted extension namespace to air 33.1

2023.01.20 [v8.1.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2022.12.15 [v8.0.5]

fix(desktop): fix issue with isSupported flag with adl on macOS

2022.11.14 [v8.0.4]

fix(airpackage,docs): fix missing queries manifest additions required to check Play Games install state (resolves #227)

2022.03.22 [v8.0.3]

Correct missing dependency in air package (resolves #214)

2022.03.11 [v8.0.2]

Fix for issue creating save games caused by an undocumented Play Games change (resolves #210)

2022.03.08 [v8.0.0]

Android: Update Google Play Games to v22.0.1 (#210, #203)
Android: Update for Android 31
macOS: Initial implementation of Game Center

Add descriptions to air package
Update docs to use apm and additions for Android 31

2021.09.28 [v7.2.7]

Corrected timestamp negative value issues (resolves #204)

2021.09.01 [v7.2.2]

Added leaderboard score tags to add context to a score entry
Added airpackage

2021.08.11 [v7.1.13]

Updated documentation around adding Google Play Games app id to manifest (resolves #199)

2021.07.19 [v7.1.11]

Removed ios minimum version flag

2021.03.03 [v7.1.009]

Added Access Point functionality for Game Center on iOS 14+
Added generic show UI functionality to show dashboard elements (resolves #189)

2021.01.20 [v7.0.005]

Updated Google Play Games to v21.0.0
- Deprecated Google related multiplayer functionality

2020.09.01 [v6.3.001]

Updated Google Play Games to v20.0.1

2020.07.09 [v6.2.062]

Implemented automatic sign in continuation after GPG installation
Added isGooglePlayGamesInstalled flag (resolves #177)

2020.06.30 [v6.1.056]

Updated to Google Play Games v19.0.0 
Clarified documentation around sign out events (resolves #176)
Removed additional permission request that isn't required for Google Play Games to simplify sign in process (resolves #166)
Removed pre-check of Play Games app for isServiceSupported check allowing display of the “Install Google Play Games” dialog (resolves #173)

2020.03.22 [v6.0.033]

Android X migration (resolves #164)
Android: Play Games: Fixed issue with id token not refreshing (resolves #161)

2020.02.26 [v5.1.026]

Documentation update + minor AuthUtil updates

2019.12.11 [v5.1.020]

Android: Added checks for saved game data (resolves #158)
Android: Better handling of achievements and leaderboard ui display
Android: Added additional checks for support for Google Play games

2019.09.05 [v5.0.011]

Android 64bit support (resolves #146)
Updated minimum iOS version to 9.0
Added checks for null pointer (#144)
Android: Corrected UI element display when not calling signIn (resolves #147)
Corrected TBM rematch functionality (resolves #151)
Embedded iOS bitcode
Added GoogleSignInStatusCode to sign in failed event (resolves #145)
Game Center corrected dismiss match when not active player turn (resolves #154)

2019.02.21 [v4.3.224]

Updated minimum iOS version option

2019.02.21 [v4.3.223]

Corrected missing class from default implementation (resolves #140)

2019.01.14 [v4.3.222]

Add loadPlayer method for asynchronous player information retrieval (resolves #132)

2019.01.07 [v4.2.213]

Android: Ensured sign in call always dispatches event (resolves #135)

2018.11.27 [v4.2.206]

Updated to Google Play Services v16.0.5 
Removed application keys

2018.11.18 [v4.1.204]

Updated documentation

2018.11.18 [v4.1.203]

Simplified integration with Google Identity sign-in

2018.10.25 [v4.1.198]

Started some troubleshooting docs

2018.10.25 [v4.1.196]

Updated Turn Based Multiplayer documentation (#107)
Added NoRecording variant without ReplayKit (resolves #124)
Added checks for replay kit on iOS 8 and lower (#124)

2018.10.08 [v4.1.186]

Corrected events from Turn Based Matches on certain Android versions (#107)

2018.09.14 [v4.1.183]

iOS: GameCenter: Handled duplicate notification of conflicts from Apple (resolves #115)

2018.09.10 [v4.1.175]

iOS: GameCenter: Corrected resolve conflict return events (#115)

2018.09.10 [v4.1.174]

iOS: GameCenter: Corrected loading of saved game data on conflict (resolves #115)

2018.07.04 [v4.1.166]

Android: Removed automatic request of email address of Google Play users (#110)

2018.06.22 [v4.1.165]

Added screen recording:
- ReplayKit on iOS;
- Google Play Games Recording on Android
Added ability to reset achievements where available
Android: Corrected sign in process on relaunch where account still present (resolves #104)
Android: Corrected display of notification popups (resolves #106)
Android: Additional checks on player success (resolves #108)

2018.03.02 [v4.0.068]

Android: Corrected all leaderboards display (#101)

2018.03.01 [v4.0.067]

Removed incorrectly packaged Google iOS frameworks (#101)

2018.02.25 [v4.0.066]

AppleTV (tvOS) implementation
Major Google Play Games update
- Updated SDK
- New sign in method (resolves #100) (https://developers.google.com/identity/sign-in/android/migration-guide)
- Updated Auth utilities
- Added Players functionality
- Quests deprecated (https://android-developers.googleblog.com/2017/04/focusing-our-google-play-games-services.html)
- iOS deprecated

2017.10.08 [v3.4.015]

Added Achievements and Leaderboard documentation (resolves #96)
Added Saved Games conflict handling documentation (resolves #97)

2017.07.26 [v3.4.015]

Added issue template and support docs

2017.07.26 [v3.4.015]

Fixed error on dispose (resolves #90)
iOS: Corrected sign in failed event with silent signin (resolves #91)

2017.07.10 [v3.3.011]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.06.20 [v3.3.010]

Added Turn Based Multiplayer Documentation

2017.04.28 [v3.3.010]

Updated Game Center documentation (#86)

2017.02.07 [v3.3.010]

Android: Update for incorrect handling of native UI sign out (resolves #84)
Android: Update to Google Play Services v10.0.1

2017.02.07 [v3.3.010]

Android: Update for incorrect handling of native UI sign out (resolves #84)
Android: Update to Google Play Services v10.0.1

2016.12.28 [v3.3.006]

Updated documentation

2016.12.20 [v3.3.005]

Update wiki

2016.12.20 [v3.3.005]

Fix for crash on iOS 7 + initial wiki

2016.10.26 [v3.3.001]

Added Game Center load player friends functionality (resolves #77)

2016.08.18 [v3.2.006]

Android: Corrected loading saved games with no cover images (#74)

2016.08.10 [v3.2.003]

Android: Removed additional activity dependencies to remove visual issues (resolves #66)
Added ability to load player centered leaderboard data (resolves #62)
Added ability to load current players leaderboard score (resolves #61)
Game Center: Added ability to get player server authentication (resolves #69)

2016.07.04

iOS: Added Game Center Saved Games (resolves #64)
iOS: Resolved sign-in popup displaying twice for Game Center (resolves #63)
iOS: Updated to latest Google Play Games SDK
Renamed ANE files to be less confusing on supported platforms

2016.05.12

Google Play: Quests and Events for iOS + Android (resolves #51)

2016.02.14

iOS: Corrected framework inclusions (resolves #52)

2016.02.13

iOS: Updated Play Gamse SDK (resolves #52)

2016.02.01

Android: Fix for incorrect handling of owner of save game in openGame (#50)

2015.12.24

Fixed issue with signIn after sign out from native UI (resolves #44)

2015.12.23

Android: Fixed issue when attempting to save game after signing out
Android: Added SIGN_OUT_SUCCESS event when user signs out through native UI (resolves #44)

2015.11.05

Updated to latest SDK versions
Added retrieval of Google auth token on iOS and Android (resolves #43)
Added retrieval of iconUrl and imageUrl where available
Added loading of player icon assets (resolves #18)
Android: Added timestamps to players (resolves #42)
Added 'silent' sign in for determining sign in status at start up (resolves #26)

2015.07.23

iOS: GameCenter: Added checks for getPlayer call (#33)

2015.06.23

iOS: Added a new version of the ANE for iOS 6 compatibility of Game Center (resolves #28)

2015.06.23

iOS: Added a new version of the ANE for iOS 6 compatibility of Game Center (resolves #28)

2015.06.15

Removed debug code from AS lib

2015.06.09

Android: GooglePlay: Corrected open saved game event when saved game was not found

2015.06.05

Android: Corrected operation of conflicts of saved games

2015.06.03

Android: Corrected some sign in events when user cancels the sign in (resolves #25)

2015.05.15

iOS: GameCenter: Corrected multiple sign in/out events (resolves #24)

2015.05.12

Added the ALL leaderboards UI displayed when no board ID specified (resolves #23)
Added automatic check if signin required when application brought to foreground
Android: Corrected timing of initialised event

2015.04.29

Android: x86 Build
Android: Corrected issue with UI popups not displaying (resolves #16)

2015.03.04

Separated common app delegates and notifications into a centralised Core ANE to resolve issues with conflicting ANEs (resolves #10)

2015.02.25

iOS: Corrected packaged framework structure which was causing an 'invalid binary' error (resolves #8)

2015.02.23

Android: Separated Google Play Services Library into shared ANE (resolves #5)

2015.02.13

Corrected application key check on iOS (#2)

2015.02.05

Added iOS Simulator version and some documentation updates

2015.01.05

First complete release version of the Game Services ANE with iOS GameCenter and iOS/Android Google Play
- + \ No newline at end of file diff --git a/docs/gameservices/index.html b/docs/gameservices/index.html index 0515c6244e4..92fca7a6444 100644 --- a/docs/gameservices/index.html +++ b/docs/gameservices/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Game Services

The GameServices extension allows developers to use a single cross-platform API to interface with many different gaming platforms.

The single API allows you to quickly integrate leaderboards, achievements, saved games and more in your AIR application, and without having to worry about different APIs for each of the services you wish to use. This allows you to use an identical code base across multiple platforms allowing you to concentrate on your application rather than platform and gaming service specifics.

Leaderboards allow you to create score boards for your application allowing your players to compare their scores against other players. You can easily display the built in user interfaces for the leaderboards or build your own loading the scores for the leaderboards and displaying as you require.

Achievements can be a great way to increase your users' engagement within your game. You can implement achievements in your game to encourage players to experiment with features they might not normally use, or to approach your game with entirely different play styles. Achievements can also be a fun way for players to compare their progress with each other and engage in light-hearted competition.

The Saved Games service gives you a convenient way to save your players' game progression to the game service servers. Your game can retrieve the saved game data to allow returning players to continue a game at their last save point from any device.

We provide complete guides to get you up and running with the different game services quickly and easily.

Current Services

  • Google Play on Android;
  • Apple Game Center on iOS and tvOS

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Features

  • Player sign in;
  • Access to your leaderboards, and top scores;
  • Submit new scores to your leaderboards;
  • Access to your achievements;
  • Achievement progress and unlocking;
  • Save and load data to and from Saved Games;
  • Turn Based Multiplayer;

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

More information here:

com.distriqt.GameServices

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/gameservices/initialise-the-service/index.html b/docs/gameservices/initialise-the-service/index.html index 05454041303..d4fe46d270f 100644 --- a/docs/gameservices/initialise-the-service/index.html +++ b/docs/gameservices/initialise-the-service/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Initialise the Service

This step initialises the platform using your game service settings. Initialising the service performs serveral things, notably:

  • configures the extension to use the requested service;
  • initialises any required configuration and connections to the service;

You perform this initialisation by firstly constructing an instance of the Service class, setting the required service type and then passing this to the initialiseService() method.

This will then dispatch either:

  • GameServicesEvent.INITIALISED: when the service is initialised successfully and game services are available;
  • GameServicesEvent.INITIALISE_ERROR: when the service failed to initialise, check the error and message for help on resolving the issue;
var service:Service;


// CHANGE THIS TO INITIALISE YOUR REQUIRED SERVICE(S)

if (GameServices.service.isServiceSupported( Service.HUAWEI_GAME_SERVICE ))
{
service = new Service( Service.HUAWEI_GAME_SERVICE );
}

else if (GameServices.service.isServiceSupported( Service.GOOGLE_PLAY_GAME_SERVICES ))
{
service = new Service( Service.GOOGLE_PLAY_GAME_SERVICES );
}

else if (GameServices.service.isServiceSupported( Service.IOS_GAME_CENTER ))
{
service = new Service( Service.IOS_GAME_CENTER );
}


GameServices.service.addEventListener( GameServicesEvent.INITIALISED, initialisedHandler );
GameServices.service.addEventListener( GameServicesEvent.INITIALISE_ERROR, errorHandler );

GameServices.service.initialiseService( service );



function initialisedHandler( event:GameServicesEvent ):void
{
// The platform has been initialised ready for sign in functions
}

function gameServices_initialiseErrorHandler( event:GameServicesEvent ):void
{
// An error occurred, try initialising the service again later
// Check the error code for developer errors and potentially network issues
}
- + \ No newline at end of file diff --git a/docs/gameservices/leaderboards/index.html b/docs/gameservices/leaderboards/index.html index 5630195103f..82b791f3535 100644 --- a/docs/gameservices/leaderboards/index.html +++ b/docs/gameservices/leaderboards/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Leaderboards

Leaderboards can be a fun way to drive competition among your players, both for your most hardcore fans (who will be fighting for the top spot in a public leaderboard) and for your more casual players (who will be interested in comparing their progress to their friends').

When you create a leaderboard, the games service will take care of managing most aspects of this leaderboard for you. The typical process works like this:

  • At the end of a game (or at an appropriate moment that you've determined), the game submits the player's score to one or more leaderboards you've created for the game.
  • The games service checks if this score is better than the player's current leaderboard entry for the daily, weekly, or all-time score. If it is, the games service updates the corresponding leaderboards with the new score.
  • To retrieve a player's results for a leaderboard, you can requests a time frame (daily, weekly, or all-time), and specify whether or not the user wants to see a social or public leaderboard. The Games service performs all the necessary filtering, and then sends the results back to the client.

A Leaderboard

A leaderboard is represented by the Leaderboard class and is made up of a series of pieces of information that describe and identify the leaderboard.

These basic elements are associated with every leaderboard:

  • id: A unique string that identifies the leaderboard in the game service.
  • displayName: A short display name of the leaderboard (for example, "High Scores" or "Level 3").
  • scoreOrder: The order in which the scores are ordered in the leaderboard

Score Order

The score order represents the order in which the scores are ordered in the leaderboard. Generally larger values are better however there are circumstances where smaller are better, such as lap times in a racing game.

These orders are defined in the Leaderboard class:

  • Leaderboard.SCORE_ORDER_LARGEST_FIRST: Larger is better leaderboards are the default. This is typically what you would see in most games where players earn points.
  • Leaderboard.SCORE_ORDER_LARGEST_FIRST: Smaller is better leaderboards are occasionally used in cases where a smaller score would be better. The most common examples of this type of leaderboard are in racing games, where the score represents the player's time to finish the race.

Creating Leaderboards

Usage

To access the leaderboards functionality you will be using the functionality defined in the Leaderboards interface accessed by GameServices.service.leaderboards.

You must have a signed in player in order to access the leaderboards functionality.

Generally it is good practice to define the leaderboard IDs as static strings in your application. This reduces the requirement for you to load the leaderboards from the service. Most of the calls do not require usage of a Leaderboard object but just specify the ID.

Supported

Checking for support of leaderboards can be done via the isSupported flag on the Leaderboards interface:

if (GameServices.service.leaderboards.isSupported)
{
// Leaderboards functionality is supported
}

Some services may not implement leaderboards or may not support the user's current device (operating system or version). You should check this flag before attempting to use the leaderboards functionality.

Submit Score

When the player's score changes (for example, when the player finishes the game), your game can update their score on the leaderboard by calling submitScore(), and passing in the leaderboard ID and the raw score value.

GameServices.service.leaderboards.submitScore( "leaderboard_id", score );

The score value must be an integer.

Score Tags

You can associate a "tag" with a score to give the score some context within your application.

GameServices.service.leaderboards.submitScore( "leaderboard_id", score, "1" );

This "tag" value will then be returned when retrieving scores from a leaderboard and allows you to customise the appearance of the score in your application with this additional context information.

note

The tag is a string value here however certain services limit the type that can be used. So we suggest using only numeric characters for the tag value.

  • Game Center uses a "context" integer value so we will strip and non-numeric characters out of the tag before passing to Game Center;
  • Google Play accepts a string value so the value will be passed directly;

Load Leaderboards

You can load the leaderboards that are associated with your game by calling the loadLeaderboards() function.

This will query the server for the available leaderboards and return the details as an array of Leaderboard objects in the LeaderboardEvent.LEADERBOARDS_LOADED event.

GameServices.service.leaderboards.addEventListener( LeaderboardEvent.LEADERBOARDS_LOADED, leaderboardsLoadedHandler );
GameServices.service.leaderboards.addEventListener( LeaderboardEvent.LEADERBOARDS_ERROR, leaderboardsLoadErrorHandler );

GameServices.service.leaderboards.loadLeaderboards();

On success an array of Leaderboard objects will be avilable:

function leaderboardsLoadedHandler( event:LeaderboardEvent ):void
{
var boards:Array = event.data;
for each (var board:Leaderboard in boards)
{
trace( "["+board.id+"] "+board.displayName );
}
}

On error, the data property will contain information about the error:

function leaderboardsLoadErrorHandler( event:LeaderboardEvent ):void
{
trace( "ERROR " + event.data );
}

Loading Scores

Each leaderboard has a series of LeaderboardScores attached each representing a score entry in the leaderboard. You load these values by using one of the load methods below:

  • loadPlayerScore()
  • loadTopScores()
  • loadPlayerCenteredScores()

Each of these functions accept a range of parameters,

  • leaderboardId: The id of the specific leaderboard
  • span: The timespan of interest. Defaults to Leaderboard.TIME_SPAN_ALL_TIME but can also be daily or weekly.
  • collection: The collection of scores of interest, defaults to Leaderboard.COLLECTION_PUBLIC but if you wish to load the player's friends scores you can change this to Leaderboard.COLLECTION_SOCIAL.

Some will also take a maxResults parameter that allow you to suggest the number of results to return.

Load Player Score

You can load the player's score for a particular leaderboard by calling the loadPlayerScore() function. The success event should contain one LeaderboardScore value being the player's score in the specified leaderboard.

GameServices.service.leaderboards.addEventListener( LeaderboardEvent.PLAYERSCORE_LOADED, playerScoreLoadedHandler );
GameServices.service.leaderboards.addEventListener( LeaderboardEvent.PLAYERSCORE_ERROR, playerScoreErrorHandler );

GameServices.service.leaderboards.loadPlayerScore( "leaderboard_id" );


function playerScoreLoadedHandler( event:LeaderboardEvent ):void
{
var score:LeaderboardScore = event.data[0];
trace( "PLAYER SCORE LOADED: ["+score.rank+"] "+score.displayScore );
}

function playerScoreErrorHandler( event:LeaderboardEvent ):void
{
trace( "PLAYER SCORE ERROR" );
}

Load Top Scores

You can load the top scores of a leaderboard by using the loadTopScores() function with the leaderboard id of interest. This will dispatch either LeaderboardEvent.TOPSCORES_LOADED or LeaderboardEvent.TOPSCORES_ERROR in the case of success and failure respectively.

GameServices.service.leaderboards.addEventListener( LeaderboardEvent.TOPSCORES_LOADED, scoresLoadedHandler );
GameServices.service.leaderboards.addEventListener( LeaderboardEvent.TOPSCORES_ERROR, scoresErrorHandler );

GameServices.service.leaderboards.loadTopScores( "leaderboard_id" );

On success you will have access to an array of score values:

function scoresLoadedHandler( event:LeaderboardEvent ):void
{
var board:Leaderboard = event.leaderboard;
var scores:Array = event.data;

for each (var score:LeaderboardScore in scores)
{
trace( score.displayRank +" :: "+ score.displayScore +" :: "+ score.player.displayName );
}
}

On error, the data property will contain information about the error:

function scoresErrorHandler( event:LeaderboardEvent ):void
{
trace( "ERROR::"+ event.data );
}

Load Player Centered Scores

Similar to loading the top scores of a leaderboard, you can load the scores around the players score by using the loadPlayerCenteredScores() function with the leaderboard id of interest. This will dispatch either LeaderboardEvent.PLAYERCENTEREDSCORES_LOADED or LeaderboardEvent.PLAYERCENTEREDSCORES_ERROR in the case of success and failure respectively.

GameServices.service.leaderboards.addEventListener( LeaderboardEvent.PLAYERCENTEREDSCORES_LOADED, scoresLoadedHandler );
GameServices.service.leaderboards.addEventListener( LeaderboardEvent.PLAYERCENTEREDSCORES_ERROR, scoresErrorHandler );

GameServices.service.leaderboards.loadPlayerCenteredScores( "leaderboard_id" );

On success you will have access to an array of score values:

function scoresLoadedHandler( event:LeaderboardEvent ):void
{
var board:Leaderboard = event.leaderboard;
var scores:Array = event.data;

for each (var score:LeaderboardScore in scores)
{
trace( score.displayRank +" :: "+ score.displayScore +" :: "+ score.player.displayName );
}
}

On error, the data property will contain information about the error:

function scoresErrorHandler( event:LeaderboardEvent ):void
{
trace( "ERROR::"+ event.data );
}

Displaying Leaderboard UI

To display the native leaderboard UI, call displayLeaderboardUI() with the leaderboard id of interest.

GameServices.service.leaderboards.displayLeaderboardUI( "leaderboard_id" );

Your game will then display the leaderboard UI for the specified leaderboard, for example, Google Play Games on Android:

Game Center on iOS:

You can also listen for the LeaderboardEvent.UI_CLOSED event to be informed about the user closing the native UI:

GameServices.service.leaderboards.addEventListener( LeaderboardEvent.UI_CLOSED, uiClosedHandler );

GameServices.service.leaderboards.displayLeaderboardUI( "leaderboard_id" );

function uiClosedHandler( event:AchievementEvent ):void
{
// ui closed .. resume your game
}
- + \ No newline at end of file diff --git a/docs/gameservices/migrating-to-androidx/index.html b/docs/gameservices/migrating-to-androidx/index.html index 2cd9fab624a..75fa22d5af9 100644 --- a/docs/gameservices/migrating-to-androidx/index.html +++ b/docs/gameservices/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/gameservices/quests-and-events/index.html b/docs/gameservices/quests-and-events/index.html index 858c0b17e11..65942af7a95 100644 --- a/docs/gameservices/quests-and-events/index.html +++ b/docs/gameservices/quests-and-events/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ reward through the native UI. You should account for both scenarios by making sure you always have an event listener for the QuestEvent.QUEST_CLAIM_SUCCESS event, and reward your player when this event occurs.

private function questsCompletedHandler( event:QuestEvent ):void
{
var quest:Quest = event.quests[0];
trace( "QUEST COMPLETED: " + quest.questId + "::"+ quest.currentMilestone.milestoneId );

// Call this when your user claims the reward
GameServices.service.quests.claim( quest.questId, quest.currentMilestone.milestoneId );
}

private function questsClaimSuccessHandler( event:QuestEvent ):void
{
// Use the rewardData as required to give your player the quest reward
trace( "CLAIM SUCCESS: " + event.quests[0].currentMilestone.rewardData.toString() );
}

private function questsClaimErrorHandler( event:QuestEvent ):void
{
trace( "CLAIM ERROR:" + event.message );
}
- + \ No newline at end of file diff --git a/docs/gameservices/saved-games---conflicts/index.html b/docs/gameservices/saved-games---conflicts/index.html index 219cf2b1664..f17d0d16436 100644 --- a/docs/gameservices/saved-games---conflicts/index.html +++ b/docs/gameservices/saved-games---conflicts/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Saved Games - Conflicts

Detecting Conflicts

When using the Saved Games service in your game, it is possible for multiple devices to perform reads and writes on the same saved game. In the event that a device temporarily loses its network connection and later reconnects, this might cause data conflicts whereby the saved game stored on a player's local device is out-of-sync with the remote version stored in service's servers. The Saved Games services provides a conflict resolution mechanism that presents both sets of conflicting saved games at read-time and lets you implement a resolution strategy that is appropriate for your game.

When the games service detects a data conflict, it notifies your game during a saved game operation (open, create, save etc) by dispatching a SavedGamesEvent.CONFLICT event.

You should make sure you add a listener for this event before attempting any saved game operation.

GameServices.service.savedGames.addEventListener( SavedGamesEvent.CONFLICT, conflictHandler );


function conflictHandler( event:SavedGamesEvent ):void
{
// Handle the conflict here

// event.conflictId identifies this conflict
}

The conflict event willl contain two versions of the saved game in the data Array:

  • The most-up-to-date version known by the service to be accurate (event.data[0]); and
  • A modified version detected on one of the player's devices that contains conflicting content or metadata (event.data[1]). This may not be the same as the version that you tried to save.

It will also contain the conflictId which identifies this conflict occurrance and is required to resolve this conflict.

Resolving Conflicts

Your game must decide how to resolve the conflict by picking one of the provided versions or merging the data of the two saved game versions.

Once you have assembled the resolved version of the save game you call resolveConflict to resolve the conflict on the saved game with the conflict id and the resolved saved game as parameters:

GameServices.service.savedGames.resolveConflict( conflictId, resolvedGame );

The following snippet shows and example of how your game might handle a saved game conflict by selecting the most recent saved game as the final version to save:

function conflictHandler( event:SavedGameEvent ):void 
{
var savedGameA:SavedGame = event.data[0];
var savedGameB:SavedGame = event.data[1];

var resolvedGame:SavedGame = savedGameA.modified > savedGameB.modified ? savedGameA : savedGameB;
GameServices.service.savedGames.resolveConflict( event.conflictId, resolvedGame );
}

This call will result in either a SavedGamesEvent.CONFLICT_RESOLVE_SUCCESS or a SavedGamesEvent.CONFLICT_RESOLVE_ERROR event.

GameServices.service.savedGames.addEventListener( SavedGamesEvent.CONFLICT_RESOLVE_SUCCESS, resolveSuccessHandler );
GameServices.service.savedGames.addEventListener( SavedGamesEvent.CONFLICT_RESOLVE_ERROR, resolveErrorHandler );


function resolveSuccessHandler( event:SavedGamesEvent ):void
{
// The conflict was resolved and you can resume normal loading/saving etc.
}

function resolveErrorHandler( event:SavedGamesEvent ):void
{
// The conflict wasn't resolved and will be encountered on the next saved games operation again
}

Be aware that the call to resolve a conflict may itself dispatch another SavedGamesEvent.CONFLICT event, if for some reason there were a series of conflicts awaiting resolution.

Simply ensure that your conflict handler is never removed and always available to handle conflict resolutions.

- + \ No newline at end of file diff --git a/docs/gameservices/saved-games/index.html b/docs/gameservices/saved-games/index.html index f4326581626..bf7ed1090a9 100644 --- a/docs/gameservices/saved-games/index.html +++ b/docs/gameservices/saved-games/index.html @@ -13,7 +13,7 @@ - + @@ -43,7 +43,7 @@ Game Center is only limited by the users' iCloud available space.

var savedGame:SavedGame = ...; // This should be the currently opened user saved game

// Some game data
var data:String = "<game><a>data</a><b>"+Math.random().toPrecision(5)+"</b></game>";

// Change the description of the saved game
savedGame.description = "Saved game " + String( 1000 * Math.random());

// Write the new data
savedGame.data.clear();
savedGame.data.writeUTFBytes( data );
savedGame.data.position = 0;

GameServices.service.savedGames.addEventListener( SavedGamesEvent.SAVE_SUCCESS, savedGamesSaveSuccessHandler );
GameServices.service.savedGames.addEventListener( SavedGamesEvent.SAVE_ERROR, savedGamesSaveErrorHandler );

GameServices.service.savedGames.saveGame( savedGame );

The events will tell us the success or failure of the save:

function savedGamesSaveSuccessHandler( event:SavedGamesEvent ):void
{
trace( "SAVE SUCCESS" );
}

function savedGamesSaveErrorHandler( event:SavedGamesEvent ):void
{
trace( "SAVE ERROR: "+event.data );
}

Deleting Saved Games

Deleting a saved game is simply a process of calling deleteGame and passing a valid SavedGame object.

var savedGame:SavedGame = ...; // This should be a reference to a saved from returned from a load or open

GameServices.service.savedGames.addEventListener( SavedGamesEvent.DELETE_SUCCESS, savedGamesDeleteSuccessHandler );
GameServices.service.savedGames.addEventListener( SavedGamesEvent.DELETE_ERROR, savedGamesDeleteErrorHandler );

GameServices.service.savedGames.deleteGame( savedGame );


function savedGamesDeleteSuccessHandler( event:SavedGamesEvent ):void
{
trace( "SAVE SUCCESS" );
}

function savedGamesDeleteErrorHandler( event:SavedGamesEvent ):void
{
trace( "SAVE ERROR: "+event.data );
}

Saved Games UI

To simplify your development, the Saved Games API provides a default Saved Games selection user interface (UI) that you can use out-of-the-box. The Saved Games selection UI allows players to create a new saved game, view details about existing saved games, and load previous saved games.

GameServices.service.savedGames.displaySavedGamesUI( "Saved Games" );


- + \ No newline at end of file diff --git a/docs/gameservices/screen-recording/index.html b/docs/gameservices/screen-recording/index.html index a0a78591111..a5db2bdbe0e 100644 --- a/docs/gameservices/screen-recording/index.html +++ b/docs/gameservices/screen-recording/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ you should not attempt to start recording if it isn't available.

To check simply use the checkAvailability function, either with a callback function:

GameServices.service.recording.checkAvailability( function( available:Boolean ):void
{
// available indicates if screen recording is available
});

Or using an event:

GameServices.service.recording.addEventListener( ScreenRecordingEvent.AVAILABILITY_CHANGED, changeHandler );
GameServices.service.recording.checkAvailability();

function changeHandler( event:ScreenRecordingEvent ):void
{
GameServices.service.recording.removeEventListener( ScreenRecordingEvent.AVAILABILITY_CHANGED, changeHandler );
var available:Boolean = GameServices.service.recording.checkAvailability();
}

Start Recording

To start the recording you call the start function:

GameServices.service.recording.start();

This will either start recording or present controls for the user to start recording.

For example, on Google Play Games, you cannot start a recording directly, instead this call presents the screen recording controls.

Whereas on ReplayKit you can start a recording directly, so this call will initiate the recording.

At this point you can expect either a ScreenRecordingEvent.CONTROLS_SHOWN event, a ScreenRecordingEvent.STARTED event, or if an error occurred you could encounter a ScreenRecordingEvent.ERROR event.

Recording Options

You can at this point specify some options for the recording on supported services, by passing a ScreenRecordingOptions object as the parameter to the start function:

var options:ScreenRecordingOptions = new ScreenRecordingOptions();

GameServices.service.recording.start( options );

No options are available here, all options will be ignored.

With iOS 9/10 you can specify an overlay UI stop button that won't be included in the screen recording. This allows you to present an interface for your user to stop the recording without being included in your game.

You can enable / disable the overlay and specify a custom bitmap data for the stop button:

var options:ScreenRecordingOptions = new ScreenRecordingOptions();
options.uiOverlayEnabled = true;
options.uiOverlayStopButton = stopButtonBitmapData;

The UI is enabled by default and uses a built in stop button as below:

With iOS 11 ReplayKit additionally allows you to specify the location of the recorded video. You can still specify the overlay UI as previously.

For example, to specify the recording is saved to the application storage directory as recording.mp4:

var recordedFile:File = File.applicationStorageDirectory.resolvePath("recording.mp4");

var options:ScreenRecordingOptions = new ScreenRecordingOptions();
options.filepath = recordedFile.nativePath;
options.quality = ScreenRecordingOptions.LOW;

The quality can be set here, either HIGH, MEDIUM or LOW. This will control the quality and hence filesize of the recorded video.

Stop Recording

With some services you can programmatically stop the screen recording.

GameServices.service.recording.stop();

This is only currently supported with ReplayKit under iOS Game Center.

Recording Events

During the screen recording process there will be a series of events dispatched depending on the current state of the recording. The main events related to a recording are:

Additionally you have the following events that are dispatched when various views / controls are presented to the user:

The order of these events depends on the service so see the section below for details on the flow through each screen recording service.

ReplayKit (GameCenter iOS/tvOS)

With ReplayKit you can control the screen recording start and stop processes, and present a stop button in an overlay that isn't recorded.

When recording starts the user will be presented with a permission dialog asking them to allow screen recording. This dialog is presented on subsequent recordings as well if there hasn't been a screen recording allowed within 8 minutes:

If they deny, you will receive an ScreenRecordingEvent.ERROR event.

If they allow, the recording will start and you will receive the ScreenRecordingEvent.STARTED event, and, if enabled, the UI overlay stop button will be shown:

iOS 9 - 10

With iOS 9 and 10, after a video is recorded ReplayKit will present a preview controller allowing the user to view and edit (trim) the video and then share or save the video to their settings. You will not have direct access to the recorded video.

You will get ScreenRecordingEvent.PREVIEW_SHOWN and ScreenRecordingEvent.PREVIEW_CLOSED events when the preview controller is shown and closed respectively. After the preview controller is closed you will receive the ScreenRecordingEvent.COMPLETE event.

iOS 11 +

From iOS 11, the preview controller is no longer presented to the user. Instead when recording stops the ScreenRecordingEvent.COMPLETE event is dispatched containing the path of the recorded file. You have direct access to this file and can present in a media player as you require, or share to other platforms.

Google Play Games (Android)

With Play Games the user controls the screen recording start and stop processes. When calling start the user is presented with a permission dialog and then UI controls are placed on screen to allow the user to enable camera / microphone recording and to start / stop the recording.

On first run, the user will be taken through a guide on the process, asked for permission and the recording quality, and then the controls will be shown:

On subsequent calls to start the user will simply be asked the recording quality and then the controls will be shown:

You will receive the ScreenRecordingEvent.CONTROLS_SHOWN event when the controls are presented to the user.

When a user starts a recording by pressing the record button, a countdown will initiate and then recording will begin. At this point you will receive the ScreenRecordingEvent.STARTED event and the controls will change to show a stop recording button.

When the user stops recording the ScreenRecordingEvent.STOPPED and the ScreenRecordingEvent.COMPLETE events will be dispatched and the user will be shown a notification asking if they wish to review the recording.

The user can dismiss these controls at any time, even without performing a recording session by dragging the controls onto the close icon which will appear in the middle of the screen when dragging. The ScreenRecordingEvent.CONTROLS_CLOSED event will be dispatched whenever the controls are removed.

- + \ No newline at end of file diff --git a/docs/gameservices/service/gamecenter/add-the-extension/index.html b/docs/gameservices/service/gamecenter/add-the-extension/index.html index 1ea55bf25b5..d14f912e667 100644 --- a/docs/gameservices/service/gamecenter/add-the-extension/index.html +++ b/docs/gameservices/service/gamecenter/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

You can access this extension here: https://github.com/distriqt/ANE-Core.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

iOS

If you are supporting saved games on Game Center then you must add the additional configuration for iCloud. You should do this before generating your application descriptor.

Firstly add a custom iOS configuration file by running:

apm generate config ios

This should produce config/ios/InfoAdditions.xml and config/ios/Entitlements.xml files alongside your project.

Edit the config/ios/Entitlements.xml file to resemble the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

<!-- GAME CENTER SAVED GAMES ADDITIONS -->
<!-- You only need the following lines if you are going to support GameCenter Saves -->
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>${iosContainerIdentifier}</string>
</array>

<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>${iosKvstoreIdentifier}</string>

</dict>
</plist>

Then set the configuration values in your project by running:

apm project config set iosContainerIdentifier CONTAINER_IDENTIFIER
apm project config set iosKvstoreIdentifier KVSTORE_IDENTIFIER

The container identifier should be the container you created in Setup Game Center and the kvstore identifier should be your iOS team id followed by your application (bundle) id.

For example:

apm project config set iosContainerIdentifier iCloud.com.distriqt.test.testcontainer
apm project config set iosKvstoreIdentifier XXXXXXYYY.com.distriqt.test

Once you have added this configuration run the steps above to update / generate your application descriptor.

tvOS

Note: Saved games are not supported on Apple tvOS. If you are supporting this platform you should not add the container to your application descriptor. If you are supporting both platforms and utilising saved games on iOS you will need to create separate projects for each and only add the above to the iOS application build.

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (GameServices.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/gameservices/service/gamecenter/setup/index.html b/docs/gameservices/service/gamecenter/setup/index.html index 8dee35b7265..86e42b32bf5 100644 --- a/docs/gameservices/service/gamecenter/setup/index.html +++ b/docs/gameservices/service/gamecenter/setup/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ platform you should not add the container to your application descriptor. If you are supporting both platforms and utilising saved games on iOS you will need to create separate application descriptors for each and only add the following to the iOS application build.

- + \ No newline at end of file diff --git a/docs/gameservices/service/gamecenter/troubleshooting/index.html b/docs/gameservices/service/gamecenter/troubleshooting/index.html index 49c49b534b8..d9f2b548321 100644 --- a/docs/gameservices/service/gamecenter/troubleshooting/index.html +++ b/docs/gameservices/service/gamecenter/troubleshooting/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/gameservices/service/huawei/add-the-extension/index.html b/docs/gameservices/service/huawei/add-the-extension/index.html index b625d2b9ece..d6367245fa3 100644 --- a/docs/gameservices/service/huawei/add-the-extension/index.html +++ b/docs/gameservices/service/huawei/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ This will correctly install all the Play Games dependencies along with Huawei Game Services.

All variants support Game Center on iOS / macOS / tvOS.

apm project config set com.distriqt.GameServices

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (GameServices.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/gameservices/service/huawei/setup/index.html b/docs/gameservices/service/huawei/setup/index.html index 8be7b48dc4b..aecdc5f63dc 100644 --- a/docs/gameservices/service/huawei/setup/index.html +++ b/docs/gameservices/service/huawei/setup/index.html @@ -13,14 +13,14 @@ - +
Skip to main content

Huawei Game Services

With Game Service, you will have access to a range of development capabilities. You can promote your game quickly and efficiently to Huawei's vast user base by having users sign in using their HUAWEI IDs. You can also use the service to quickly implement functions such as achievements, leaderboards and game addiction prevention.

AppGallery Connect

Before you start developing an app, configure app information in AppGallery Connect.

Signing Certificate Fingerprint

When configuring the signing certificate fingerprint, use the p12 certificate you are using to sign your application.

You can use the keytool utility to get the details of your p12 certificate directly, the SHA1 signature will be listed in the output from the following command:

keytool -list -v -keystore /path/to/your/certificate.p12 
keytool location

keytool is a key and certificate management utility.

You will find it in $JAVA_HOME/bin/keytool.

Enter this SHA1 fingerprint in the required section in your project settings.

Enabling Required Services

Before using Game Service, enable the permission for using its APIs in AppGallery Connect: Select your desired project, go to Project settings > Manage APIs, find Game Service, and toggle on its switch.

Ensure you enable the Game Service and Account Kit at a minimum.

AppGallery Connect Configuration File

Sign in to AppGallery Connect, download the agconnect-services.json file under Project settings > General information of the project of your app, and copy the file to your app's module directory

Add agconnect-services.json to the root of your application and ensure it is packaged.

- + \ No newline at end of file diff --git a/docs/gameservices/service/huawei/troubleshooting/index.html b/docs/gameservices/service/huawei/troubleshooting/index.html index 6f949b3f64f..432e46bbb71 100644 --- a/docs/gameservices/service/huawei/troubleshooting/index.html +++ b/docs/gameservices/service/huawei/troubleshooting/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/gameservices/service/playgames/add-the-extension/index.html b/docs/gameservices/service/playgames/add-the-extension/index.html index 08557ba9dc1..5b48d41e99c 100644 --- a/docs/gameservices/service/playgames/add-the-extension/index.html +++ b/docs/gameservices/service/playgames/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ activities and set certain information. You should add the listing below to your manifest, replacing the XXXXXXXXXXXX with your application ID that you took note of when enabling Game Services in the console. (Note you must leave the \u003 before your application id).

You should make sure your manifest contains the following:

<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>

<queries>
<package android:name="com.google.android.play.games" />
</queries>

<application android:appComponentFactory="androidx.core.app.CoreComponentFactory">

<meta-data android:name="com.google.android.gms.games.APP_ID" android:value="\u003XXXXXXXXXXXX" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

<activity
android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity"
android:excludeFromRecents="true"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<service
android:name="com.google.android.gms.auth.api.signin.RevocationBoundService"
android:exported="true"
android:permission="com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION"
android:visibleToInstantApps="true" />

<activity
android:name="com.google.android.gms.common.api.GoogleApiActivity"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />

</application>

</manifest>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (GameServices.isSupported)
{
// Functionality here
}

Check Google Play Services Availability

This extension requires the use of Google Play Services.

You should use the GoogleApiAvailability helper in the com.distriqt.playservices.Base ANE. The documentation for this class is available in the Google Play Services wiki.

For example:

import com.distriqt.extension.playservices.base.ConnectionResult;
import com.distriqt.extension.playservices.base.GoogleApiAvailability;
var result:int = GoogleApiAvailability.instance.isGooglePlayServicesAvailable();
if (result != ConnectionResult.SUCCESS)
{
if (GoogleApiAvailability.instance.isUserRecoverableError( result ))
{
GoogleApiAvailability.instance.showErrorDialog( result );
}
else
{
trace( "Google Play Services aren't available on this device" );
}
}
else
{
trace( "Google Play Services are Available" );
}

If Google Play Services aren't available then you won't be able to use the functionality in this extension.

- + \ No newline at end of file diff --git a/docs/gameservices/service/playgames/setup/index.html b/docs/gameservices/service/playgames/setup/index.html index 74f50ea57d2..548d6a60e54 100644 --- a/docs/gameservices/service/playgames/setup/index.html +++ b/docs/gameservices/service/playgames/setup/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Google Play Games

You must setup your application for Play Services, the following guide will help you through that.

Getting the SHA1 signature

If you are using the current Play App signing approach you can get the signatures of your certificates directly from the Play console, in the "App integrity" section.

This is the suggested method for the current release process through the Play Store as the certificate you are using to sign your AAB is likely just the upload certificate and not the release certificate used when the application is installed through the store.

Debugging

When debugging locally you will likely be signing an APK with your upload certificate. Hence when adding your SHA1 we suggest you also add both the SHA1 for your release certificate and the SHA1 for your upload certificate. This is so play games services will work locally when directly testing on a device.

SHA1 From A Certificate

You can use the keytool utility to get the details of your p12 certificate directly, the SHA1 signature will be listed in the output from the following command:

keytool -list -v -keystore /path/to/your/certificate.p12 
keytool location

keytool is a key and certificate management utility.

You will find it in $JAVA_HOME/bin/keytool.

Flash Builder Debug Certificate

Note: We advise against using Flash Builder currently. It is unmaintained and there are much better IDEs available for AIR now.

If you are attempting to use the default debug certificate in Flash Builder then it can be useful to add the signature of this certificate to your configuration as well. This certificate is likely different from both the upload and release certificates mentioned previously.

The following command retrieves the SHA1 signature for the debug certificate used in Flash Builder. This will allow you to test your application from debug builds.

keytool -list -v 
-keystore /Applications/Adobe\ Flash\ Builder\ 4.7/eclipse/plugins/com.adobe.flexide.multiplatform.android_4.7.0.349722/resources/debug-certificate-android.p12
-storepass debug
-storetype PKCS12

Also note Flash Builder will likely prepend .debug to your application package name so you will have to adjust that accordingly.

Add your game in the Google Play Developer Console

Create an entry for your game in the Google Play Developer Console. This enables Game services for your application, and creates an OAuth 2.0 client ID, if you don't have one yet. You must perform this step even if you have created a client ID for your game in the Google Developers Console.

  • Record the following credential information for later.
    • Your game's application ID - you will need to enter this into the apm project config or your manually managed manifest additions
    • Your game's OAuth 2.0 client ID
  • (Optional) Add achievements and leaderboards to your game by following the steps described in Configuring Achievements and Leaderboards.
  • Add test accounts for other members of your team to test your game by following the steps described in Publishing Your Game Changes.
- + \ No newline at end of file diff --git a/docs/gameservices/service/playgames/troubleshooting/index.html b/docs/gameservices/service/playgames/troubleshooting/index.html index 860e71cc99c..91566db1190 100644 --- a/docs/gameservices/service/playgames/troubleshooting/index.html +++ b/docs/gameservices/service/playgames/troubleshooting/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Troubleshooting

This is a list of common errors encountered in using the Game Services and possible resolutions.

Errors

  • 26502: CLIENT_RECONNECT_REQUIRED:

    • Generally this is caused by some issue in the account setup. We suggest you go through your application setup in Google Play and confirm everything is correctly setup especially the SHA1 of your certificate associated with the api project.
- + \ No newline at end of file diff --git a/docs/gameservices/sign-in/index.html b/docs/gameservices/sign-in/index.html index 3b3b3e9479d..6247526050f 100644 --- a/docs/gameservices/sign-in/index.html +++ b/docs/gameservices/sign-in/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ This will load information into a Player object to give you information about the player such as alias, displayName and a player identifier (ID).

GameServices.service.addEventListener( PlayerEvent.LOADED, loadPlayer_loadedHandler );
GameServices.service.addEventListener( PlayerEvent.ERROR, loadPlayer_errorHandler );
GameServices.service.loadPlayer();

function loadPlayer_loadedHandler( event:PlayerEvent ):void
{
var player:Player = event.player;

trace( "player :: "+ "["+player.id+"]" +player.displayName + "(" + player.alias + ")" );
}

function loadPlayer_errorHandler( event:PlayerEvent ):void
{
trace( "loadPlayer_errorHandler(): " + event.error );
}

Note: The getPlayer() function has been deprecated as the process to retrieve player information is now asynchronous. Using getPlayer() will only return the previously retrieved information and may be out of date or null. Calling it will trigger a load of the player information so it will become available shortly after.

var player:Player = GameServices.service.getPlayer();

Images

The Player also contains image and icon / avatar urls, however as they may be represented as content providers on Android we don't suggest you attempt to access them directly instead use the loadPlayerIcon() function:

GameServices.service.addEventListener( PlayerIconEvent.LOADED, playerIconLoadedHandler );
GameServices.service.addEventListener( PlayerIconEvent.ERROR, playerIconErrorHandler );

GameServices.service.loadPlayerIcon( player );

function playerIconLoadedHandler( event:PlayerIconEvent ):void
{
// event.icon will contain the BitmapData of the player's icon

// Starling example
var texture:Texture = Texture.fromBitmapData( event.icon );
}

private function playerIconErrorHandler( event:PlayerIconEvent ):void
{
trace( "Error: " event.error );
}

Advanced

Android

We highly recommend utilising the Google Identity ANE for advanced sign-in options. It is much more complete, providing additional controls over the sign in process and user authentication options. If you are looking for additional scopes and permissions please utilise that ANE.

With Google Play Games if you require advanced user information such as requesting additional scopes you firstly setup the ANE with the GoogleIdentityOptions.DEFAULT_GAMES_SIGN_IN option:

var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder( GoogleIdentityOptions.DEFAULT_GAMES_SIGN_IN )
.requestProfile()
.requestEmail()
.setIOSClientID( Config.googlePlayClientID )
.addScope( "additional/required/scope" )
.build();

GoogleIdentity.service.setup( options );

Then use the Google Identity sign in call instead of the Game Services:

GoogleIdentity.service.addEventListener( GoogleIdentityEvent.SIGN_IN, signInHandler );

GoogleIdentity.service.signIn();


function signInHandler( event:GoogleIdentityEvent ):void
{
// Sign in complete
}

Once complete the GameServices.service.isSignedIn() will correctly return the status as though the Game Services ANE was used directly.

- + \ No newline at end of file diff --git a/docs/gameservices/troubleshooting/index.html b/docs/gameservices/troubleshooting/index.html index 9dc6bd8df8d..263724ef998 100644 --- a/docs/gameservices/troubleshooting/index.html +++ b/docs/gameservices/troubleshooting/index.html @@ -13,13 +13,13 @@ - +
Skip to main content
- + \ No newline at end of file diff --git a/docs/gameservices/turn-based-multiplayer---implementation-overview/index.html b/docs/gameservices/turn-based-multiplayer---implementation-overview/index.html index 540367155b0..67745edfdaf 100644 --- a/docs/gameservices/turn-based-multiplayer---implementation-overview/index.html +++ b/docs/gameservices/turn-based-multiplayer---implementation-overview/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Turn Based Multiplayer - Implementation Overview

Overview

During the process of making a turned based game you will follow the procedure below:

Step 1 - Player 1

At this point the match will be valid and invited players will be sent invitations which will appear as notifications on their device. If they don't have the app installed they will be prompted to install.

Step 2 - Player 2

The other players will now receive a notification about a game invitation.

If they don't have the game installed they can install it at this point or ignore the invitation.

At this point they can accept the invitation and open / install the game. This can be done through the Game Center / Play Games application outside your application, although with Play Games you can do this in your game as well.

When this player launches the app:

As long as the player accepted one of the invitations they should now have an active match. So as part of your start up process you should load active matches.

Step 3

This step will repeat until the game is completed.

If the player has the application open then the TurnBasedMatchEvent.MATCH_UPDATED event will be dispatched and you can respond immediately.

Otherwise the player will receive a notification about a game update:

[images/android_playgames_turnnotification.png]] ](-[[images/android_playgames_turnnotification_b.png)

Either case you should process the match and give the user the option to take a turn.

Step 4

When your game logic determines the game to be complete the same process as step 3 above should be taken but instead of taking a turn the player should complete the match with the final game data.

- + \ No newline at end of file diff --git a/docs/gameservices/turn-based-multiplayer---implementation/index.html b/docs/gameservices/turn-based-multiplayer---implementation/index.html index 2fe7b2a0a13..004a29938f9 100644 --- a/docs/gameservices/turn-based-multiplayer---implementation/index.html +++ b/docs/gameservices/turn-based-multiplayer---implementation/index.html @@ -13,7 +13,7 @@ - + @@ -52,7 +52,7 @@ instead of takeTurn.

The result of the match is specified by an Array of ParticipantResult objects for each of the participants in the match that require a result. If there is simply a winner, then you can use a single ParticipantResult in this Array.

var winner:ParticipantResult = new ParticipantResult();
winner.result = ParticipantResult.MATCH_RESULT_WIN;
winner.participant = ...; // Participant from match.participants array that has won
winner.placing = 1;

match.finishMatch( [ winner ] );

The call to finishMatch will dispatch one of the following events:

match.addEventListener( TurnBasedMatchEvent.FINISH_SUCCESS, finishSuccessHandler );

function finishSuccessHandler( event:TurnBasedMatchEvent ):void
{
// Match will now be complete
}
- + \ No newline at end of file diff --git a/docs/gameservices/turn-based-multiplayer---invitations/index.html b/docs/gameservices/turn-based-multiplayer---invitations/index.html index 4db99a2fe6e..a6f263e9603 100644 --- a/docs/gameservices/turn-based-multiplayer---invitations/index.html +++ b/docs/gameservices/turn-based-multiplayer---invitations/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ which can be either INVITATION_TYPE_REAL_TIME or INVITATION_TYPE_TURN_BASED.

Turn Based Invites

Accepting a turn based match uses the GameServices.service.turnBasedMultiplayer.acceptInvitation function which will accept an available invitation to start a match.

GameServices.service.turnBasedMultiplayer.acceptInvitation( invite );

If successful the player will receive a new match object to play this game.

GameServices.service.turnBasedMultiplayer.addEventListener( TurnBasedMatchEvent.ACCEPTINVITATION_SUCCESS, acceptInvitationSuccessHandler );
private function acceptInvitationSuccessHandler( event:TurnBasedMatchEvent ):void 
{
// event.match will contain the match object
}

You can now process the match object: Add Turn-based Multplayer Support

Decline Invites

If your player doesn't wish to accept the invite and play the match, they can decline the invitation using the declineInvitation function.

GameServices.service.turnBasedMultiplayer.declineInvitation( invite );
- + \ No newline at end of file diff --git a/docs/gameservices/turn-based-multiplayer---key-concepts/index.html b/docs/gameservices/turn-based-multiplayer---key-concepts/index.html index 704e72fbc70..bf1c5137c0a 100644 --- a/docs/gameservices/turn-based-multiplayer---key-concepts/index.html +++ b/docs/gameservices/turn-based-multiplayer---key-concepts/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ asynchronously according to an order of play determined by the game. Your game can use the turn-based multiplayer API provided by games services to manage the following tasks:

Key Concepts

A turn-based match is a gaming session with multiple participants who take consecutive turns to update the game data during the match. Matches must be initiated by a player who is signed-in.

A turn-based multiplayer match contains these key properties:

Participants

If your game runs on a mobile device, the turn-based multiplayer API provides a default player selection UI. The UI allows players to invite friends or select a number of auto-match opponents. This simplifies your UI coding but you can also choose to implement your own player selection UI.

The participants in a turn-based match can fall into one of these categories:

Note: In general, when a participant leaves a match, another player cannot take that participant’s place. If a player joins by auto-matching but leaves without taking a turn immediately, games services considers that player to have abandoned the match and frees the auto-match slot for another player to join

Turn-taking

The basic flow for turn-taking is as follows:

  1. If the player initiated a match, check to see if the game data is null. If so, the client should initialize this data as needed by your game. For example, you might need to initialize the starting positions for players in a strategy game or initialize the first hand for players in a card game.
  2. Let the current player perform their normal turn.
  3. Update the match by calling takeTurn(). In your method call, pass in the following information:
  1. Repeat steps 2-3 until the match is completed, or until the game ends some other way.

Specifying the order of play

The order of play is determined by the design of your game. The turn-based multiplayer API provided by the games services allows your game to flexibly specify the order of play during a match.

When updating the match, your game can assign one of these players to take the next turn:

For example, in a 2-player turn-based match, your game might randomly pick one player to take the first turn, then subsequently switch to the other player for the next turn, and so on.

- + \ No newline at end of file diff --git a/docs/gameservices/user-interface/index.html b/docs/gameservices/user-interface/index.html index f58eb934c78..34c96ea2e16 100644 --- a/docs/gameservices/user-interface/index.html +++ b/docs/gameservices/user-interface/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

UI Elements

There are several user interface elements you can use. Some of these can be accessed from other parts of the API eg:

However there are some general elements that can be accessed here directly. This is broken into two major functionality pieces, a Show UI function that allows you to show fullscreen user interface elements and the Access Point functionality that overlays user interface elements on your application.

Show UI

A generic showUI() function allows you to show certain UI elements directly.

GameServices.service.showUI( state );

The state can be one of the following. Not all states are available on all services, and showUI() may return false in these situations. However we have tried to provide reasonable replacements wherever possible.

The possible states are:

  • dashboard: The default dashboard screen if available (Game Center has a dashboard, whereas Play Games will present a profile icon);
  • achievements: Will launch the achievements UI;
  • leaderboards: Will launch the "all" leaderboards UI (Note: if you want to display a specific leaderboard see the Display Leaderboard UI functionality);
  • profile: Will launch a player profile UI;

Dashboard

Game Center Dashboard

Achievements

Game Center Achievements

Leaderboards

Game Center Leaderboards

Player Profile

Game Center Player Profile

- + \ No newline at end of file diff --git a/docs/googleanalytics/add-the-extension/index.html b/docs/googleanalytics/add-the-extension/index.html index 228b78e484d..e5cce7acce2 100644 --- a/docs/googleanalytics/add-the-extension/index.html +++ b/docs/googleanalytics/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ https://github.com/distriqt/ANE-GooglePlayServices.

Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

Application Descriptor

Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

You update your application descriptor by running:

apm generate app-descriptor src/MyApp-app.xml

Change the path (src/MyApp-app.xml) to point to your application descriptor.

caution

This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

You should backup your application descriptor before running this command to ensure you don't lose any information.

If you need to insert custom data into these sections see the guides for Android and iOS

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

if (GoogleAnalytics.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/googleanalytics/changelog/index.html b/docs/googleanalytics/changelog/index.html index 2f72af13d83..ac67af0918b 100644 --- a/docs/googleanalytics/changelog/index.html +++ b/docs/googleanalytics/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.01.20 [v4.2.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2022.03.08 [v4.1.0]

Android: Update SDK to v18.0.1
Updates for Android 31

2022.02.07 [v4.0.17]

Update docs to use apm
Update air package dependencies
Android 31 updates

2021.10.05 [v4.0.16]

Add air package
Remove ios minimum version flag
Add android x64

2020.09.01 [v4.0.015]

Updated build for compatibility with latest extensions

2020.03.22 [v4.0.008]

Android X migration (resolves #60)

2019.08.16 [v3.0.004]

Android 64bit support (resolves #54)
Updated minimum iOS version to 9.0

2019.02.27 [v2.1.031]

Updated minimum iOS version to 8.0 (resolves #52)
Embedded iOS bitcode

2018.11.27 [v2.0.028]

Updated to Google Play Services v16.0.5

2018.11.14 [v1.9.024]

Removed application keys (#50)

2018.06.01 [v1.9.022]

Android: Updated to Google Play Services v15+

2018.05.25 [v1.9.020]

Added setAnonymizeIp for GDPR requirements (resolves #46)

2017.07.10 [v1.8.009]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.05.20 [v1.8.007]

Corrected install referrer build (#37 #38)

2017.05.17 [v1.8.006]

Added event for install referrer update (#37)

2017.04.05 [v1.8.005]

iOS: Fixed crash with getValue when no value specified (resolves #36)

2017.03.02 [v1.8.003]

iOS: Updated SDK to v3.17
Resolved fatal flag issue for exceptions (resolves #29)
Internal refactoring

2017.03.01 [v1.7.014]

Android Update for Google Play Services v10.2.0

2016.12.29 [v1.7.012]

Updated documentation

2016.12.29 [v1.7.012]

Update to latest SDKs + documentation

2016.08.09 [v1.7.007]

Added ability to clear a value on a tracker (resolves #25)

2016.08.05

Corrected multiple addImpression calls (resolves #24)

2016.07.20

iOS: Corrected issue with providing invalid ecommerce product params

2016.07.13

Added Enhanced Ecommerce: Product Impressions (#17)

2016.07.13

Added Enhanced Ecommerce features (resolves #17)

2016.06.04

Added 'getValue' call to retrieve tracker value (resolves #16)

2016.04.22

iOS: Added AdIdSupport ANE for IDFA support (#6)
iOS: Resolved conflict with other Google libraries

2016.04.22

iOS: Added AdIdSupport ANE for IDFA support (#6)
iOS: Resolved conflict with other Google libraries

2016.03.18

iOS: Fixed issue with additional params (#15)

2016.03.18

iOS: Fix for TimingBuilder crashing (resolves #14)

2016.03.09

Updated test application

2016.03.09

iOS: Resolved invalid bundle structure (resolves #10)

2016.03.02

Added install referrer (resolves #2)
Android: Updated support for crash reporting (resolves #7)

2015.11.26

Fixed issue with custom dimensions on a hit builder (resolves #1)

2015.11.23

Corrected missing classes from default library

2015.11.18

Google Analytics first release version
- + \ No newline at end of file diff --git a/docs/googleanalytics/create-a-tracker/index.html b/docs/googleanalytics/create-a-tracker/index.html index 449d3059609..9474abe5632 100644 --- a/docs/googleanalytics/create-a-tracker/index.html +++ b/docs/googleanalytics/create-a-tracker/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Create a Tracker

Creating and retrieving a Tracker use the same piece of code as shown below:

var tracker:Tracker = GoogleAnalytics.service.getTracker( "YOUR_TRACKING_ID" );

// Set a value that will be sent with every message
tracker.setValue( "&uid", "userIdString" );

You can create many Tracker instances as you require, however you should note that the first Tracker you create will be considered the default tracker and can be retrieved using GoogleAnalytics.service.defaultTracker.

- + \ No newline at end of file diff --git a/docs/googleanalytics/ecommerce/index.html b/docs/googleanalytics/ecommerce/index.html index da6df0746f3..433c889b0b3 100644 --- a/docs/googleanalytics/ecommerce/index.html +++ b/docs/googleanalytics/ecommerce/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Ecommerce

Deprecated

Warning: Ecommerce SDK is deprecated. You still can use this functionality however it is suggested to use Enhanced Ecommerce.

Ecommerce measurement allows you to send in-app purchases and sales to Google Analytics. Ecommerce data in Google Analytics is comprised of transaction and item hits, related by a shared transaction ID.

Transactions have the following fields:

  • Transaction ID (required): A unique ID representing the transaction. This ID should not collide with other transaction IDs.
  • Affiliation (required): An entity with which the transaction should be affiliated (e.g. a particular store)
  • Revenue (required): The total revenue of a transaction, including tax and shipping
  • Tax (required): The total tax for a transaction
  • Shipping (required): The total cost of shipping for a transaction
  • Currency code: The local currency of a transaction. Defaults to the currency of the view (profile) in which the transactions are being viewed

In the following example we send a transaction containing a single item:

var tracker:Tracker = GoogleAnalytics.service.getTracker( "YOUR_TRACKING_ID" );

// Send the overview of the transaction
tracker.send(
new TransactionBuilder()
.setTransactionId(transactionId)
.setAffiliation("internal")
.setRevenue(12.22)
.setTax(0)
.setShipping(0)
.setCurrencyCode("USD")
.build() );

// Send the items in this transaction
tracker.send(
new ItemBuilder()
.setTransactionId(transactionId)
.setName("AwesomeSauce")
.setSku("p_12341234")
.setCategory("sauce")
.setPrice(12.22)
.setQuantity(1)
.setCurrencyCode("USD")
.build() );
- + \ No newline at end of file diff --git a/docs/googleanalytics/enhanced-ecommerce/index.html b/docs/googleanalytics/enhanced-ecommerce/index.html index 402c52d069b..726e75906dd 100644 --- a/docs/googleanalytics/enhanced-ecommerce/index.html +++ b/docs/googleanalytics/enhanced-ecommerce/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Enhanced Ecommerce

Enhanced ecommerce enables the measurement of user interactions with products across the user's shopping experience, which include product impressions, product clicks, viewing product details, adding a product to a shopping cart, initiating the checkout process, transactions, and refunds.

Below we cover the main concepts involved with Enhanced Ecommerce. The API is very similar to the Android Google Analytics API so you should be able to refer to that for any advanced usage.

Measuring Products

The main measure is to record an action, by using the addProduct method with a Product object to add product details, and the setProductAction method with a ProductAction object to specify the action being performed.

In the following example we send a transaction containing a single item. Transaction level details like total revenue, tax, and shipping are provided in the ProductAction object.


var product:Product = new Product()
.setId( "P12345" )
.setName("Android Warhol T-Shirt")
.setCategory("Apparel/T-Shirts")
.setBrand("Google")
.setVariant("black")
.setPrice(29.20)
.setCouponCode("APPARELSALE")
.setQuantity(1);

var action:ProductAction = new ProductAction( ProductAction.ACTION_PURCHASE )
.setTransactionId("T12345")
.setTransactionAffiliation("Google Store - Online")
.setTransactionRevenue(37.39)
.setTransactionTax(2.85)
.setTransactionShipping(5.34)
.setTransactionCouponCode("SUMMER2013");

var builder:ScreenViewBuilder = ScreenViewBuilder(
new ScreenViewBuilder()
.addProduct( product )
.setProductAction( action )
);

var tracker:Tracker = GoogleAnalytics.service.defaultTracker;

tracker.setScreenName( "transaction" );
tracker.send( builder.build() );

Measuring the Checkout Process

To measure each step in a checkout process:

  • Add tracking code to measure each step of the checkout process.
  • If applicable, add tracking code to measure checkout options.
  • Optionally set user-friendly step names for the checkout funnel report by configuring Ecommerce Settings in the admin section of the web interface.

For each step in your checkout process, you’ll need to implement the corresponding tracking code to send data to Google Analytics.


var product:Product = new Product()
.setId( "P12345" )
.setName("Android Warhol T-Shirt")
.setCategory("Apparel/T-Shirts")
.setBrand("Google")
.setVariant("black")
.setPrice(29.20)
.setCouponCode("APPARELSALE")
.setQuantity(1);

var action:ProductAction = new ProductAction( ProductAction.ACTION_CHECKOUT )
.setCheckoutStep(1)
.setCheckoutOptions("Visa");

var builder:ScreenViewBuilder = ScreenViewBuilder(
new ScreenViewBuilder()
.addProduct( product )
.setProductAction( action )
);


var tracker:Tracker = GoogleAnalytics.service.defaultTracker;

tracker.setScreenName( "checkoutStep1" );
tracker.send( builder.build() );

Measuring Promotions

Enhanced ecommerce includes support for measuring impressions and clicks of internal promotions, such as banners displayed to promote a sale.

Internal promotion impressions are generally measured with the initial screen view using the addPromotion method with a Promotion object to specify the details of the promotion. For example:

var promotion:Promotion = new Promotion()
.setId("PROMO_1234")
.setName("Summer Sale")
.setCreative("summer_banner2")
.setPosition("banner_slot1");

var builder:ScreenViewBuilder = ScreenViewBuilder(
new ScreenViewBuilder()
.addPromotion( promotion )
);


var tracker:Tracker = GoogleAnalytics.service.defaultTracker;

tracker.setScreenName( "promotions" );
tracker.send( builder.build() );
- + \ No newline at end of file diff --git a/docs/googleanalytics/index.html b/docs/googleanalytics/index.html index f6651790254..a416d2c7e2c 100644 --- a/docs/googleanalytics/index.html +++ b/docs/googleanalytics/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ allowing you to develop once and deploy everywhere! It comes with detailed AS docs, and a complete example application.

Features

As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

Documentation

The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

Quick Example:

var tracker:Tracker = GoogleAnalytics.service.getTracker( "YOUR_TRACKING_ID" );

tracker.send(
new EventBuilder()
.setCategory( "user" )
.setAction( "signIn" )
.setValue( 123 )
.build() );

More information here:

com.distriqt.GoogleAnalytics

License

You can purchase a license for using this extension:

airnativeextensions.com

distriqt retains all copyright.

- + \ No newline at end of file diff --git a/docs/googleanalytics/install-referrer/index.html b/docs/googleanalytics/install-referrer/index.html index 0c3a862b131..31359b21ea6 100644 --- a/docs/googleanalytics/install-referrer/index.html +++ b/docs/googleanalytics/install-referrer/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ replace air.com.distriqt.test with the package of your application.

adb shell
am broadcast -a com.android.vending.INSTALL_REFERRER -n air.com.distriqt.test/com.distriqt.extension.googleanalytics.InstallReferrerReceiver --es "referrer" "utm_source=test_source\&amp;utm_medium=test_medium\&amp;utm_term=test_term\&amp;utm_content=test_content\&amp;utm_campaign=test_name"

Running this command will broadcast the INSTALL_REFERRER intent which will update the referrer in your application. You can edit the string at the end as you wish to try different referrer strings.

- + \ No newline at end of file diff --git a/docs/googleanalytics/migrating-to-androidx/index.html b/docs/googleanalytics/migrating-to-androidx/index.html index 430399d1c65..2527b674180 100644 --- a/docs/googleanalytics/migrating-to-androidx/index.html +++ b/docs/googleanalytics/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Migrating to AndroidX

Android X

AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

Generally migrating is fairly simple.

Simply use the table below to swap the extensions you currently have in your application.

Android SupportAndroid X
com.distriqt.androidsupport.V4androidx.core
com.distriqt.androidsupport.AppCompatV7androidx.appcompat
com.distriqt.androidsupport.CardViewV7androidx.cardview
com.distriqt.androidsupport.CustomTabsandroidx.browser
com.distriqt.androidsupport.Designcom.google.android.material
com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

- + \ No newline at end of file diff --git a/docs/googleanalytics/notes/index.html b/docs/googleanalytics/notes/index.html index a1927f08f06..c105b5d8ae7 100644 --- a/docs/googleanalytics/notes/index.html +++ b/docs/googleanalytics/notes/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
Skip to main content

Notes

Dashboard

Please note that calls to Google Analytics on mobile is batched and data may take a while to be displayed in the dashboard. So expect delays and do not expect your data to appear instantaneously in the dashboard.

Further Reading

The Google Documentation contains a lot more detail on all the available features:

If there's anything missing, drop an enhancement request in github.

- + \ No newline at end of file diff --git a/docs/googleanalytics/sending-hits-and-events/index.html b/docs/googleanalytics/sending-hits-and-events/index.html index 1fe707aa258..40b0e84d027 100644 --- a/docs/googleanalytics/sending-hits-and-events/index.html +++ b/docs/googleanalytics/sending-hits-and-events/index.html @@ -13,7 +13,7 @@ - + @@ -32,7 +32,7 @@ An event consists of four fields that you can use to describe a user's interaction with your app content, a 'category', an 'action', a 'label' and a numeric 'value'. The 'category' and 'action' are required.

var tracker:Tracker = GoogleAnalytics.service.getTracker( "YOUR_TRACKING_ID" );

tracker.send(
new EventBuilder()
.setCategory( "user" )
.setAction( "signIn" )
.setValue( 123 )
.build() );
- + \ No newline at end of file diff --git a/docs/googleanalytics/tracking-ids/index.html b/docs/googleanalytics/tracking-ids/index.html index 928676f5dbb..1199f6f8e4b 100644 --- a/docs/googleanalytics/tracking-ids/index.html +++ b/docs/googleanalytics/tracking-ids/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Tracking IDs

Now that Google are encouraging mobile to use Firebase the process of creating tracking ids for use only with Google Analytics in mobile applications is slightly confusing.

In order to use this ANE without Firebase follow the instructions below to create your tracking id. Basically you create a "website" tracker and use that id:

  1. Sign in to your Google Analytics account.
  2. Click Admin.
  3. In the PROPERTY column, select Create new property from the dropdown menu.
  4. Select Website.
  5. Provide a Website Name. You may use the name of your app.
  6. Provide a Website URL. You may use your company URL or the URL for your app’s marketing site.
  7. Click Get Tracking ID.
  8. In the VIEW column, select Create new view from the dropdown menu.
  9. Select Mobile app.
  10. Provide a Reporting View Name.
  11. Click Create View.
- + \ No newline at end of file diff --git a/docs/googleidentity/add-the-extension/index.html b/docs/googleidentity/add-the-extension/index.html index ea4a461acc2..04987ca2964 100644 --- a/docs/googleidentity/add-the-extension/index.html +++ b/docs/googleidentity/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ replace the URL_SCHEME and URL_NAME in the additions with the ones you created when setting up your application in the Google developer console.

<InfoAdditions><![CDATA[
<key>UIDeviceFamily</key>
<array>
<string>1</string>
</array>

<key>GIDClientID</key>
<string>IOS_CLIENT_ID</string>

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>URL_SCHEME</string>
</array>
<key>CFBundleURLName</key>
<string>URL_NAME</string>
</dict>
</array>

]]></InfoAdditions>

The IOS_CLIENT_ID should be your iOS OAuth client id, eg XXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com.

The URL_SCHEME should be your reversed ios client id, along the lines of the following: com.googleusercontent.apps.XXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxx

The URL_NAME should be your application identifier, eg: com.distriqt.test

See the example application for our test application implementation.

Optional: Configure backend authentication

If you need to get users' ID tokens for backend authentication, also set the GIDServerClientID key in your app's Info.plist file.

Note: This is the OAuth client ID for your backend project, not the ID for your iOS or macOS app. You need to get an OAuth server client ID and specify it here.

<key>GIDServerClientID</key>
<string>SERVER_CLIENT_ID</string>

Checking for Support

You can use the isSupported flag to determine if this extension is supported on the current platform and device.

This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

Core.init();
if (GoogleIdentity.isSupported)
{
// Functionality here
}
- + \ No newline at end of file diff --git a/docs/googleidentity/android-certificate/index.html b/docs/googleidentity/android-certificate/index.html index c96bdb73328..a3fa0a804bf 100644 --- a/docs/googleidentity/android-certificate/index.html +++ b/docs/googleidentity/android-certificate/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ go into production, so make sure you create a second debugging project.

Using the production certificate for debugging

The best method to debug is to use your production certificate for debugging. Getting this working requires a few configuration tricks.

Flash Builder

Go to 'Properties' for your project

Flash Builder will not save the password for the certificate. So each time you relaunch Flash Builder you will need to reenter the password in the debug settings.

- + \ No newline at end of file diff --git a/docs/googleidentity/authenticate-with-a-backend-server/index.html b/docs/googleidentity/authenticate-with-a-backend-server/index.html index 907b3124f7c..aa3fbbeafe2 100644 --- a/docs/googleidentity/authenticate-with-a-backend-server/index.html +++ b/docs/googleidentity/authenticate-with-a-backend-server/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Authenticate with a backend server

If you use Google Sign-In with an app or site that communicates with a backend server, you might need to identify the currently signed-in user on the server. To do so securely, after a user successfully signs in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity of the ID token and use the user information contained in the token to establish a session or create a new account.

danger

Do not accept plain user IDs, such as those you can get with the GoogleSignInAccount.getId() method, on your backend server. A modified client application can send arbitrary user IDs to your server to impersonate users, so you must instead use verifiable ID tokens to securely get the user IDs of signed-in users on the server side.

Setup

If you plan on identifying your user with your server you will need to request the id token and provide the server client ids when you setup the extension.

The server client ids are created through the Google API Console by creating an OAuth 2.0 web application client ID for your backend server. If you have different servers for iOS and Android applications use the setiOSServerClientID and setAndroidServerClientID otherwise if you just have the one you can use setServerClientID.

var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
.requestEmail()
.requestIdToken()
.setIOSClientID( IOS_CLIENT_ID )
.setiOSServerClientID( IOS_SERVER_CLIENT_ID )
.setAndroidServerClientID( ANDROID_SERVER_CLIENT_ID )
.build();

GoogleIdentity.service.setup( options );

If you didn't configure GoogleIdentityOptionsBuilder with requestIdToken(), your user's id token will return null or an empty string.

Sign In

Follow the normal process to sign in and in your sign in success handler ensure you grab the user and the id token:

function signInHandler( event:GoogleIdentityEvent ):void
{
trace( event.user.userID );
trace( event.user.authentication.idToken );
}

You can then use a normal URLRequest to send this token to your server to identify your user:

var vars:URLVariables = new URLVariables();
vars.idToken = user.authentication.idToken;

var request:URLRequest = new URLRequest( YOUR_SERVER_URL );
request.data = vars;
request.method = URLRequestMethod.POST;

var loader:URLLoader = new URLLoader();
loader.addEventListener( Event.COMPLETE, loaderCompleteHandler );
loader.load( request );

(This is just intended as a quick example and is missing error handling)

Verify

After you receive the ID token by HTTPS POST, you must verify the integrity of the token. To verify that the token is valid, ensure that the following criteria are satisfied:

  • The ID token is properly signed by Google. Use Google's public keys (available in JWK or PEM format) to verify the token's signature. These keys are regularly rotated; examine the Cache-Control header in the response to determine when you should retrieve them again.
  • The value of aud in the ID token is equal to one of your app's client IDs. This check is necessary to prevent ID tokens issued to a malicious app being used to access data about the same user on your app's backend server.
  • The value of iss in the ID token is equal to accounts.google.com or https://accounts.google.com.
  • The expiry time (exp) of the ID token has not passed.
  • If you want to restrict access to only members of your G Suite domain, verify that the ID token has an hd claim that matches your G Suite domain name.

Rather than writing your own code to perform these verification steps, we strongly recommend using a Google API client library for your platform, or calling our tokeninfo validation endpoint.

Further information:

- + \ No newline at end of file diff --git a/docs/googleidentity/changelog/index.html b/docs/googleidentity/changelog/index.html index bf82eb871e5..2bc0ffd2d05 100644 --- a/docs/googleidentity/changelog/index.html +++ b/docs/googleidentity/changelog/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

changelog

2023.07.05 [v5.5.0]

feat(android): update google play services auth version to v20.5.0
feat(ios): update google sign in version to v7.0.0

2023.01.20 [v5.4.0]

feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

2022.11.24 [v5.3.2]

fix(docs,airpackage): correct dependency on kotlin library (resolves #73)

2022.03.29 [v5.3.1]

Correct air package dependencies (resolves #72)

2022.03.08 [v5.3.0]

Updated SDK
- Android v20.1.0

Android 31 documentation updates

2022.02.07 [v5.2.5]

Update docs to use apm

2022.01.19 [v5.2.4]

Update air package parameter descriptions

2021.10.05 [v5.2.3]

Add air package

2021.01.20 [v5.2.002]

Updated SDK
- Android v19.0.0
- iOS v5.0.2

2020.09.01 [v5.1.043]

Updated SDK (now Firebase compatible)
Resolved crash on iOS 12 (resolves #67)

2020.08.14 [v5.0.031]

Updated build and added SWC

2020.05.11 [v5.0.029]

Updated SDK
- Android v18.0.0
- iOS v5.0.2 (resolves #66)

2020.03.22 [v4.0.016]

Android X migration (resolves #65)

2019.11.22 [v3.1.012]

iOS: Resolved duplicate symbols with Firebase performance extension (resolves #64)

2019.08.16 [v3.0.002]

Android 64bit support (resolves #62)
Updated minimum iOS version to 9.0
Added checks for null pointer in edge case (#58)

2019.02.22 [v2.3.092]

Corrected Android requestEmail option (#59)
Updated minimum iOS version to 8.0

2018.11.27 [v2.2.089]

Updated to Google Play Services v16.0.5 
Removed application keys

2018.11.18 [v2.1.087]

Simplified integration with Games Services sign-in

2018.10.18 [v2.1.080]

Update for new square okhttp extension

2018.09.20 [v2.1.079]

Extracted square open source library to resolve conflict

2018.06.01 [v2.1.062]

Android: Updated to Google Play Services v15+

2018.03.15 [v2.0.059]

Corrected Firebase compat ANE build

2018.03.15 [v2.0.057]

Updated to latest SDK
- Android v11.8.0
- iOS v4.1.2
Refactored options and introduced builder utility to clarify config and processes (resolves #45)
Deprecated getToken as against best practices (resolves #40)
Added getUser and isSignedIn functionality

2017.11.18 [v1.8.036]

Updated documentation (#45)

2017.10.20 [v1.8.036]

Resolved conflict with Firebase Auth (resolves #42)

2017.07.10 [v1.7.018]

Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

2017.06.19 [v1.7.013]

Corrected missing getToken function from default lib (#38)

2017.06.07 [v1.7.012]

Android: Updated detection of Google Play Services version on device

2017.03.01 [v1.7.006]

Android Update for Google Play Services v10.2.0

2017.02.07 [v1.7.005]

Updated documentation

2017.02.07 [v1.7.005]

Add additional profile information (resolves #18)

2017.01.30 [v1.6.007]

Updated to Google Play Services v10.0.1

2016.12.29 [v1.6.004]

Updated documentation

2016.12.29 [v1.6.004]

Update to latest SDKs + documentation

2016.11.22 [v1.6.001]

Updated for Firebase compatibility

2016.08.17 [v1.5.002]

iOS: Updated native SDK to v4.0.0 (resolves #8)

2016.08.11 [v1.4.004]

New versioning system
Corrected key check (#5)

2016.07.01

Android: Corrected potential null pointer reference (resolves #4)

2016.06.18

Added serverAuthCode to user object (resolves #3)

2016.06.16

iOS: Removed logging that could cause an issue (#2)

2016.06.10

Added getToken function to retrieve access tokens (#1)

2016.05.27

Updated example app

2016.05.27

Release v1.0
- + \ No newline at end of file diff --git a/docs/googleidentity/disconnect/index.html b/docs/googleidentity/disconnect/index.html index 21f5780cc35..f4c1fc59ab5 100644 --- a/docs/googleidentity/disconnect/index.html +++ b/docs/googleidentity/disconnect/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ your app must provide a way to delete the association between your app and their account. By adding this capability to your app, you can respond to the event and trigger any appropriate logic such as deleting any information you have stored about the user.

GoogleIdentity.service.addEventListener( GoogleIdentityEvent.DISCONNECT, disconnectHandler );

GoogleIdentity.service.disconnect();
private function disconnectHandler( event:GoogleIdentityEvent ):void
{
trace( event.type );
}
- + \ No newline at end of file diff --git a/docs/googleidentity/enabling-server-side-access/index.html b/docs/googleidentity/enabling-server-side-access/index.html index aa5b0c83eb4..45230b702fc 100644 --- a/docs/googleidentity/enabling-server-side-access/index.html +++ b/docs/googleidentity/enabling-server-side-access/index.html @@ -13,13 +13,13 @@ - +
Skip to main content

Enabling Server-Side Access

With the Sign-In procedure, your app authenticates the user on the client side only; in that case, you can access the Google APIs only while the user is actively using your app. If you want your servers to be able to make Google API calls on behalf of users—possibly while they are offline—your server requires an access token.

Setup

If you require server side access then you will need to request the server auth code and provide the server client ids when you setup the extension.

The server client ids are created through the Google API Console by creating an OAuth 2.0 web application client ID for your backend server. If you have different servers for iOS and Android applications use the setiOSServerClientID and setAndroidServerClientID otherwise if you just have the one you can use setServerClientID.

var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
.requestEmail()
.requestIdToken()
.requestServerAuthCode()
.setIOSClientID( IOS_CLIENT_ID )
.setiOSServerClientID( IOS_SERVER_CLIENT_ID )
.setAndroidServerClientID( ANDROID_SERVER_CLIENT_ID )
.build();

GoogleIdentity.service.setup( options );

Ensure you add any additional scopes your backend server requires using the addScope function of the builder.

If you didn't configure GoogleIdentityOptionsBuilder with requestServerAuthCode(), your user's server auth code will return null.

Sign In

Follow the normal process to sign in and in your sign in success handler ensure you grab the user and the server auth code:

function signInHandler( event:GoogleIdentityEvent ):void
{
trace( event.user.userID );
trace( event.user.serverAuthCode );
}

You can then use a normal URLRequest to send this token to your server to identify your user:

var vars:URLVariables = new URLVariables();
vars.serverAuthCode = user.serverAuthCode;

var request:URLRequest = new URLRequest( YOUR_SERVER_URL );
request.data = vars;
request.method = URLRequestMethod.POST;

var loader:URLLoader = new URLLoader();
loader.addEventListener( Event.COMPLETE, loaderCompleteHandler );
loader.load( request );

(This is just intended as a quick example and is missing error handling)

Exchange for Access Token

On your server you'll want to exchange the server auth code for an access token which can then be used to access the Google APIs on behalf of your user.

This process is beyond the scope of this documentation but you'll find information in the Google documentation:

- + \ No newline at end of file diff --git a/docs/googleidentity/google-developers-console-project/index.html b/docs/googleidentity/google-developers-console-project/index.html index 527137500ca..64b8fac62bf 100644 --- a/docs/googleidentity/google-developers-console-project/index.html +++ b/docs/googleidentity/google-developers-console-project/index.html @@ -13,7 +13,7 @@ - + @@ -32,7 +32,7 @@ is related to your AIR application ID but can be very different. We suggest making sure you use a valid Java package name for your AIR application ID.
  • You do not directly need to supply any information from this credential to the ANE. The matching is made completely on the package name and the certificate fingerprint.
    1. Web Application:
      • Create credential / OAuth client ID / Web application
      • Take note of the "Client ID" for the "Web application", you will need this value for your GoogleIdentityOptions

    Firebase

    If you are using Firebase you can update your certifcate signature after setting up your project.

    More information: https://support.google.com/firebase/answer/9137403?hl=en

    More Information

    More information can be found here:

    - + \ No newline at end of file diff --git a/docs/googleidentity/google-identity-options/index.html b/docs/googleidentity/google-identity-options/index.html index 4f25a08273c..5c2848b0eea 100644 --- a/docs/googleidentity/google-identity-options/index.html +++ b/docs/googleidentity/google-identity-options/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Google Identity Options

    This shows you where to gather the information required for the Google Identity options you will use to initialise the extension.

    Client IDs

    You should now go to the Google Developers APIs Console select your project and retrieve the client IDs from the Credentials section.

    Take note of the following identifiers from the OAuth 2.0 client IDs:

    • The Client ID for the iOS client. This is your iOS application clientID
    • The Client ID for the Web client. This is the serverClientID.
      • If you have different servers and hence ids for applications you may have 2 different server client IDs
    note

    YOU DO NOT NEED TO USE THE ANDROID CLIENT. Android applications are identified through their package name and certificate signature so ensure those properties match the configuration of your application in the console.

    Setup Options

    The simplest method to correctly create your options for setup is to use the GoogleIdentityOptionsBuilder. This class contains helper functions to construct the options correctly for the setup of your application. The builder is setup in such a way that you can use a single code base and the builder will determine the correct values to use in the GoogleIdentityOptions instance based on the current platform of the device. This allows you to simplify your code having one code base for both Android and iOS. If you wish more control you can use the direct accessors, setClientID and setServerClientID, which will ignore the current platform.

    As a minimum you will need to set the iOS Client ID:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .requestEmail()
    .setIOSClientID( IOS_CLIENT_ID )
    .build();

    If you plan on identifying your user with your server you will need to request the id token and provide the server client ids:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .requestEmail()
    .requestIdToken()
    .setIOSClientID( IOS_CLIENT_ID )
    .setiOSServerClientID( IOS_SERVER_CLIENT_ID )
    .setAndroidServerClientID( ANDROID_SERVER_CLIENT_ID )
    .build();

    See the section on authenticating with a backend server.

    If you require server side access then you will need to request the server auth code and provide the server client ids:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .requestEmail()
    .requestIdToken()
    .requestServerAuthCode()
    .setIOSClientID( IOS_CLIENT_ID )
    .setiOSServerClientID( IOS_SERVER_CLIENT_ID )
    .setAndroidServerClientID( ANDROID_SERVER_CLIENT_ID )
    .build();

    See the section on enabling server-side access.

    You can add additional scopes using the addScope method. This will add additional access permissions to your users signin process which you may require for your application:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .requestEmail()
    .requestIdToken()
    .requestServerAuthCode()
    .setIOSClientID( IOS_CLIENT_ID )
    .setiOSServerClientID( IOS_SERVER_CLIENT_ID )
    .setAndroidServerClientID( ANDROID_SERVER_CLIENT_ID )
    .addScope( "https://www.googleapis.com/auth/plus.login" )
    .addScope( "https://www.googleapis.com/auth/plus.me" )
    .addScope( "profile" )
    .build();

    Once you have your options instance you pass this to the setup function.

    - + \ No newline at end of file diff --git a/docs/googleidentity/index.html b/docs/googleidentity/index.html index 1ce9658fad6..fdbb41ee2e3 100644 --- a/docs/googleidentity/index.html +++ b/docs/googleidentity/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with asset selection quickly and easily.

    YOUTUBE

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    Latest documentation can be found in the documentation site

    More information here:

    com.distriqt.GoogleIdentity

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/googleidentity/migrating-from-version-1/index.html b/docs/googleidentity/migrating-from-version-1/index.html index a9bec1bba1a..abb97f59e87 100644 --- a/docs/googleidentity/migrating-from-version-1/index.html +++ b/docs/googleidentity/migrating-from-version-1/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating from version 1

    Version 2 brings the latest Google Identity Sign In SDK and with it some changes to the API.

    These changes are mainly around the options passed to setup and getToken functionality.

    Google Identity Options

    The options you supply to the setup function (GoogleIdentityOptions) have been simplified and updated to better reflect the functionality available.

    Firstly we have removed the "secret" references as these were misleading and we want to discourage their usage.

    Additionally we have changed the references to Android and iOS so the GoogleIdentityOptions class more simply states the functionality currently in use.

    To help with setup we have introduced the GoogleIdentityOptionsBuilder. This class will help you construct the correct options instance irrespective of platform.

    To migrate, the following:

    var options:GoogleIdentityOptions = new GoogleIdentityOptions();
    options.clientID_iOS = CLIENTID_IOS;
    options.clientID_Android = CLIENTID_ANDROID;
    options.requestIdToken = true;
    options.requestServerAuthCode = true;
    options.scopes.push( "profile" );

    becomes:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .requestServerAuthCode()
    .requestIdToken()
    .setIOSClientID( CLIENTID_IOS )
    .setiOSServerClientID( SERVER_CLIENTID_IOS )
    .setAndroidServerClientID( SERVER_CLIENTID_ANDROID )
    .addScope( "profile" )
    .build();

    The ability to set the server client id has been added to specify it's difference from the application client ids. The SERVER_CLIENTID_ANDROID is the equivalent of the CLIENTID_ANDROID used in the past, we have just clarified it's naming, to not confuse it with the Android client id in the console.

    getToken

    The getToken functionality has been deprecated.

    You should instead migrate to using the Server Auth Code and exchanging that code for your users' access token on your server to enable Server-Side Access .

    - + \ No newline at end of file diff --git a/docs/googleidentity/migrating-to-androidx/index.html b/docs/googleidentity/migrating-to-androidx/index.html index 77a16fa6690..a45caff82b6 100644 --- a/docs/googleidentity/migrating-to-androidx/index.html +++ b/docs/googleidentity/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/googleidentity/setup/index.html b/docs/googleidentity/setup/index.html index 3498751fa57..67fba5f01fe 100644 --- a/docs/googleidentity/setup/index.html +++ b/docs/googleidentity/setup/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Setup

    Setup the extension

    Next you need to setup the platform using your Google API client ID and specify any additional options such as scopes you require:

    At a minimum you will need to specify the iOS client ID:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .requestEmail()
    .setIOSClientID( IOS_CLIENT_ID )
    .build();

    GoogleIdentity.service.setup( options );

    The options here specify the permissions and scopes that you require from your users. This information will get displayed as part of the sign in process.

    For more information on these options see the Google Identity Options section.

    After setup you may wish to attempt to sign in silently.

    Games Signin

    If you are planning to use Google Play Games on Android in your application then you can use this ANE to handle the signin process for games rather than handling two authentication processes. Additionally this ANE gives you more control over the sign in options and adding extra scopes that you don't get with the Game Services ANE.

    To do this we have added some default functionality to make the setup process simpler. Simply pass the GoogleIdentityOptions.DEFAULT_GAMES_SIGN_IN to the builder constructor and then set any additional options as required.

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder( GoogleIdentityOptions.DEFAULT_GAMES_SIGN_IN )
    .requestProfile()
    .setIOSClientID( IOS_CLIENT_ID )
    .build();
    note

    You will most likely want to request the profile so you can retrieve the player information so make sure you add the requestProfile() call to the builder (as above).

    Utilising this method automatically adds the required scopes and permissions for games sign in along with any other options you add to the builder.

    iOS

    As Play Games is no longer supported on iOS this addition does nothing on iOS and you will simply get the normal Google signin on iOS.

    - + \ No newline at end of file diff --git a/docs/googleidentity/signing-in/index.html b/docs/googleidentity/signing-in/index.html index 9ef10f0a443..01ec74b686b 100644 --- a/docs/googleidentity/signing-in/index.html +++ b/docs/googleidentity/signing-in/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ signIn method. You will then receive either a GoogleIdentityEvent.SIGN_IN or a GoogleIdentityEvent.ERROR depending on the success of the sign in operation.

    GoogleIdentity.service.addEventListener( GoogleIdentityEvent.SIGN_IN, signInHandler );
    GoogleIdentity.service.addEventListener( GoogleIdentityEvent.ERROR, errorHandler );

    GoogleIdentity.service.signIn();

    On successful sign in the event.user property will contain user information:

    function signInHandler( event:GoogleIdentityEvent ):void
    {
    trace( event.user.userID );
    }

    function errorHandler( event:GoogleIdentityEvent ):void
    {
    trace( event.errorCode + "::" + event.error );
    }

    Sign In Silently

    When your application starts up it can be good practice to attempt to sign in your user automatically if they have previously signed in. A silent sign in allows you to achieve this by attempt to access stored credentials and signing in the user again, without any user interface being presented.

    Signing in silently is exactly the same as the normal sign in process above, except you'll call signInSilently instead and the sign in will fail if the user hasn't recently signed in using the UI.

    GoogleIdentity.service.addEventListener( GoogleIdentityEvent.SIGN_IN, signInHandler );
    GoogleIdentity.service.addEventListener( GoogleIdentityEvent.ERROR, errorHandler );

    GoogleIdentity.service.signInSilently();

    function signInHandler( event:GoogleIdentityEvent ):void
    {
    trace( event.user.userID );
    }

    function errorHandler( event:GoogleIdentityEvent ):void
    {
    trace( event.errorCode + "::" + event.error );
    }

    Sign out

    Signing out is a call to the signOut function and the appropriate event listener.

    GoogleIdentity.service.addEventListener( GoogleIdentityEvent.SIGN_OUT, signOutHandler );

    GoogleIdentity.service.signOut();
    function signOutHandler( event:GoogleIdentityEvent ):void
    {
    trace( event.type );
    }
    - + \ No newline at end of file diff --git a/docs/googleidentity/troubleshooting/index.html b/docs/googleidentity/troubleshooting/index.html index 624fd5ddd60..23c05627ce9 100644 --- a/docs/googleidentity/troubleshooting/index.html +++ b/docs/googleidentity/troubleshooting/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Troubleshooting

    Common Issues

    Android Sign In Error

    If you are getting an error returned when attempting to sign in users on Android, in particular an error code 8 (INTERNAL_ERROR) please double check your applications credentials in the Google API console are correct.

    The most common cause for this issue is that the certificate and package name of the application doesn't match an entry in your api console project.

    Every Android application is uniquely identified by the signature of the certificate (your p12 file) and the package name (AIR application id perfixed by air.).

    To verify:

    1. Open the credentials page in your console project;

    2. Make sure your certificate / package name has an Android typed OAuth 2.0 client ID. To create a new ID follow the instructions in setup

    - + \ No newline at end of file diff --git a/docs/googleidentity/user-information/index.html b/docs/googleidentity/user-information/index.html index fa29ba293fa..416eea356ef 100644 --- a/docs/googleidentity/user-information/index.html +++ b/docs/googleidentity/user-information/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ and profile information:

    Profile Data

    The GoogleProfileData object contains personal details about the user that you can use to customise their experience in your application.

    This includes:

    Authentication Information

    The GoogleAuthentication object contains tokens required to access other services acting on behalf of the user.

    This includes:

    Each of these tokens has their different uses, which the services you are using will explain.

    - + \ No newline at end of file diff --git a/docs/googletagmanager/add-the-extension/index.html b/docs/googletagmanager/add-the-extension/index.html index d92df6b25c0..3cf2a7e1c11 100644 --- a/docs/googletagmanager/add-the-extension/index.html +++ b/docs/googletagmanager/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ and you need to ensure they are packaged with your application.

    You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (GoogleTagManager.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/googletagmanager/changelog/index.html b/docs/googletagmanager/changelog/index.html index 5deb59e0caa..87947a8c914 100644 --- a/docs/googletagmanager/changelog/index.html +++ b/docs/googletagmanager/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.09.08 [v5.0.2]

    Breaking changes: containers and data layers are now deprecated, you should use Firebase to log events

    feat(ios): update ios sdk v7.4.0
    feat(android): update android sdk v18.0.3

    2023.01.20 [v2.3.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.03.08 [v2.2.0]

    Update SDK:
    - Android v18.0.1

    Update docs for Android 31 and to use apm

    2021.10.05 [v2.1.0]

    Add air package
    Remove ios minimum version flag

    2020.03.21 [v2.0.019]

    Android X migration (resolves #4)

    2018.11.27 [v1.2.015]

    Updated to Google Play Services v16.0.5
    Removed application keys

    2018.06.01 [v1.1.012]

    Android: Updated to Google Play Services v15+

    2017.07.10 [v1.1.009]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.07.06 [v1.1.008]

    Added checks for issues with loading container (#1)

    2017.03.01 [v1.1.005]

    Android Update for Google Play Services v10.2.0

    2016.12.29 [v1.1.004]

    Updated to latest SDKs + documentation

    2016.05.03

    Release v1.0

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support
    - + \ No newline at end of file diff --git a/docs/googletagmanager/google-tag-manager-setup/index.html b/docs/googletagmanager/google-tag-manager-setup/index.html index 4a9682fdaf2..0c3b21e8f2a 100644 --- a/docs/googletagmanager/google-tag-manager-setup/index.html +++ b/docs/googletagmanager/google-tag-manager-setup/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Google Tag Manager Setup

    Prerequisites

    Before attempting to use this extension make sure you have correctly setup Google Tag Manager and prerequisites your application:

    Download your container

    • Sign in to your Tag Manager account
    • Select your container
    • Click Versions in the top navigation bar
    • Click Actions > Export on the selected container version
    note

    The name of the downloaded file is the container ID with a .json extension.

    Next, add the downloaded container file to your project:

    • Create a folder called container for iOS and containers for Android
    • Copy the downloaded json file into the correct folder for your platform
    • Add this directory to your application package at the root level
    note

    Android and iOS directory names are slightly different

    - + \ No newline at end of file diff --git a/docs/googletagmanager/index.html b/docs/googletagmanager/index.html index 6807fda06af..c617f9d584b 100644 --- a/docs/googletagmanager/index.html +++ b/docs/googletagmanager/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ Identical code base can be used across all platforms without any platfrom specific code, allowing you to develop once and deploy everywhere! It comes with detailed AS docs, and a complete example application.

    YOUTUBE

    Please note this extension requires Firebase.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Simple example of pushing to the data layer:

    Firebase.service.analytics.logEvent(
    new EventObject()
    .setName( "share_image" )
    .setParams( {
    "image_name": "test.png",
    "full_text" : "test image share"
    } )
    );

    More information here:

    com.distriqt.GoogleTagManager

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/googletagmanager/legacy/containers/index.html b/docs/googletagmanager/legacy/containers/index.html index e75f0a18022..cf47a793ae7 100644 --- a/docs/googletagmanager/legacy/containers/index.html +++ b/docs/googletagmanager/legacy/containers/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ You should listen for the ContainerEvent.REFRESH events from a container (as shown above) and then call the refresh function.

    The following code continues on from the previous snippets, you must first have opened and stored your container.

    container.addEventListener( ContainerEvent.REFRESH,        container_refreshHandler );
    container.addEventListener( ContainerEvent.REFRESH_BEGIN, container_refreshBeginHandler );
    container.addEventListener( ContainerEvent.REFRESH_FAILED, container_refreshFailedHandler );

    container.refresh();
    private function container_refreshHandler( event:ContainerEvent ):void
    {
    trace( "Container refreshed" );
    }

    private function container_refreshBeginHandler( event:ContainerEvent ):void
    {
    trace( "Container refresh begin..." );
    }

    private function container_refreshFailedHandler( event:ContainerEvent ):void
    {
    trace( "Container refresh FAILED" );
    }
    - + \ No newline at end of file diff --git a/docs/googletagmanager/legacy/datalayer/index.html b/docs/googletagmanager/legacy/datalayer/index.html index 86b52829335..4323c228b5d 100644 --- a/docs/googletagmanager/legacy/datalayer/index.html +++ b/docs/googletagmanager/legacy/datalayer/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ interface. This gives you the flexibility to modify that tag, or add additional tags that respond to screen events, without updating your application code.

    The data object should be a series of key/value pairs and will be interpretted as String values.

    The following example demonstrates pushing an app view event onto the data layer:

    var data:Object = {
    event: "openScreen",
    screenName: "Home Screen"
    };

    GoogleTagManager.service.dataLayer.push( data );
    - + \ No newline at end of file diff --git a/docs/googletagmanager/log-events/index.html b/docs/googletagmanager/log-events/index.html index 59d24c89ab6..c6415ee4bb1 100644 --- a/docs/googletagmanager/log-events/index.html +++ b/docs/googletagmanager/log-events/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Log events and variables

    Tag Manager uses events, parameters, and user properties logged by the Google Analytics for Firebase SDK to trigger and build tags you've configured in Google Tag Manager.

    Read the Firebase developer documentation for instructions on how to log events and set user properties.

    Configure variables in Tag Manager

    To capture the value of event parameters and user properties for use in Google Tag Manager, you can configure variables in the Tag Manager interface.

    For example, you could log the following custom event in your app:

    Firebase.service.analytics.logEvent(
    new EventObject()
    .setName( "share_image" )
    .setParams( {
    "image_name": "test.png",
    "full_text" : "test image share"
    } )
    );

    Then, you could configure new Event Parameter variables in Tag Manager as follows to capture the image_name and full_text parameter values:

    • Variable Name: Image Name
    • Variable Type: Event Parameter
    • Event Parameter Key Name: image_name

    and:

    • Variable Name: Full Text
    • Variable Type: Event Parameter
    • Event Parameter Key Name: full_text

    Similarly, you could set the following user property in your app:

    Firebase.service.analytics.setUserProperty(
    "favourite_food",
    "carrot"
    );

    Then, you could configure a new Firebase User Property variable in Google Tag Manager to capture the favourite_food value:

    • Variable Name: Favourite Food
    • Variable Type: Firebase User Property
    • Event Parameter Key Name: favourite_food

    For more information refer to the Google Tag Manager documentation.

    - + \ No newline at end of file diff --git a/docs/gyroscope/add-the-extension/index.html b/docs/gyroscope/add-the-extension/index.html index e7ea3c42fe7..c665cf9b9dc 100644 --- a/docs/gyroscope/add-the-extension/index.html +++ b/docs/gyroscope/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Gyroscope

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Gyroscope.ane # Gyroscope extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Gyroscope.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/gyroscope/changelog/index.html b/docs/gyroscope/changelog/index.html index ab44c80b4a8..77f341466de 100644 --- a/docs/gyroscope/changelog/index.html +++ b/docs/gyroscope/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.20 [v3.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.02.07 [v3.1.1]

    Update docs to use apm

    2021.10.05 [v3.1.0]

    Add air package
    Remove ios minimum version flag
    Add android x64

    2020.03.21 [v3.0.006]

    Android X migration (resolves #10)

    2019.08.16 [v2.0.002]

    Android 64bit support (resolves #9)
    Updated minimum iOS version to 9.0

    2019.06.06 [v1.12.010]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode
    Removed application keys

    2017.07.10 [v1.12.007]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.29 [v1.12.006]

    Updated documentation

    2016.12.29 [v1.12.006]

    Updated documentation

    2016.12.29 [v1.12.006]

    Updated documentation

    2016.12.29 [v1.12.006]

    Updated to latest SDKs + documentation

    2016.10.26 [v1.11.004]

    Updated build to latest (#6)

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.02.02

    Added check for .debug suffix in application id

    2014.12.20

    iOS: Included arm64 support (resolves #1) 
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.05

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    New application based key check, removing server checks
    - + \ No newline at end of file diff --git a/docs/gyroscope/index.html b/docs/gyroscope/index.html index b87df3e6173..02b258689d1 100644 --- a/docs/gyroscope/index.html +++ b/docs/gyroscope/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ Identical code base can be used across all platforms without any platfrom specific code, allowing you to develop once and deploy everywhere!

    It comes with detailed AS docs, and a complete example application.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    Latest documentation can be found in the documentation site

    More information here:

    com.distriqt.Gyroscope

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/gyroscope/sensor-updates/index.html b/docs/gyroscope/sensor-updates/index.html index 204d4dede78..ea18a845fc8 100644 --- a/docs/gyroscope/sensor-updates/index.html +++ b/docs/gyroscope/sensor-updates/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ rate.

    Gyroscope.service.addEventListener( GyroscopeEvent.UPDATE, gyro_updateHandler );

    Gyroscope.service.register( Gyroscope.SENSOR_DELAY_GAME );

    The extension will now dispatch events at the specified rate giving you access to the angular speeds:

    private function gyro_updateHandler(event:GyroscopeEvent):void
    {
    trace( "Angular Speeds: " + event.x +", "+ event.y +", "+ event.z );
    }

    Stopping Sensor Updates

    Whenever you are done listening for sensor events you should inform the extension to stop monitoring the sensor and hence conserve battery life.

    This is done by a simple call to unregister:

    Gyroscope.service.unregister();

    After calling this you will no longer receive GyroscopeEvent.UPDATE events.

    - + \ No newline at end of file diff --git a/docs/health/add-the-extension/index.html b/docs/health/add-the-extension/index.html index d49ccdc79cc..02581fed602 100644 --- a/docs/health/add-the-extension/index.html +++ b/docs/health/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Health

    If you are looking to use Google Fitness use the com.distriqt.Health-Fitness variant to ensure the dependencies for Google Fitness are installed.

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Health.ane # Health extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    • You will need to set the configuration values for usage in the extension. Call the following to step through the configuration values for this extension:
    apm project config set com.distriqt.Health

    Application Descriptor

    Add Android Permissions

    You will need to add the Android permissions to your android manifest for the health data you require access to.

    Firstly, generate an apm config for android:

    apm generate config android

    Then edit the file created at config/android/AndroidManifest.xml and add in the required permissions, for example, to read and write the step data you need the following permissions:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <uses-sdk android:minSdkVersion="26" android:targetSdkVersion="33" />

    <!-- Health Connect Permissions -->
    <uses-permission android:name="android.permission.health.READ_STEPS"/>
    <uses-permission android:name="android.permission.health.WRITE_STEPS"/>


    <!-- Google Fitness Permissions -->
    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>


    </manifest>

    Create Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Health.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/health/add-the-plugin/index.html b/docs/health/add-the-plugin/index.html index 328c679b4a0..baf6b5e6ce7 100644 --- a/docs/health/add-the-plugin/index.html +++ b/docs/health/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Plugin

    First step is always to add the plugin to your development environment.

    Asset Store

    Open the Asset Store in your browser and add the plugin to your assets.

    Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

    Manual Installation

    In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.Health.unitypackage.

    You can manually download the extension from our repository:

    Import the Plugin

    This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

    The plugin will be added to your project and you can now use the plugins functionality in your application.

    Resolve Android Dependencies

    This plugin depends on some common Android libraries, particularly the Google Play Core Library, which enables in-app reviews.

    You can get these dependencies using one of the following methods.

    Unity Jar Resolver

    This is the suggested method.

    Use the Unity Jar Resolver plugin to download and manage the Android dependencies.

    Importing

    If you already use the Unity Jar Resolver in your project you can skip this step.

    • Download the latest version of the Unity Jar Resolver
    • Import the plugin by selecting Assets / Import Package / Custom Package ... and locate the plugin you downloaded. The plugin will be in the zip named: external-dependency-manager-latest.unitypackage
    • In the Import Unity Package window, click Import

    Resolving

    By default, the resolver should run automatically and will add the dependencies required by this plugin.

    If you have need to resolve the dependencies manually then you will need to:

    • Open the menu under: Assets / External Dependency Manager / Android Resolver
    • Select Resolve or Force Resolve

    More information on the Unity Jar Resolver can be found here

    Custom Gradle Health

    Unity's in-built gradle build support and exporting to android studio does not support per plugin gradle script. Therefore, this plugin cannot add the dependencies by itself.

    The mainHealth.gradle is generated when you enable the Custom Gradle Health property on the Player window.

    The build.gradle exists in generated Gradle project when you enable the Export Project property on the Player window and Build the project.

    Update the dependencies section in your mainHealth.gradle or build.gradle as below:

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.google.android.play:core:1.9.1'
    }

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Health.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/health/authorisation/index.html b/docs/health/authorisation/index.html index d1e66123980..6c0f5a5d256 100644 --- a/docs/health/authorisation/index.html +++ b/docs/health/authorisation/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Authorisation

    Request Authorisation

    In order to access the user's health data you must first request authorisation.

    To request access call the requestAuthorisation() method:

    Health.instance.requestAuthorisation(
    new <HealthType> [],
    new <HealthType> [ HealthType.STEP_COUNT ],
    function ( success:Boolean, error:Error ):void
    {
    trace( "requestAuthorisation:complete( " + success + " )" );
    }
    );

    The first parameter is a Vector.<HealthType> reqpresenting the write / share types you require access to and the second is similarly for the read types.

    The third parameter is a callback function that will be called once the authorisation process is complete. It must be of the form function( success:Boolean, error:Error ):void.

    Authorisation Status

    You can check the authorisation status by calling the authorisationStatus() method.

    Health.instance.authorisationStatus(
    HealthType.STEP_COUNT,
    function( status:String ):void
    {
    trace( "authorisationStatus: " + status );
    }
    );

    The first parameter is the HealthType you wish to query and the second is a callback function that will be called once the authorisation status has been determined (if possible). This function takes one parameter being the status string as defined in the AuthorisationStatus class.

    note

    On iOS there are certain limitations around the data this will return. Particularly Apple has decided not to return the read status for health data. Instead they suggest you request access whenever you require it and only attempt a read after you have successfully completed that process.

    Users

    If you are using the Google Fitness API you will need to authenticate your user using their Google account. This will give you access to the fit api and their data.

    Follow the Google Identity extension integration guide, you will just need to ensure that you add the Fitness API scope to your sign-in options:

    var options:GoogleIdentityOptions = new GoogleIdentityOptionsBuilder()
    .addScope( "https://www.googleapis.com/auth/fitness.activity.read" )
    .build();

    GoogleIdentity.service.setup( options );

    More information on the scopes is available here.

    note

    This is only required to access the Google Fitness API and isn't required for the other services

    If your user isn't signed in, all queries will fail.

    - + \ No newline at end of file diff --git a/docs/health/changelog/index.html b/docs/health/changelog/index.html index 51df68aef9a..bcda27a9467 100644 --- a/docs/health/changelog/index.html +++ b/docs/health/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.13 [v1.5.0]

    feat: add ability to retrieve manual step entries only

    2023.09.28 [v1.4.0]

    feat: add interval to specify statistic bucket size
    feat: add filtering of user manual entries

    2023.07.13 [v1.2.0]

    feat(android,fitness): add the legacy google fitness api for android

    2023.06.09 [v1.0.4]

    initial release

    2023.06.09 [v1.0.3]

    initial release
    - + \ No newline at end of file diff --git a/docs/health/check-for-updates/index.html b/docs/health/check-for-updates/index.html index 2ea031d7d6b..3e265edb40c 100644 --- a/docs/health/check-for-updates/index.html +++ b/docs/health/check-for-updates/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Availablility & Updates

    iOS

    This is required on Android Health Connect but can be skipped if you are developing for iOS only.

    On Android you will need to ensure the Health Connect application is installed and available for the user.

    You can do this by checking the isUpdateRequired() function:

    var updateRequired:Boolean = Health.instance.isUpdateRequired();

    If this returns true then you must redirect the user to update (or install) the health connect functionality on their device.

    You can do this by calling update()

    Health.instance.update();

    This will redirect the user to the appropriate location in the store or settings to install or update the health connect functionality.

    note

    You must do this before any other functionality in the extension will operate correctly.

    - + \ No newline at end of file diff --git a/docs/health/index.html b/docs/health/index.html index 4230a5f82e0..c265f38c835 100644 --- a/docs/health/index.html +++ b/docs/health/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Health

    The Health extension gives you access to the user's health data on a device, such as steps taken.

    Features:

    • HealthKit data access on iOS
    • HealthConnect data access on Android
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    AIR
    var now:Date = new Date();
    var startDate:Date = new Date( 2023, 0, 1 );

    var stepQuery:StatisticsQuery = new StatisticsQuery( HealthType.STEP_COUNT )
    .withStartDate( startDate )
    .withEndDate( now );

    Health.instance.execute(
    stepQuery,
    function ( result:HealthQueryResult, error:Error ):void
    {
    if (error != null)
    {
    trace( "ERROR: " + error.message );
    return;
    }
    // result will contain query data
    for each (var stat:Statistic in result.statistics)
    {
    trace( stat.startDate.toString() + "::" + stat.sum );
    }
    }
    );

    More information here:

    com.distriqt.Health

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/health/queries/index.html b/docs/health/queries/index.html index 47251e7588c..e104fe0596f 100644 --- a/docs/health/queries/index.html +++ b/docs/health/queries/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Querying Data

    To query data you will create a StatisticsQuery and then pass it to the execute() method. This will query the data specified and when complete call a callback function with the result.

    var query:StatisticQuery = ...;

    Health.instance.execute( query, callback );

    The callback function should be of the form:

    function( result:HealthQueryResult, error:Error ):void
    {
    // Process query result
    }

    The HealthQueryResult contains the result of the query including an array of Statistic objects in the result.statistics parameter. If an error occurred then the error parameter will be non-null and contain the details of the error.

    For example:

    var now:Date = new Date();
    var startDate:Date = new Date( 2023, 0, 1 );

    var stepQuery:StatisticsQuery = new StatisticsQuery( HealthType.STEP_COUNT )
    .withStartDate( startDate )
    .withEndDate( now );

    Health.instance.execute(
    stepQuery,
    function ( result:HealthQueryResult, error:Error ):void
    {
    if (error != null)
    {
    trace( "ERROR: " + error.message );
    return;
    }
    // result will contain query data
    for each (var stat:Statistic in result.statistics)
    {
    trace( stat.startDate.toString() + "::" + stat.sum );
    }
    }
    );

    Aggregating results

    You can get the results aggregated into time intervals by calling the withInterval() method on the StatisticsQuery.

    For example to group the results into daily totals:

    var stepQuery:StatisticsQuery = new StatisticsQuery( HealthType.STEP_COUNT )
    .withStartDate( startDate )
    .withEndDate( now )
    .withInterval( 1, TimeUnit.DAYS );

    This can be useful when you are displaying results in a particular format to a user.

    The withInterval() method takes 2 parameters, the first being a duration and the second is a unit from the predefined values in the TimeUnit class.

    This allows you to create various intervals:

    • daily results: withInterval( 1, TimeUnit.DAYS )
    • 6 hour buckets: withInterval( 6, TimeUnit.HOURS )
    • 30 minute buckets: withInterval( 30, TimeUnit.MINUTES )

    Manual User Entries

    Filtering out entries that have been manually entered by the user can be helpful in certain situations. To do this, call the filterManualDataEntries() method on the StatisticsQuery.

    For example:

    var stepQuery:StatisticsQuery = new StatisticsQuery( HealthType.STEP_COUNT )
    .withStartDate( startDate )
    .withEndDate( now )
    .filterManualDataEntries();

    Conversely, you can request only manual data entries by using manualDataEntriesOnly():

    var stepQuery:StatisticsQuery = new StatisticsQuery( HealthType.STEP_COUNT )
    .withStartDate( startDate )
    .withEndDate( now )
    .manualDataEntriesOnly();
    caution

    Filtering data entries will override aggregation requests on Android, resulting in a query that returns individual samples. Apple's HealthKit seems to have no issues with this.

    Fit

    With the Google FIT API service the data records are queried within the time frame and then any with a data source set to user_input are removed. This was impossible when aggregated as the sources were combined together.

    HealthConnect

    Currently Health Connect seems to be inconsistent with filtering results. Similar to Google Fit the samples must be queried without aggregation to get access to the data origins, however the fields don't seem to be correctly set by certain applications so the results may be inconsistent.

    - + \ No newline at end of file diff --git a/docs/health/setup/index.html b/docs/health/setup/index.html index d87d4d2a042..15ccbc6170c 100644 --- a/docs/health/setup/index.html +++ b/docs/health/setup/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Setup

    Initialise

    In order to use the rest of this extensions functionality you must first initialise the extension, specifying the service type you wish to use in your application.

    This allows us to provide the same API to various different services.

    To specify the service type, construct a HealthService instance and pass it to the initialise() method, eg to use the HealthService.HEALTH_CONNECT service:

    Health.instance.initialise(
    new HealthService()
    .setServiceType( HealthService.HEALTH_CONNECT )
    );

    You can check whether a service is supported via the isServiceSupported() method:

    if (Health.instance.isServiceSupported( HealthService.HEALTH_CONNECT ))
    {
    // Health Connect is supported
    }

    You can just use the default service by calling initialise() with no parameters:

    // Initialise the default service
    Health.instance.initialise();

    On iOS this will use HealthKit, and on Android this will use Health Connect.

    Services include:

    • HealthService.APPLE: Apple's HealthKit;
    • HealthService.HEALTH_CONNECT: Android Health Connect;
    • HealthService.FIT: Google Fitness API;

    Android Health Connect

    There is no setup required outside your application to use Health Connect.

    Google Fitness API

    Follow Google's Guide to create an OAuth client ID for your application and add the Fitness API to your Google app console project.

    note

    You may need to submit your application for verification from Google

    You will need to setup and sign-in your users using the Google Identity extension.

    Apple HealthKit

    Enable HealthKit

    Before you can use HealthKit, you must enable the HealthKit capabilities for your app.

    Open your developer console and enable HealthKit for your application identifier:

    • Open the Developer Console
    • Locate your application and click on it to edit;
    • Under Capabilities, locate HealthKit and enable it:

    • Click Save;

    You will now need to regenerate your provisioning profiles and download them again:

    • Navigate to Profiles
    • Locate and Edit your profile;
    • Click Save;
    • Click Download to download the updated profile;
    - + \ No newline at end of file diff --git a/docs/idfa/add-the-extension/index.html b/docs/idfa/add-the-extension/index.html index 43ef8002461..a349e5051b8 100644 --- a/docs/idfa/add-the-extension/index.html +++ b/docs/idfa/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ https://github.com/distriqt/ANE-GooglePlayServices.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (IDFA.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/idfa/changelog/index.html b/docs/idfa/changelog/index.html index e17461fea02..e2aaa271551 100644 --- a/docs/idfa/changelog/index.html +++ b/docs/idfa/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.18 [v5.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #12)

    2022.03.08 [v5.1.0]

    Android update for API 31
    Update SDK
    - Android v18.0.1

    2022.02.07 [v5.0.33]

    Update installation docs
    Update air package dependencies

    2022.01.20 [v5.0.32]

    Update documentation to use apm
    Add descriptions for air package parameters

    2021.09.10 [v5.0.31]

    Added airpackage
    Added AdvertisingIdInfo to bring inline with Adverts API deprecation

    2021.05.17 [v5.0.029]

    Corrected documentation

    2021.05.17 [v5.0.029]

    Corrected documentation

    2021.05.17 [v5.0.029]

    Corrected documentation

    2021.02.12 [v5.0.028]

    Updated docs

    2020.10.16 [v5.0.028]

    Corrected docs

    2020.10.16 [v5.0.028]

    Removed hard dependency on iOS 14 AppTrackingTransparency framework

    2020.09.18 [v5.0.027]

    Authorisation request using App Tracking Transparency in iOS 14

    2020.03.21 [v3.0.007]

    Android X migration (resolves #4)

    2019.08.16 [v2.0.003]

    Android 64bit support (resolves #3)
    Updated minimum iOS version to 9.0

    2019.02.26 [v1.1.025]

    Updated minimum iOS version to 8.0 (resolves #2)

    2018.10.31 [v1.0.024]

    Added isLimitAdTrackingEnabled for Android and iOS (resolves #1)

    2017.12.01 [v1.0.021]

    Updated documentation

    2017.12.01 [v1.0.021]

    Initial release
    - + \ No newline at end of file diff --git a/docs/idfa/get-advertising-identifier/index.html b/docs/idfa/get-advertising-identifier/index.html index 0adcfe0d1e9..4a64c2816c8 100644 --- a/docs/idfa/get-advertising-identifier/index.html +++ b/docs/idfa/get-advertising-identifier/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Get Advertising Identifier

    Authorisation

    iOS 14 introduced the App Tracking Transparency authorisation which requires applications to request permission to track a user.

    You must have authorisation otherwise the IDFA will be invalid.

    You can check what the current granted authorisation status is by calling the authorisationStatus() function. This will return one of the values defined in the TrackingAuthorisationStatus class:

    var authorisationStatus:String = IDFA.service.authorisationStatus();

    For example:

    switch (IDFA.service.authorisationStatus())
    {
    case TrackingAuthorisationStatus.NOT_DETERMINED:
    // Authorisation not yet requested
    break;

    case TrackingAuthorisationStatus.AUTHORISED:
    // Authorised to retrieve IDFA
    break;

    case TrackingAuthorisationStatus.DENIED:
    // User has denied access
    break;

    case TrackingAuthorisationStatus.RESTRICTED:
    // Restricted usage
    break
    }

    Note: On platforms that do not require user authorisation this will always return AUTHORISED

    Requesting Authorisation

    You can request user authorisation by calling the requestAuthorisation() function. If possible, this will present a dialog to request permission from the user. The text in this dialog can be customised through the "usage description" text in your info additions. (See Add the Extension for details on setting this value).

    IDFA.service.requestAuthorisation();

    This function will return true if the dialog will be presented and false in all other situations (eg the dialog has already been displayed or the platform does not require user authorisation).

    You handle feedback from this dialog either by listening for the IDFAAuthorisationEvent.CHANGED event or passing a callback function to the requestAuthorisation() function. The callback will always be called even if the dialog isn't presented whereas the event will only be dispatched if the dialog is presented (i.e. if requestAuthorisation() returns true ).

    Using the callback:

    IDFA.service.requestAuthorisation(
    function( authorisationStatus:String ):void
    {
    trace( authorisationStatus );
    }
    );

    Using the event:

    IDFA.service.addEventListener( IDFAAuthorisationEvent.CHANGED, authorisationChangedHandler );
    var success:Boolean = IDFA.service.requestAuthorisation();

    function authorisationChangedHandler( event:IDFAAuthorisationEvent ):void
    {
    trace( "authorisationChangedHandler: " + event.authorisationStatus );
    }

    Advertising Identifier

    The advertising identifier is a user-specific, unique, resettable ID for advertising, provided by Google Play services and the iOS SDK. It gives users better controls and provides developers with a simple, standard system to continue to monetize your apps. It is an anonymous identifier for advertising purposes and enables users to reset their identifier or opt out of interest-based ads within Google Play and iOS apps.

    • iOS: this is the value of the ASIdentifierManager advertisingIdentifier property - documentation
    • Android: this is the value of the Google Play Services advertising ID - documentation.

    The user has the ability to limit ad tracking on both iOS and Android through the device settings. This value can also be retrieved so that you can respect this value in any tracking your application performs.

    Retrieving the advertising identifier or identifier for advertising (IDFA) is an asynchronous process.

    You will need to call getIDFA() to start the call and listen for the IDFAEvent.COMPLETE event. This event contains the current advertisting identifier and whether the user has limited ad tracking.

    IDFA.service.addEventListener( IDFAEvent.COMPLETE, idfaCompleteHandler );
    IDFA.service.getIDFA();

    function idfaCompleteHandler( event:IDFAEvent ):void
    {
    trace( "identifier: " + event.identifier );
    trace( "isLimitAdTrackingEnabled: " + event.isLimitAdTrackingEnabled );
    }

    Example

    The following is a simple example of combining the authorisation request and IDFA retrieval:

    IDFA.service.addEventListener( IDFAEvent.COMPLETE, idfaCompleteHandler );

    IDFA.service.requestAuthorisation(
    function ( status:String ):void
    {
    if (status == TrackingAuthorisationStatus.AUTHORISED)
    {
    IDFA.service.getIDFA();
    }
    }
    );

    function idfaCompleteHandler( event:IDFAEvent ):void
    {
    trace( "identifier: " + event.identifier );
    trace( "isLimitAdTrackingEnabled: " + event.isLimitAdTrackingEnabled );
    }
    - + \ No newline at end of file diff --git a/docs/idfa/index.html b/docs/idfa/index.html index 4ba98e499ee..ffa27f407bd 100644 --- a/docs/idfa/index.html +++ b/docs/idfa/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:

    ❤️ Sponsor

    IDFA

    The IDFA extension gives you simple access to the advertising identifiers on Android and iOS.

    Features

    • Access the identifier for advertising on iOS;
    • Access the advertising Id on Android;
    • Request authorisation using the App Tracking Transparency framework on iOS;
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Example:

    IDFA.service.addEventListener( IDFAEvent.COMPLETE, idfaCompleteHandler );

    IDFA.service.requestAuthorisation(
    function ( status:String ):void
    {
    if (status == TrackingAuthorisationStatus.AUTHORISED)
    {
    IDFA.service.getIDFA();
    }
    }
    );

    function idfaCompleteHandler( event:IDFAEvent ):void
    {
    trace( "identifier: " + event.identifier );
    trace( "isLimitAdTrackingEnabled: " + event.isLimitAdTrackingEnabled );
    }

    - + \ No newline at end of file diff --git a/docs/idfa/migrating-to-androidx/index.html b/docs/idfa/migrating-to-androidx/index.html index aa1edd873fc..a5cee395bbe 100644 --- a/docs/idfa/migrating-to-androidx/index.html +++ b/docs/idfa/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/idfa/migrating/index.html b/docs/idfa/migrating/index.html index 1e89c67ca33..71705c8fb9a 100644 --- a/docs/idfa/migrating/index.html +++ b/docs/idfa/migrating/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating

    Version 5

    Version 5 brings the iOS 14 authorisation requests using the App Tracking Transparency framework.

    You will need to add the usage description to your info additions:

    <key>NSUserTrackingUsageDescription</key>
    <string>This identifier will be used to deliver personalized ads to you.</string>

    (Reference)

    And to ensure you have authorisation before attempting to retrieve the IDFA:

    if (IDFA.service.authorisationStatus() == TrackingAuthorisationStatus.AUTHORISED)
    {
    // You have permission to access the IDFA
    }

    Reference

    Version 4

    Version 4 changes the Google Play Services dependencies removing the dependency on the entire Ads library and replacing it with the much smaller AdsIdentifier library.

    In order to support this change you will need to add the com.distriqt.playservices.AdsIdentifier dependency and remove the com.distriqt.playservices.Ads.

    Please note that other extensions may still need the com.distriqt.playservices.Ads extension (mainly AdMob or related services) so ensure you check your other ANEs before removing it.

    - + \ No newline at end of file diff --git a/docs/image/add-the-extension/index.html b/docs/image/add-the-extension/index.html index 277298d08f8..0d335b9cfae 100644 --- a/docs/image/add-the-extension/index.html +++ b/docs/image/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You should check whether the extension is supported before making calls with the isSupported property. This allows you to react to whether the functionality is available on the device.

    We always implement this function to allow you to dynamically switch functionality and fallback to other methods if the extension is not supported on the current platform and version.

    if (Image.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/image/capturing-a-screenshot/index.html b/docs/image/capturing-a-screenshot/index.html index 4e1692f44b0..90a3949631e 100644 --- a/docs/image/capturing-a-screenshot/index.html +++ b/docs/image/capturing-a-screenshot/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Capturing a Screenshot

    You can use this extension to capture a screenshot of your application as bitmap data and subsequently use that data as you require.

    This is currently supported on iOS and Android API version 21 or higher.

    To capture a screenshot you simply call captureScreenshot and await completion.

    var success:Boolean = Image.service.captureScreenshot();

    captureScreenshot may return false if the current platform is not supported or if a screenshot capture is currently in progress. You should avoid wherever possible capturing two screenshot simulataneously as this may have undesirable results.

    Completion is indicated by either a success event ImageEvent.SCREENSHOT_COMPLETE or an error ImageEvent.SCREENSHOT_ERROR.

    Image.service.addEventListener( ImageEvent.SCREENSHOT_COMPLETE, screenshot_completeHandler );
    Image.service.addEventListener( ImageEvent.SCREENSHOT_ERROR, screenshot_errorHandler );

    var success:Boolean = Image.service.captureScreenshot();

    function screenshot_completeHandler( event:ImageEvent ):void
    {
    // event.bitmapData will contain the bitmap data of the screenshot
    }

    function screenshot_errorHandler( event:ImageEvent ):void
    {
    // event.error will contain a description of the error
    // event.errorCode will contain a numeric code of the error
    }

    iOS

    On iOS your screenshot will be captured without any user interaction. It is not possible to get the current image of the status bar so only your application accessible content will be contained in the screenshot.

    Android

    On Android, user permission is required to capture a screenshot. On calling captureScreenshot your user may be presented a permission dialog. If they accept then the screenshot will be captured and subsequent screenshots will not require interaction. If they deny the permission then the screenshot will fail with an error event and subsequent screenshot capture attempts will present the permission dialog again.

    - + \ No newline at end of file diff --git a/docs/image/changelog/index.html b/docs/image/changelog/index.html index 292b7969d7a..f956369335d 100644 --- a/docs/image/changelog/index.html +++ b/docs/image/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.18 [v5.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #50)
    feat(android): Move to new permissions request process

    2022.02.07 [v5.1.82]

    Update air package for Android 31
    Update docs for Android 31

    2022.01.20 [v5.1.81]

    Update documentation to use apm
    Add descriptions for air package parameters
    Add windows x64 support

    2021.10.05 [v5.1.79]

    Add air package
    Add windows implementation
    Add default decoding functionality
    Remove ios minimum version flag
    Add android activity security

    2020.03.21 [v5.0.007]

    Android X migration (resolves #49)

    2019.08.15 [v4.0.003]

    Android 64bit support (resolves #45)
    Updated minimum iOS version to 9.0

    2019.03.12 [v3.2.098]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode

    2018.08.21 [v3.1.097]

    Android: Added additional memory checks on large image operations (#42)

    2018.08.17 [v3.1.095]

    Added error events when bitmap could not be retrieved (resolves #43)

    2018.01.18 [v3.1.089]

    Added ability to take a screenshot (resolves #39)

    2017.10.12 [v3.0.038]

    Added rotate and resize transformations (resolves #32, resolves #25)
    Added checks for directories (resolves #28)

    2017.07.14 [v2.6.020]

    Updated documentation to reflect new permissions (resolves #31)
    iOS: Added authorisation process for iOS 10+ (resolves #35)
    iOS: Cached bitmap data internally to avoid async crash (resolves #30)

    2017.07.10 [v2.5.016]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.29 [v2.5.015]

    Updated documentation

    2016.12.29 [v2.5.015]

    Added runtime authorisation for Android, updated SDKs + documentation

    2016.09.20 [v2.4.004]

    iOS: Corrected legacy support for pre Photos framework (#19)

    2016.09.16 [v2.4.003]

    Added ability to set filename of file saved to the camera roll (resolves #19)

    2016.08.01

    Added function to rotate bitmap data (resolves #21)

    2016.07.05

    Enhanced saveToCameraRoll enabling format and quality options (resolves #19)

    2016.06.30

    Added the saveToCameraRoll function to save bitmapData to the users photos (resolves #18)

    2016.05.10

    Release v2.0
    Added native load/decode (resolves #14)
    Android: Implemented saveBitmapData function (resolves #17)
    Added asynchronous versions of all functions
    Added checks on inputs (resolves #6)

    2016.02.25

    Added checks on the quality value to avoid crashes with extreme values (resolves #10)

    2015.07.09

    Android: Fix for key verification failing for package names starting with a numerical value (resolves #7)

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.02.02

    Added check for .debug suffix in application id

    2014.12.20

    iOS: Included arm64 support (resolves #2) 
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.05

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    New application based key check, removing server checks
    - + \ No newline at end of file diff --git a/docs/image/decoding-bytearray-to-bitmapdata/index.html b/docs/image/decoding-bytearray-to-bitmapdata/index.html index e989303813a..d0fb5709f13 100644 --- a/docs/image/decoding-bytearray-to-bitmapdata/index.html +++ b/docs/image/decoding-bytearray-to-bitmapdata/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ encoded image data into bitmap data. It is the core functionality used to load a bitmap from file converting the file bytes to bitmap data.

    var data:ByteArray = ...; // Encoded data from a file load for example

    Image.service.addEventListener( ImageEvent.DECODE_COMPLETE, decodeAsync_completeHandler );
    Image.service.addEventListener( ImageEvent.DECODE_ERROR, decodeAsync_errorHandler );

    var success:Boolean = Image.service.decodeAsync( data );

    When the decode operation completes you will receive either an ImageEvent.DECODE_COMPLETE event or an ImageEvent.DECODE_ERROR event:

    function decodeAsync_completeHandler( event:ImageEvent ):void
    {
    trace( "Decode successful" );

    // Use the bitmap data
    var b:Bitmap = new Bitmap( event.bitmapData );
    addChild( b );
    }

    function decodeAsync_errorHandler( event:ImageEvent ):void
    {
    trace( "Decode failed: " + event.error );
    }
    - + \ No newline at end of file diff --git a/docs/image/encoding-bitmapdata-to-bytearray/index.html b/docs/image/encoding-bitmapdata-to-bytearray/index.html index 416b55516a1..17fd76de66a 100644 --- a/docs/image/encoding-bitmapdata-to-bytearray/index.html +++ b/docs/image/encoding-bitmapdata-to-bytearray/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Encoding BitmapData to ByteArray

    This process is the allows you to encode image data into encoded image bytes. It is the core functionality used to save a bitmap to file.

    var image:Bitmap = new SampleImage() as Bitmap;

    Image.service.addEventListener( ImageDataEvent.ENCODE_COMPLETE, encodeAsync_completeHandler );
    Image.service.addEventListener( ImageDataEvent.ENCODE_ERROR, encodeAsync_errorHandler );

    var success:Boolean = Image.service.encodeAsync( image.bitmapData, ImageFormat.PNG );

    When the encode operation completes you will receive either an ImageDataEvent.ENCODE_COMPLETE event or an ImageDataEvent.ENCODE_ERROR event:

    function encodeAsync_completeHandler( event:ImageDataEvent ):void
    {
    var encodedData:ByteArray = event.data;
    }

    function encodeAsync_errorHandler( event:ImageDataEvent ):void
    {
    trace( "Encode failed: " + event.error );
    }
    - + \ No newline at end of file diff --git a/docs/image/index.html b/docs/image/index.html index 9aa0659ec42..5dd8b8dfb5b 100644 --- a/docs/image/index.html +++ b/docs/image/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ synchronously and asynchronously. Using native functionality to encode image data will significantly increase the speed of saving image data to the device.

    We provide complete guides to get you up and running with dialogs quickly and easily.

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Features

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    var icon:Bitmap = new Icon() as Bitmap;
    var encodedData:ByteArray = new ByteArray();

    Image.service.encode( icon.bitmapData, encodedData, ImageFormat.JPG, 0.2 );

    More information here:

    com.distriqt.Image

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/image/loading-bitmapdata-from-file/index.html b/docs/image/loading-bitmapdata-from-file/index.html index b639fc802bf..3204873008f 100644 --- a/docs/image/loading-bitmapdata-from-file/index.html +++ b/docs/image/loading-bitmapdata-from-file/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ however the difference is much closer here, and sometimes the built in AIR methods can be faster, mainly due to the time taken to move the bitmap across the native - AIR boundary.

    Image.service.addEventListener( ImageEvent.LOAD_COMPLETE, loadBitmapDataAsync_completeHandler );
    Image.service.addEventListener( ImageEvent.LOAD_ERROR, loadBitmapDataAsync_errorHandler );

    var file:File = File.applicationStorageDirectory.resolvePath("test.png");

    var success:Boolean = Image.service.loadBitmapDataAsync( file.nativePath );

    When the load operation completes you will receive either an ImageEvent.LOAD_COMPLETE event or an ImageEvent.LOAD_ERROR event:

    function loadBitmapDataAsync_completeHandler( event:ImageEvent ):void
    {
    trace( "Load successful" );

    // Use the bitmap data
    var b:Bitmap = new Bitmap( event.bitmapData );
    addChild( b );
    }

    function loadBitmapDataAsync_errorHandler( event:ImageEvent ):void
    {
    trace( "Load error: " + event.error );
    }
    - + \ No newline at end of file diff --git a/docs/image/migrating-to-androidx/index.html b/docs/image/migrating-to-androidx/index.html index 6e8e38e1498..78d44bb55fa 100644 --- a/docs/image/migrating-to-androidx/index.html +++ b/docs/image/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/image/migrating-to-v5.2/index.html b/docs/image/migrating-to-v5.2/index.html index ebda1b9bb73..963c24b638c 100644 --- a/docs/image/migrating-to-v5.2/index.html +++ b/docs/image/migrating-to-v5.2/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v5.2

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/image/request-authorisation/index.html b/docs/image/request-authorisation/index.html index cda8a31b313..67dee27bf0d 100644 --- a/docs/image/request-authorisation/index.html +++ b/docs/image/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ about why you require this functionality.

    On iOS the user must be asked at runtime, which you only get one chance to ask, after which you must direct the user to manually change the permissions in the settings.

    On iOS < 10 you will not need to request permissions for this extension. This is due to iOS not requiring user permission to save image data to the camera roll.

    This changed in iOS 10 and you are now required to request permissions.

    Usage Description

    You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

    The image below is an example of the authorisation dialog. The content "This app would like to access your photos" is the usage description message you can set.

    You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project. (See Add the Extension for details on setting these values).

    Authorisation Status

    To get the current status call the authorisationStatus() function:

    var status:String = Image.service.authorisationStatus();

    The returned value will be one of the values defined in the AuthorisationStatus class:

    Request Authorisation

    To request authorisation call the requestAuthorisation() function:

    Image.service.requestAuthorisation();

    This will present the authorisation dialog (if possible).

    Example

    The following code will work across both platforms:

    Image.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
    checkAuthorisation();

    function checkAuthorisation():void
    {
    switch (Image.service.authorisationStatus())
    {
    case AuthorisationStatus.SHOULD_EXPLAIN:
    // You should further explain the usage here
    // before calling requestAuthorisation again

    case AuthorisationStatus.NOT_DETERMINED:
    // REQUEST AUTHORISATION: This will display the permission dialog
    Image.service.requestAuthorisation();
    return;

    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    case AuthorisationStatus.RESTRICTED:
    // ACCESS DENIED: You should inform your user appropriately
    return;

    case AuthorisationStatus.AUTHORISED:
    // AUTHORISED: Saving to camera roll will be available
    break;
    }
    }

    function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    // You should perform the above check again
    checkAuthorisation();
    }
    - + \ No newline at end of file diff --git a/docs/image/saving-bitmapdata-to-file/index.html b/docs/image/saving-bitmapdata-to-file/index.html index 9f3a2a102f3..3edd67f5e0b 100644 --- a/docs/image/saving-bitmapdata-to-file/index.html +++ b/docs/image/saving-bitmapdata-to-file/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ to save the image. So by default we cache the image internally.

    This can have a small affect on the performance as we need to create a copy of the image.

    If you are concerned about the speed of this function you should try to set cacheBitmapInternally to false and make sure that you hold onto a reference to your bitmap data, for example, as a class variable.

    // Class variable will hold reference to bitmap
    private var image:Bitmap;


    private function saveBitmap():void
    {
    Image.service.addEventListener( ImageEvent.SAVE_COMPLETE, saveBitmapDataAsync_completeHandler );
    Image.service.addEventListener( ImageEvent.SAVE_ERROR, saveBitmapDataAsync_errorHandler );

    // Set cacheBitmapInternally to false
    var success:Boolean = Image.service.saveBitmapDataAsync( image.bitmapData, f.nativePath, ImageFormat.PNG, false );
    }

    private function saveBitmapDataAsync_completeHandler( event:ImageEvent ):void
    {
    trace( "Save successfully: " + event.identifier );
    // dispose image if required.
    }

    private function saveBitmapDataAsync_errorHandler( event:ImageEvent ):void
    {
    trace( "Save failed: " + event.identifier );
    // dispose image if required.
    }
    - + \ No newline at end of file diff --git a/docs/image/saving-bitmapdata-to-the-camera-roll/index.html b/docs/image/saving-bitmapdata-to-the-camera-roll/index.html index 03a1265e7fa..e17ca78b9e4 100644 --- a/docs/image/saving-bitmapdata-to-the-camera-roll/index.html +++ b/docs/image/saving-bitmapdata-to-the-camera-roll/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ your application permission to save to the camera roll. On Android this is a "dangerous" permission and requires runtime permission. On iOS it should always be granted.

    Take a look at the Request Authorisation section for more information.

    Example

    This example uses an embedded image asset in the class SampleImage.

    var image:Bitmap = new SampleImage() as Bitmap;

    Image.service.addEventListener( ImageEvent.SAVE_TO_CAMERAROLL_COMPLETE, completeHandler );
    Image.service.addEventListener( ImageEvent.SAVE_TO_CAMERAROLL_ERROR, errorHandler );
    Image.service.saveToCameraRoll( image.bitmapData );

    You will receive either an ImageEvent.SAVE_TO_CAMERAROLL_COMPLETE event or an ImageEvent.SAVE_TO_CAMERAROLL_ERROR event:

    private function completeHandler( event:ImageEvent ):void
    {
    trace( "saveToCameraRoll : complete" );
    }

    private function errorHandler( event:ImageEvent ):void
    {
    trace( "saveToCameraRoll : error: "+event.error );
    }
    - + \ No newline at end of file diff --git a/docs/image/transformations/index.html b/docs/image/transformations/index.html index f0386a0b427..504d87b9526 100644 --- a/docs/image/transformations/index.html +++ b/docs/image/transformations/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Transformations

    You can apply transformations to BitmapData by using the transformAsync function to return BitmapData or the transformAndSaveAsync function to save to a file.

    Each of these functions take an instance of the ImageTransform class which specifies the details of the transformation to apply to the image.

    The functions will return true if the transformation process was started successfully and false if there was an error either with the state of the extension or with the conversion of the parameters to native.

    The transformation will occur on a background thread and once complete will dispatch the ImageEvent.TRANSFORM_COMPLETE event or ImageEvent.TRANSFORM_ERROR if there was an error.

    Rotations

    To rotate an image set the rotate property of your transform to be the angle of rotation in degrees:

    var transform:ImageTransform = new ImageTransform();
    transform.rotate = 90;

    Image.service.addEventListener( ImageEvent.TRANSFORM_COMPLETE, completeHandler );
    Image.service.addEventListener( ImageEvent.TRANSFORM_ERROR, errorHandler );

    Image.service.transformAsync( bitmapData, transform );

    function completeHandler( event:ImageEvent ):void
    {
    // event.bitmapData contains the transformation result
    }

    function errorHandler( event:ImageEvent ):void
    {
    // An error occurred
    }

    You can specify any arbitrary angle to rotate the image by. The size of the resulting image will be a bounding box around the rotated image so will most likely be larger than the original image.

    Resizing

    To resize an image there are several options to achieve a different sized image.

    The resizeMethod specifies the approach the resizing will take to handle dealing with aspect ratios and clipping. It can be one of the following:

    • ImageTransform.RESIZE_NONE: (Default) no resizing will occur
    • ImageTransform.RESIZE_BEST_FIT: best fit the image to inside the specified width and height
    • ImageTransform.RESIZE_FILL_NO_CROP: Uses the width and height as the minimum dimensions and performs no cropping.
    • ImageTransform.RESIZE_FILL: Fill the specified width and height with the image, cropping if necessary.

    Along with this method you specify the width and height you require.

    For example, to get an exact image sized 150x150 we would use the fill method:

    var transform:ImageTransform = new ImageTransform();
    transform.resizeMethod = ImageTransform.RESIZE_FILL;
    transform.width = 150;
    transform.height = 150;

    Image.service.transformAsync( bitmapData, transform );

    See the ImageTransform class in asdocs for more on these methods.

    Transform and Save

    In some circumstances you may need to transform an image and save to a file directly, rather than needing the transformed data in your application. Using the transformAndSaveAsync function you will save on the time required to create and return the required bitmap data to AIR and the extension instead will save the result directly to a file on the user's device.

    This function takes the same transformation options as the transformAsync function however it additionally takes an output parameter that specifies the location and format of the output file.

    For example, to generate a 150x150 thumbnail for an image and save to the application storage:

    var transform:ImageTransform = new ImageTransform();
    transform.resizeMethod = ImageTransform.RESIZE_FILL;
    transform.width = 150;
    transform.height = 150;

    var file:File = File.applicationStorageDirectory.resolvePath("images/thumbnail.jpg");

    var output:ImageOutput = new ImageOutput( file.nativePath );
    output.format = ImageFormat.JPG;

    Image.service.transformAndSaveAsync( transformImage.bitmapData, transform, output );

    Events and Callbacks

    You can use the events to process the completion of the transformation.

    Image.service.addEventListener( ImageEvent.TRANSFORM_COMPLETE, completeHandler );
    Image.service.addEventListener( ImageEvent.TRANSFORM_ERROR, errorHandler );

    function completeHandler( event:ImageEvent ):void
    {
    // event.bitmapData contains the transformation result
    }

    function errorHandler( event:ImageEvent ):void
    {
    // An error occurred
    }

    Alternatively, you can use a callback function as a parameter to the transformAsync or transformAndSaveAsync functions.

    The callback for transformAsync passes the transformed bitmap data as a parameter to the callback:

    Image.service.transformAsync( bitmapData, transform, callback );

    function callback( bitmapData:BitmapData ):void
    {
    // This will be called when the above transform completes
    }

    The callback for transformAndSaveAsync passes the success of the save operation to the callback:

    Image.service.transformAndSaveAsync( bitmapData, transform, output, callback );

    function callback( success:Boolean ):void
    {
    // This will be called when the above transform completes
    }
    - + \ No newline at end of file diff --git a/docs/inappbilling/add-the-extension/index.html b/docs/inappbilling/add-the-extension/index.html index 10762d3598c..e0ad8b9a307 100644 --- a/docs/inappbilling/add-the-extension/index.html +++ b/docs/inappbilling/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    This extension requires you call the init() function at some point early in your application, generally at the same time as the initialisation of this extension. If you are using other extensions that also require the Core extension, you only need to initialise it once, before initialising the other extensions.

    Core.init();

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (InAppBilling.isSupported)
    {
    // Functionality here
    }
    note

    This only checks if there is some functionality supported, not whether a particular billing service is available.

    - + \ No newline at end of file diff --git a/docs/inappbilling/amazon/add-the-extension/index.html b/docs/inappbilling/amazon/add-the-extension/index.html index 1bf51d49dd8..1e56f9d0e35 100644 --- a/docs/inappbilling/amazon/add-the-extension/index.html +++ b/docs/inappbilling/amazon/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    This extension requires you call the init() function at some point early in your application, generally at the same time as the initialisation of this extension. If you are using other extensions that also require the Core extension, you only need to initialise it once, before initialising the other extensions.

    Core.init();

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Appstore Authentication Key

    To add the PEM file to your application:

    note

    The link to the public key appears only when you create a new version or when you create a new app. If you had a new version in progress prior to the release of the Appstore SDK, you must complete your existing version and then create a new version — then the public key link will appear. Alternatively, for this tutorial you can just create a new Android app.

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (InAppBilling.isSupported)
    {
    // Functionality here
    }
    note

    This only checks if there is some functionality supported, not whether a particular billing service is available.

    - + \ No newline at end of file diff --git a/docs/inappbilling/amazon/amazon-in-app-purchasing/index.html b/docs/inappbilling/amazon/amazon-in-app-purchasing/index.html index f10b79c62c5..a804a0940cd 100644 --- a/docs/inappbilling/amazon/amazon-in-app-purchasing/index.html +++ b/docs/inappbilling/amazon/amazon-in-app-purchasing/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Setup Amazon IAP

    Add Your Application to the Developer Console

    Login to the Amazon developer console and add your application to the available apps:

    https://developer.amazon.com/apps-and-games/console/apps/list.html

    Creating your products

    Select "In-App Items" and add all your products making sure to correctly set them up as either a consumable, entitlement (non-consumable) or subscription.

    Ensure the status of your items is "Live" in order to correctly access the products through your application and take note of all your product identifiers (SKUs).

    While you are in this section after setting up all your products it is useful to download the IAP exported JSON file to use when testing. See Testing Amazon In-App Purchasing for more.

    Types of Purchasable Items

    IAP includes three different categories of purchasable items:

    • Consumables: Purchase that is made, then consumed within the app, such as extra lives, extra moves, or in-game currency. May be purchased multiple times.
    • Entitlements: One-time purchase to unlock access to features or content within an app or game.
    • Subscriptions: Offers access to a premium set of content or features for a limited period of time.

    SKUs

    A SKU (technically a stock-keeping unit) is a unique identifier for each distinct purchasable item. It is unique to you (specifically your developer account registered on the developer portal), and is a (up to) 150-character length string of arbitrary structure that can contain the characters a-z, A-Z, 0-9, underscores, periods, and dashes, and is case sensitive. Purchasable items and SKUs have a 1:1 mapping. Your app will pass the SKU value via the PurchasingManager helper class to the client. The SKU is how the client knows what the customer is trying to purchase, and will manage the purchase flow accordingly.

    You need to ensure that every purchasable item you define has a unique SKU. The SKUs are unique across your developer account. When you submit SKUs for multiple apps you need to ensure that there is no overlap.

    Before a SKU can be used, it must be configured via the developer portal. Refer to the developer portal section of the Frequently Asked Questions for information on how to configure SKUs.

    Subscription SKUs

    Subscriptions will have a "parent SKU" which is the main subscription IAP in the console. You shouldn't use this SKU directly. Instead when you create a "Subscription Term" you will create a secondary SKU for the particular subscription term. This is the identifier you should use for getProducts() and when making a purchase.

    Unfortunately there is no functionality in the SDK to retrieve the parent subscription currently so you must understand the relationship between your subscriptions and the subscription terms.

    Recommendation

    We recommend you use a convention on naming these subscriptions so you can easily determine which is the parent subscription and ensure you deliver the correct content.

    For example, if your parent subscription has an SKU of com.application.subscription1, then make your term SKUs extend this identifier, eg : com.application.subscription1.monthly, com.application.subscription1.annually etc.

    App Submission Process

    You need to create and submit the in-app items for your IAP-integrated app before you submit the app to the Appstore. The Amazon Appstore will not test your app until both the app and your in-app items are submitted.

    If you decide to add or edit your purchasable items after submitting your app, you will need to re-submit both the new/changed items and the app itself to the Amazon Appstore.

    - + \ No newline at end of file diff --git a/docs/inappbilling/amazon/testing/index.html b/docs/inappbilling/amazon/testing/index.html index 59eed6215a2..a6d2c0b55dc 100644 --- a/docs/inappbilling/amazon/testing/index.html +++ b/docs/inappbilling/amazon/testing/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Testing Amazon IAP

    Amazon In-App Purchasing

    Amazon does not provide a complete "sandbox" type environment for testing like Google's In-App Billing and Apple's In-App Purchases.

    Instead you will need to install and configure the App Tester application and utilise the app to intercept IAP calls.

    Install and Configure the App Tester

    App Tester allows you to unit test the In-App Purchasing (IAP) functionality of your app in sandbox mode before you submit the app for publication. You download App Tester from the Amazon Appstore onto the same Android device as your app. The App Tester simulates the production environment. You run IAP-related test cases on your app, and App Tester generates API responses (that you configure using a JSON file).

    The easiest way is to install the app from the Amazon Appstore

    • On your Android mobile device, start the Amazon Appstore app.
    • Search for "Amazon App Tester".
    • Select the "Amazon App Tester" app. (Do not select the Web App Tester, which is a different app.)
    • Tap through the prompts to download and install the app.

    Create a JSON Data File

    The App Tester responds to API calls using data stored in a JavaScript Object Notation (JSON) text file. The file contains purchase data for the IAP items.

    You can automatically create the JSON file through the Apps & Games Developer Portal.

    • In a web browser, go to the your app's page on the Apps & Games Developer Portal.
    • Add your IAP purchasable items to your app, if you have not already done so.
    • Export the IAPs to JSON by selecting: Export Multiple IAPs / JSON
    • Click the link to download your JSON Data File.
    • Name the downloaded file "amazon.sdktester.json".
    • Copy the file to /mnt/sdcard/ folder in your device file system.
    adb push amazon.sdktester.json /mnt/sdcard/amazon.sdktester.json

    The location of the download link is as in the following screenshot:

    Verify IAP Items

    You can easily review the contents of the JSON file. From the App Tester main menu, tap the IAP Items in JSON File option to display a human-readable list of the item data in the JSON file.

    Enter sandbox mode

    Sandbox mode constrains calls that would normally go to the Appstore client to route to the Amazon App Tester app instead. Use this mode only for testing locally.

    In the same terminal where you connected to your Fire device through ADB, enter sandbox mode:

    adb shell setprop debug.amazon.sandboxmode debug

    (Note that if you need to exit sandbox mode, run the following: adb shell setprop debug.amazon.sandboxmode none.)

    Every time you reconnect to your Fire device through ADB, you need to reinitiate sandbox mode.

    To confirm you have sandbox mode enabled have a look in the adb logs for something like the following line:

    D/Kiwi    (12294): AppstoreSDK: Sandbox Mode: Debug build and debug.amazon.sandboxmode property is set on device

    If it is in production mode you will see something like the following:

    D/Kiwi    (11971): AppstoreSDK: Production Mode: Release build or debug.amazon.sandboxmode property is not set on devic
    note

    You must be using a recent release of AIR, version 33.1.1.889 or higher. APK's produced in older versions of AIR are incorrectly packaged as production builds. You can work around this by using the AndroidStudioProject output if required.

    Next Steps

    Familiarize yourself with the App Tester tool and the test options for IAP:

    1. Read the App Tester User Guide to learn how to use this tool.
    2. See Design and Execute Test Cases for IAP for ideas on how to test your IAP functionality.

    For more information on any of the processes here see the Amazon documentation.

    Set Installer Package

    If you are using a non-Amazon device with the Amazon App-Store installed to test you must set the correct installer package in order that the extension can correctly detect that the amazon service is supported.

    When installing your application you will need to use the following commands using the adb terminal command:

    adb push YOURAPP.apk /data/local/tmp/app.apk
    adb shell pm install -i "com.amazon.venezia" -r /data/local/tmp/app.apk
    adb shell rm /data/local/tmp/app.apk

    Change YOURAPP.apk to be the path to your application. This command will set the installer package name to be the Amazon AppStore's package name com.amazon.venezia.

    If you don't set this and rely on the default detection then you will find debugging may default to the Google Play Billing implementation.

    Amazon Terms

    In order to understand the difference between our implementation and the standard Amazon documentation the table belows shows where the associated Amazon methods are called by the extension. Most have a direct relationship between the Amazon call and the extension however there are some minor differences.

    Amazon MethodExtension Method
    registerListenersetup
    getProductDatagetProducts
    getPurchaseUpdatesgetPurchases & restorePurchases
    purchasemakePurchase
    notifyFulfillmententitlement and subscription productsfinishPurchase
    consumable productsconsumePurchase

    Listener callbacks are mapped to extension events depending on the triggered call:

    Amazon Listener CallbackExtension Event(s)
    onProductDataResponsesuccessInAppBillingEvent.PRODUCTS_LOADED
    onProductDataResponseinvalid SKUInAppBillingEvent.PRODUCT_INVALID
    onProductDataResponsefailedInAppBillingEvent.PRODUCTS_FAILED
    onPurchaseResponsesuccessPurchaseEvent.PURCHASES_UPDATED
    onPurchaseResponsefailedPurchaseEvent.PURCHASE_FAILED
    onPurchaseUpdatesResponsegetPurchases > successPurchaseEvent.GET_PURCHASES_COMPLETE
    onPurchaseUpdatesResponsegetPurchases > failedPurchaseEvent.GET_PURCHASES_FAILED
    onPurchaseUpdatesResponserestorePurchases > successInAppBillingEvent.RESTORE_PURCHASES_SUCCESS
    onPurchaseUpdatesResponserestorePurchases > failedInAppBillingEvent.RESTORE_PURCHASES_FAILED

    This is provided only as a guide of the implementation to better utilise the Amazon documentation. The exact implementation is more complex.

    - + \ No newline at end of file diff --git a/docs/inappbilling/apple/apple-in-app-purchases/index.html b/docs/inappbilling/apple/apple-in-app-purchases/index.html index 693e7219a93..2eaf1c5c017 100644 --- a/docs/inappbilling/apple/apple-in-app-purchases/index.html +++ b/docs/inappbilling/apple/apple-in-app-purchases/index.html @@ -13,7 +13,7 @@ - + @@ -38,7 +38,7 @@ from your app about which account on your server is associated with the transaction.

    https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html


    Further information

    Apple provides a guide for setting up InApp Purchases. It can be quite a complex process so make sure you follow the guide exactly and complete each step:

    Adding In-App Purchase to your iOS and Mac Applications

    You can also see the Apple FAQs here.

    - + \ No newline at end of file diff --git a/docs/inappbilling/apple/server-side-verification/index.html b/docs/inappbilling/apple/server-side-verification/index.html index b66690ec85b..2b7fb825762 100644 --- a/docs/inappbilling/apple/server-side-verification/index.html +++ b/docs/inappbilling/apple/server-side-verification/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content
    - + \ No newline at end of file diff --git a/docs/inappbilling/apple/testing/index.html b/docs/inappbilling/apple/testing/index.html index 425ffd92406..75e7dfbff21 100644 --- a/docs/inappbilling/apple/testing/index.html +++ b/docs/inappbilling/apple/testing/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Testing Apple In-App Purchases

    iOS Subscriptions

    When testing subscriptions, you should be aware that they work differently in the sandbox, TestFlight and on the App Store.

    In order to test correctly you will need to be aware of these differences.

    Importantly be aware that while running your application in sandbox or TestFlight you will not be able to use Touch / Face ID and that you will experience a much large number of password requests. Basically for every AppStore interaction the password dialog will be presented.

    You have to trust that this process is not how your live application will perform once deployed to production in the AppStore.

    We often advise developers to make a simple way for beta testers to switch between subscribed and unsubscribed otherwise you may find your subscribed state will get a lot less testing due to the number of password requests required (sometimes up to three to purchase a subscription).

    Duration

    Subscription durations are greatly reduced for testing purposes allowing you to quickly test multiple renewals and expirations via TestFlight and in the sandbox.

    Subscription DurationTest Duration
    1 week3 minutes
    1 month5 minutes
    2 months10 minutes
    3 months15 minutes
    6 months30 minutes
    1 year1 hour

    A subscription will automatically renew 6 times per account per 8 hour window, at which point the subscription will expire.

    There is no way to test cancellation directly as these renewals happen automatically.

    There is also no way to test subscription management while in the sandbox or TestFlight.

    Suggested Tests

    Note that with the notes above about the 8 hour window performing several of these tests within a short period may have unexpected results. You should be aware that every subscription may not renew 6 times within that window. Try to perform tests within the first subscription period (5 minutes for monthly).

    We suggest you test the Renewals and Expiration first as this is the main test that uses the renewal attempts.

    Also it is helpful to test with multiple sandbox accounts as these restrictions are per account.

    Renewals and Expiration

    This process is to test the the subscription, renewals and expiration process works correctly.

    • Subscribe to a monthly subscription
    • Close your app and wait 5 minutes
    • Launch your app
    • If a prompt is displayed enter the password

    Your application should still be subscribed at this point.

    • Repeat this process until 35 minutes have passed (6 renewal periods + original subscription period)

    Your application should now be in an un-subscribed state.

    Restoring after Expiration

    This process is to test whether the restore purchases call correctly reports no active subscriptions after a subscription has expired.

    • Subscribe to a monthly subscription
    • Perform the Renewals and Expiration test to expire the subscription or simply close the app and wait 35 minutes
    • Launch the application (enter password if prompted)
    • Go through your restore purchases process

    At this point it should report no active subscriptions were found and your application should be in the un-subscribed state.

    Restoring during Subscription

    This process is to check the restoring of a subscription during an active subscription period.

    • Subscribe to a monthly subscription
    • Close and uninstall the application
    • Reinstall the application within 5 minutes
    • Go through your restore purchases process

    At this point the application should have restored the active subscription and be in the subscribed state.

    Restoring during Subscription on multiple devices

    This process is to check the updating of the subscription state across a user's devices.

    • Subscribe to a monthly subscription
    • Install the application on another device before the expiration
    • Go through your restore purchases process using the same test user as on the first device

    The restore process should have picked up the active subscription purchased on the first device and the second device should be in the subscribed state.

    - + \ No newline at end of file diff --git a/docs/inappbilling/apple/troubleshooting/index.html b/docs/inappbilling/apple/troubleshooting/index.html index 276959a9c72..9da63d50c80 100644 --- a/docs/inappbilling/apple/troubleshooting/index.html +++ b/docs/inappbilling/apple/troubleshooting/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Change the status to "Waiting for Upload" by clicking "Ready to Upload Binary" in iTunes Connect and the problem should be resolved after about 10 minutes.

    The correct order for purchasing a product is as follows:

    Note: You should be aware that any process that causes the iTunes login without user interaction will most likely result in your application failing to pass the review guidelines.

    - + \ No newline at end of file diff --git a/docs/inappbilling/application-receipt/index.html b/docs/inappbilling/application-receipt/index.html index 88c381a5708..d3e6d29d0b0 100644 --- a/docs/inappbilling/application-receipt/index.html +++ b/docs/inappbilling/application-receipt/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Application Receipt

    note

    The concepts here are relevant only to iOS, iPadOS and macOS using Apple's In-App Purchasing

    The application receipt provides a record of the sale of an app and any purchases the person makes within the app.

    You can use this receipt to verify purchases and check expiration of subscriptions.

    There are two ways to verify a receipt’s authenticity:

    • On your server with the App Store. Validating receipts with the App Store requires secure connections between your app and your server, and between your server and the App Store. For more information, see Validating receipts with the App Store.
    • Locally, on the device. Validating receipts locally requires code that reads and validates a binary file that Apple encodes and signs as a PKCS #7 container. For more information, see Validating receipts on the device.

    It is up to you to decide if this is required for your situation.

    info

    The "Application Receipt" variant performs local validation of the application receipt to retrieve purchase information and makes this information available through the Get Purchases API.

    Checking for support

    You can check if the current device supports the application receipt by checking the isSupported flag:

    if (InAppBilling.service.applicationReceipt.isSupported)
    {
    // Application Receipt functionality is supported
    }

    Fetch the receipt data

    To retrieve the receipt call the getAppReceipt() method:

    var appReceipt:String = InAppBilling.service.applicationReceipt.getAppReceipt();

    This returns the base 64 encoded contents of the application receipt file. Generally this is the string that you will likely send to Apple to verify the receipt.

    The app receipt is always present in the production environment on devices running macOS, iOS, and iPadOS. The app receipt is also always present in TestFlight on devices running macOS. In the sandbox environment and in StoreKit Testing in Xcode, the app receipt is present only after the tester makes the first in-app purchase. If the app calls SKReceiptRefreshRequest or restoreCompletedTransactions, the app receipt is present only if the app has at least one in-app purchase.

    If the receipt is empty i.e. appReceipt == "" then you will need to refresh the receipt.

    Refreshing the receipt

    To refresh the receipt you call the refresh() method:

    InAppBilling.service.applicationReceipt.refresh();

    You can specify some properties for the refresh process through the first optional parameter to this function which is an instance of the ApplicationReceiptProperties class,

    var props:ApplicationReceiptProperties = new ApplicationReceiptProperties();
    props.isVolumePurchase = true;

    InAppBilling.service.applicationReceipt.refresh( props );

    The default value is null.

    You can monitor the result of the refresh call either through the dispatched events or a callback.

    Events

    The refresh() method will dispatch one of two possible events:

    • ApplicationReceiptEvent.REFRESH_SUCCESS: Dispatched if the refresh succeeded;
    • ApplicationReceiptEvent.REFRESH_FAILED: Dispatched if the refresh failed;
    InAppBilling.service.applicationReceipt.addEventListener( 
    ApplicationReceiptEvent.REFRESH_FAILED,
    refreshFailedHandler );
    InAppBilling.service.applicationReceipt.addEventListener(
    ApplicationReceiptEvent.REFRESH_SUCCESS,
    refreshSuccessHandler );

    function refreshSuccessHandler( event:ApplicationReceiptEvent ):void
    {
    var appReceipt:String = InAppBilling.service.applicationReceipt.getAppReceipt();
    trace( "getAppReceipt() = " + appReceipt );
    }

    function refreshFailedHandler( event:ApplicationReceiptEvent ):void
    {
    trace( "application receipt refresh failed" + event.error );
    }

    Callback

    You can pass a callback function as the second parameter to the refresh() function, which will be called once the refresh process is complete. It must be of the form function( success:Boolean, error:Error ):void for the function callback to be successful:

    InAppBilling.service.applicationReceipt.refresh( 
    null,
    function( success:Boolean, error:Error ):void
    {
    // refresh complete, check success and error for any issues
    });
    - + \ No newline at end of file diff --git a/docs/inappbilling/billing-service/index.html b/docs/inappbilling/billing-service/index.html index c2735f03422..37f5a000466 100644 --- a/docs/inappbilling/billing-service/index.html +++ b/docs/inappbilling/billing-service/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ If you do not call it then the default for the current platform will be used, i.e. Apple InApp Purchases on iOS and Google's Play InApp Billing on Android.

    We suggest that you do specify a service type, particularly on Android where there are multiple stores involved. This is so that you ensure you are utilising the correct store for your application, otherwise you may find that the extension incorrectly assumes you are using the default store on the device (eg Huawei AppGallery on a Huawei device), which may not be what you intend.

    Availability

    Once you have completed setup it is important to check whether the user on the current device can make payments. There are certain factors that can limit the functionality which can have consequences for all product and purchasing functionality.

    For example, the latest version of Play Billing is only supported with an updated version of the Play Store app. If an older version is on the user's device the billing api will not be available.

    To check the status call the checkAvailability() function and await the result. This function will dispatch an AvailabilityEvent.COMPLETE event or call a callback function passed as the parameter to the function.

    Callback:

    InAppBilling.service.checkAvailability(
    function ( availability:String ):void
    {
    trace( "availability = " + availability );
    }
    );

    Event:

    InAppBilling.service.addEventListener( AvailabilityEvent.COMPLETE, function( event:AvailabilityEvent ):void
    {
    trace( "availability = " + event.availability );
    });
    InAppBilling.service.checkAvailability();

    The availability value will be one of the values defined in the InAppBillingAvailability class:

    You should handle the response as required and inform your users if purchasing isn't available or steps to upgrade the store application.

    note

    If you don't check for the availability you will find certain aspects of the extension will fail. For example, if a store upgrade is required you will likely get failed events from functions like getProducts() with the error code FEATURE_NOT_SUPPORTED.

    It is equally appropriate to handle those error events however we suggest an upfront approach using this function can provide a better user experience.

    Pending Purchases

    Note that the pending purchases may not be available to you at the InAppBillingEvent.SETUP_SUCCESS event, as they may be updated after setup has completed. This is particularly true on iOS/tvOS where the payment queue update (which populates the pending purchases) will occur a short time after setup succeeds.

    This update will be indicated by a PurchaseEvent.PURCHASES_UPDATED, indicating there are purchases to process.

    - + \ No newline at end of file diff --git a/docs/inappbilling/change-a-purchase/index.html b/docs/inappbilling/change-a-purchase/index.html index 5001663e449..cd852ba0f70 100644 --- a/docs/inappbilling/change-a-purchase/index.html +++ b/docs/inappbilling/change-a-purchase/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Change a Purchase

    You can offer users different subscription tiers, such as a base tier and a premium tier in some billing services (such as Google Play Billing).

    If your application provides different teirs of subscriptions a user should be able to upgrade and downgrade a subscription by purchasing a different tier subscription.

    Support

    Not every service supports changing purchases, so you should check the isChangePurchaseSupported flag before attempting any of the following functionality:

    if (InAppBilling.service.isChangePurchaseSupported)
    {
    // changing purchases is supported on the current platform and service
    }
    note

    Only call this after setting up your billing service.

    Changing a Purchase

    You should present a screen with the available subscriptions for a user and then if required trigger the upgrade / downgrade process by calling the changePurchase() method.

    When upgrading or downgrading, you pass information about the current purchase including the product id and transaction id (i.e. Google Play purchase token) for the current subscription and the product id for the new (upgraded or downgraded) subscription and subscription offer:

    var request:PurchaseChangeRequest = new PurchaseChangeRequest()
    .setCurrentDetails( "current_product_id", "current_purchase_transaction_id" )
    .setNewProductId( "new_product_id" )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    );

    var success:Boolean = InAppBilling.service.changePurchase( request );

    Similar to making a purchase you should listen for the PurchaseEvent.PURCHASES_UPDATED and PurchaseEvent.PURCHASE_FAILED events to handle the result from the purchase change.

    InAppBilling.service.addEventListener( PurchaseEvent.PURCHASES_UPDATED, purchases_updatedHandler );
    InAppBilling.service.addEventListener( PurchaseEvent.PURCHASE_FAILED, purchase_failedHandler );
    Subscription Offers

    Similar to a PurchaseRequest for a normal subscription you must provide an offer as part of the PurchaseChangeRequest. This must be an offer on the new subscription. See Subscription Offers for more information.

    Set proration mode

    When upgrading or downgrading a subscription, you can call setProrationMode() in the PurchaseChangeRequest class to provide details about the proration that will be applied when the subscription changes:

    var request:PurchaseChangeRequest = new PurchaseChangeRequest()
    .setCurrentDetails( "current_product_id", "current_purchase_transaction_id" )
    .setNewProductId( "new_product_id" )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    )
    .setProrationMode( PurchaseChangeRequest.IMMEDIATE_WITH_TIME_PRORATION );

    The following table lists all of the proration modes.

    PurchaseChangeRequest.IMMEDIATE_WITH_TIME_PRORATIONReplacement takes effect immediately, and the new expiration time will be prorated and credited or charged to the user. This is the current default behavior.
    PurchaseChangeRequest.IMMEDIATE_AND_CHARGE_PRORATED_PRICEReplacement takes effect immediately, and the billing cycle remains the same. The price for the remaining period will be charged. Note: This option is only available for subscription upgrade.
    PurchaseChangeRequest.IMMEDIATE_WITHOUT_PRORATIONReplacement takes effect immediately, and the new price will be charged on next recurrence time. The billing cycle stays the same.
    PurchaseChangeRequest.DEFERREDReplacement takes effect on the next recurrence time.
    PurchaseChangeRequest.IMMEDIATE_AND_CHARGE_FULL_PRICEReplacement takes effect immediately, and the user is charged full price of new plan and is given a full billing cycle of subscription, plus remaining prorated time from the old plan time.

    Application Username

    Similar to a purchase, you can attach an obfuscated username or account id to a purchase. You can set this during the change purchase process by calling setApplicationUsername() on your purchase change request.

    var request:PurchaseChangeRequest = new PurchaseChangeRequest()
    .setCurrentDetails( "current_product_id", "current_purchase_transaction_id" )
    .setNewProductId( "new_product_id" )
    .setApplicationUsername( "..." );

    Further Reading

    - + \ No newline at end of file diff --git a/docs/inappbilling/changelog/index.html b/docs/inappbilling/changelog/index.html index 05eafbba774..142413fa5c8 100644 --- a/docs/inappbilling/changelog/index.html +++ b/docs/inappbilling/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.13 [v15.2.1]

    fix(android): correct issue with not dispatching failed event after ui cancelled (resolves #552)

    2023.09.06 [v15.2.0]

    feat(actionscript): update api to return product instance on Purchase objects 
    feat(actionscript): add getProduct method to return Product instance for product id

    2023.08.17 [v15.1.0]

    feat(huawei): update huawei appgallery sdk hms.iap v6.10.0.300

    2023.07.05 [v15.0.1]

    feat(android,googleplay): update google play billing client version to 6.0.0
    fix(android,googleplay): correct pending purchase list after purchase consumption (resolves #542)

    2023.02.13 [v14.4.1]

    feat(macos): add apple silicon support (resolves #517)
    feat(android): update gradle version to support building on apple silicon
    feat(amazon): update amazon sdk version 3.0.3
    feat(amazon): add retrieval of product promotions, free trials and introductory offers
    fix(amazon): add workaround to resolve purchase UI not appearing in some circumstances (resolves #470, resolves #521)

    2023.02.02 [v14.4.0]

    feat(ios,appreceipt): add callback to ApplicationReceipt refresh function
    feat(docs): add documentation for the application receipt functionality

    2023.01.20 [v14.3.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #520)
    feat(huawei): update huawei in-app purchases to v6.6.0.301 (resolves #514, resolves #495, resolves #494)
    fix(playbilling): fix for change purchase flow to correctly supply subscription offer for new purchase (resolves #506)
    feat(playbilling): add fallback to legacy implementation when play store is outdated (resolves #489)

    2022.11.04 [v14.0.2]

    feat: add check availability function to check for feature availability and required store upgrades

    2022.10.25 [v14.0.1]

    fix(android): remove usage of String.join (resolves #500)
    fix(docs): update docs to reflect latest testing process with AIR 33.1.1.889+ (#459)

    2022.10.07 [v14.0.0]

    Google Play Billing update
    - v5.0.0

    feat(playbilling): update play billing sdk to v5.0.0 (resolves #482)
    feat(subscriptionoffers): introduce subscription offers across all services replacing product discounts
    feat(getpurchases): play billing purchases should be more accurately retrieved from the store
    feat(productdiscounts): product discounts have been removed
    feat(ios): add ability to show offer code redemption dialog (resolves #464)
    feat(product): add some fallbacks for product priceString
    feat(ios): skoverlay integration
    feat(ios,productoverlay): add event callbacks for product overlay lifecycle

    2022.05.20 [v13.2.4]

    fix(apple): correct closing of product view on older versions of ios (#467)

    2022.05.19 [v13.2.3]

    feat(amazon): update to Amazon Appstore SDK v3.0.2 (resolves #445)
    fix(amazon): correct android exported tags for Amazon receiver
    fix(docs,amazon): add information on adding AppstoreAuthenticationKey.pem and new testing process (#459)
    fix(googleplay): updates for handling odd case where closing app may lose purchase (#451)
    fix(docs): corrected references to REQUEST_INSTALL_PACKAGES permission (resolves #461)

    2022.02.07 [v13.2.1]

    Update package and docs for Android 31
    Update docs to use apm
    Reorganise docs layout
    Minor fixes for manifests in air packages

    2021.09.09 [v13.1.0]

    Added air package
    Updated com.google.android.play dependency to 1.10.1

    Updates:
    - Added cancel date to a purchase to indicate end date of a subscription, and corrected Amazon getProducts returning false (resolves #427)
    - Amazon: Added handling of pagination in purchase query responses (#428)
    - Amazon: Updated implementation for better handling of consume purchase (#428)

    2021.05.16 [v13.0.045]

    Google Play Billing
    - v3.0.3

    Huawei
    - Fixed endless login loop (resolves #410)
    - Changed returned error codes to match definitions in ErrorCodes class

    2021.02.26 [v13.0.037]

    Corrected developer challenge on huawei consume purchase by product id (resolves #402)

    2021.02.11 [v13.0.031]

    Fixed issue with purchase state during restore purchases on Play Billing (resolves #395)

    2021.02.01 [v13.0.030]

    Added Samsung Galaxy Store In-App Purchases (resolves #359)
    Added macOS AppStore (resolves #355)

    Google Play Billing
    - v3.0.2

    Fixes:
    - Android: Added handling of invalid extContext after app update (resolves #374)

    2020.11.06 [v12.1.133]

    Corrected missing classes from default library (resolves #369)

    2020.11.02 [v12.1.128]

    Updated documentation

    2020.11.02 [v12.1.128]

    Updated documentation

    2020.10.28 [v12.1.128]

    Added applicationUsername to a purchase change request (resolves #365)
    Android: Corrected change purchase functionality to include purchase token (resolves #364)
    Correctly reported error message and code with a PurchaseEvent.PURCHASE_FAILED event (resolves #361)

    2020.09.17 [v12.0.119]

    iOS: Corrected build issue with variants (resolves #352)

    2020.09.15 [v12.0.117]

    Added InAppUpdates functionality:
    - Huawei checkAppUpdate (resolves #344)
    - Google Play In-App Updates

    Google Play Billing
    - v3.0.0 (resolves #345)
    - Developer payload changes: https://developer.android.com/google/play/billing/developer-payload
    - Returning obfuscated application username from purchases (resolves #348)

    Android: Changed service support checks to use installer package to better detect store availability (resolves #343)

    2020.08.14 [v11.0.097]

    Added SWC + updated builds

    2020.06.25 [v11.0.096]

    Updated Huawei AppGallery documentation (#323)

    2020.06.22 [v11.0.096]

    Added support for in app purchases through Huawei AppGallery  
    Added ability to retrieve user data (initially Amazon user id) (resolves #322)
    Updated documentation

    2020.04.20 [v10.2.056]

    Added details of subscription period on supported services
    Google Play Billing: Added introductory prices and free trials (resolves #308)
    Google Play Billing library updated to version 2.2.0
    Amazon InAppPurchasing is now considered out of beta (resolves #231)
    Corrected typo in documentation purchased states (resolves #309)

    2020.03.31 [v10.1.049]

    Added finish purchase success and failed events to better handle finishing purchases (#262, #175)
    iOS: Removed dispatch of purchases updated event on finish purchase, replaced with success event
    Android: Added null pointer checks during consume purchase process and handled results (#306)

    2020.03.24 [v10.0.038]

    Android X migration (resolves #300)

    2020.01.18 [v9.1.034]

    Updated default library functions to match release (#290)

    2019.10.24 [v9.1.026]

    Android: Added check for extension context state when dispatching events (#268)

    2019.10.18 [v9.1.025]

    iOS: Application Receipt added all fields to originalMessage Purchase field (#267)

    2019.10.11 [v9.1.024]

    Corrected documentation

    2019.10.11 [v9.1.024]

    iOS: Added discounts and offers (resolves #233)

    2019.09.19 [v9.0.009]

    Android: Critical fix for crash in getPurchases call (resolves #261)

    2019.09.09 [v9.0.007]

    Android 64bit update (resolves #247)
    Removed products requirement from getPurchases, finishPurchase and consumePurchase functions (resolves #248)

    2019.04.18 [v8.0.064]

    Amazon InApp Purchasing integration (alpha) (#231)
    Added additional variants to better handle development cases
    Corrected missing method from default lib (#235)

    2019.03.27 [v7.0.042]

    Corrected getPurchases call for Play Billing (resolves #230)

    2019.03.20 [v7.0.033]

    Added applicationUsername implementation for Android (#229)

    2019.03.03 [v7.0.032]

    Complete rewrite of Android Play Store integration to latest API (closes #215)
    - Added upgrade / downgrade ability to change subscriptions (resolves #56)
    - Resolves crashes (resolves #171)
    - Fixes transaction identifiers (resolves #127)
    - Should correct template issues (#203)
    Embedded iOS bitcode

    2019.02.22 [v6.4.119]

    iOS: Added additional checks to product information (#221)
    Updated minimum iOS version to 8.0 (#222)

    2018.10.22 [v6.3.118]

    iOS: Corrected handling of error in getProducts call (resolves #204)

    2018.10.10 [v6.3.113]

    iOS getPurchases integration using AppReceipt Validation

    2018.08.17 [v6.2.107]

    Added tvOS platform support (resolves #123)

    2018.08.15 [v6.1.102]

    Corrected @available packaging issue on Windows machines (resolves #191)

    2018.08.01 [v6.1.098]

    Corrected size of ANE (#189)

    2018.07.31 [v6.1.096]

    Resolved issue with calling setup after failure (resolves #189)

    2018.01.19 [v6.1.079]

    Android: Corrected issue returning wrong response when already owned item (resolves #130)

    2017.12.19 [v6.1.076]

    iOS: Corrected minor issue with multiple simultaneous finish purchase calls
    iOS: Improved compatibility with other ANEs and the startup process (resolves #135)
    Updated User Cancellation docs (resolves #153)
    Corrected default lib function signatures

    2017.12.19 [v6.1.076]

    iOS: Corrected minor issue with multiple simultaneous finish purchase calls
    iOS: Improved compatibility with other ANEs and the startup process (resolves #135)
    Updated User Cancellation docs (resolves #153)
    Corrected default lib function signatures

    2017.10.03 [v6.0.062]

    Latest release including iOS 11 Promotions and Android updates

    2017.07.25 [v5.0.017]

    Added checks for null reference and correctly handled error (resolves #151)

    2017.07.10 [v5.0.016]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.07.01 [v5.0.015]

    Added getPurchases to retrieve purchases (resolves #36, resolves #131, resolves #142, resolves #61)
    Added subscription product handling
    Deprecated Purchase events to use PURCHASES_UPDATED main handler (resolves #115)
    Android: Corrected response from test transactions (resolves #132)
    Android: Added message to purchase cancelled event (resolves #130)
    Android: Updated IabHelper (resolves #129, resolves #126, resolves #122, resolves #145, resolves #137)
    Android: Moved to better activity handling (resolves #128)
    Android: Resolved slow isSupported call (resolves #138)
    Added ErrorCodes constants (resolves #10, resolves #141)
    Updated documentation

    2016.12.31 [v4.7.005]

    New documentation

    2016.12.01 [v4.7.002]

    Android: Implemented clear products with the getProducts function

    2016.06.04

    Android: Corrected link for product view (#105)

    2016.03.16

    Android: Fixed error when multiple consumes occur, now dispatches failed event (#90)
    Android: Fixed issue with odd characters in product description (resolves #95)

    2016.01.12

    iOS: Changed order of product loaded and invalid events
    Added a canMakePayments function to check if restrictions are enabled (resolves #82)

    2015.08.13

    Clean build to check default SWC (#52)

    2015.08.12

    Added swc to lib (#52)

    2015.07.23

    Added documentation of events dispatched from function calls (resolves #46)
    Added option to add products when calling getProducts rather than clearing the list each call (resolves #45)
    Android: Improved handling of package names in init call

    2015.06.30

    Android: Corrected issue with makePurchase not working after a call to restorePurchases (#40)

    2015.06.29

    Corrected the default library consumePurchase function to match the native library (resolves #42)

    2015.06.27

    iOS: Corrected events firing twice (on update and removed) (resolves #37)

    2015.06.19

    iOS: Added getPendingPurchases to allow access to purchases that are in progress
    iOS: Added a check of pending purchases when a call to makePurchase is made to ensure there are no pending purchases for the product (#26)
    Removed debug code from AS lib

    2015.06.12

    Android: Changed 'price' value on a product to be consistent with iOS (resolves #32)
    Android: Windows: Fix for bug in AIR packager resulting in missing resources

    2015.06.10

    Android: Corrected JSON format on cancelled event (#27)
    iOS: Corrected restored transaction receipt

    2015.05.07

    iOS: Corrected finishPurchase on a failed transaction, was incorrectly failing to find transaction (#25)

    2015.04.16

    Added changelog for front end site

    2015.04.16

    Updated documentation
    Android: Corrected product details (resolves #16)

    2015.04.15

    Completely rewriten example application using Starling

    Separated finishing a purchase into a separate call
    Separated PURCHASE_* events into separate class
    Introduced the PurchaseRequest object to initiate calls (resolves #15)
    Introduced the Product View for native product UI
    Added the currency code to the returned product details (resolves #5)

    iOS: Updated to include new receipt data using the appStoreReceiptUrl
    iOS: Added access to the application receipt (for iOS 7+) including refresh functionality (resolves #20)
    iOS: Added the applicationUsername on purchase requests as optional added security measure
    iOS: Updated to the new restorePurchases method

    Android: x86 support (resolves #19)
    Android: Fixed null pointer exception (resolves #12)
    Android: Patch for querying more than 20 items (resolves #6)

    2015.02.02

    Added check for .debug suffix in application id

    2014.12.20

    iOS: Included arm64 support (resolves #3) 
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.05

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    Updated README

    2014.12.01

    New application based key check, removing server checks

    2014.11.25

    Corrected missing default library definitions (resolves #292)
    - + \ No newline at end of file diff --git a/docs/inappbilling/consuming-purchases/index.html b/docs/inappbilling/consuming-purchases/index.html index 7339a180bc7..4ab9646a2d1 100644 --- a/docs/inappbilling/consuming-purchases/index.html +++ b/docs/inappbilling/consuming-purchases/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ for example, health points or coins in a game.

    Consuming an item involves calling the consumePurchase function with a product request containing the product id to consume.

    If you consider a product to be a consumable you should implement this process either when your user uses the product or you can call it as soon as you deliver the product to the user.

    // The service must be setup and a list of products retrieved.

    // Make sure you have the following listeners
    InAppBilling.service.addEventListener( InAppBillingEvent.CONSUME_SUCCESS, consumePurchase_successHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.CONSUME_FAILED, consumePurchase_failedHandler );

    InAppBilling.service.consumePurchase( new Purchase( productId ) );


    function consumePurchase_successHandler( event:InAppBillingEvent ):void
    {
    trace( "consume success" );
    }

    function consumePurchase_failedHandler( event:InAppBillingEvent ):void
    {
    trace( "consume failed" );
    }
    Note

    You must have completed the purchase by calling finishPurchase() before attempting to consume a purchase.

    - + \ No newline at end of file diff --git a/docs/inappbilling/get-purchases/index.html b/docs/inappbilling/get-purchases/index.html index 63b5ceb6e00..15573a29c49 100644 --- a/docs/inappbilling/get-purchases/index.html +++ b/docs/inappbilling/get-purchases/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Get Purchases

    On services where you can directly query the service for user purchases you can call the getPurchases() function to retrieve them directly from the service.

    info

    This is not supported on services like Apple's InAppPurchases where the only method of retrieving purchases is through a user initiated restore purchases process or via a server. See Restore Purchases for more on user initiated purchases restoring.

    There is an exception to this, in the situation where you are using the application receipt variant of the extension. In that variant this functionality will extract all the purchase information from the "application receipt" by decoding the receipt locally on the device.

    To query the purchases, simply call getPurchases and wait for one of the following events:

    • PurchaseEvent.GET_PURCHASES_COMPLETE: Dispatched when the purchases have been retrieved successfully
    • PurchaseEvent.GET_PURCHASES_FAILED: Dispatched when there was an error

    If the call is not supported it will return false.

    You can also check the isGetPurchasesSupported flag to determine if the functionality is supported on the current service.

    For example:

    if (InAppBilling.service.isGetPurchasesSupported)
    {
    InAppBilling.service.addEventListener( PurchaseEvent.GET_PURCHASES_COMPLETE, getPurchasesCompleteHandler );
    InAppBilling.service.addEventListener( PurchaseEvent.GET_PURCHASES_FAILED, getPurchasesFailedHandler );

    InAppBilling.service.getPurchases();
    }
    else
    {
    // Not supported - you should use restore purchases and track purchases in your app
    }

    function getPurchasesCompleteHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.data)
    {
    processPurchase( purchase );
    }
    }

    function getPurchasesFailedHandler( event:PurchaseEvent ):void
    {
    // getPurchases failed
    }

    During your processPurchase implementation you should be sure to check the purchase.transactionState. Only purchases in the state Purchase.STATE_PURCHASED should be delivered to your user. You may find there are deferred states on some platforms.

    // Check the purchase state
    if (purchase.transactionState == Purchase.STATE_PURCHASED)
    {
    // Deliver product to user
    }

    Application Receipt Variant

    A small note for the iOS application receipt variant. This variant uses the "application receipt" which is encoded data provided by the App Store for your application. There are certain circumstances where it may be out-of-date or not available, eg initial install on the iOS simulator.

    When it is not available get purchases will fail.

    It will be updated any time you interact with the App Store, eg via making a purchase or restoring purchases, or you can manually refresh it using the InAppBilling.service.applicationReceipt.refresh() method.

    If you wish you can manually decode the receipt for more information. Access it via InAppBilling.service.applicationReceipt.getAppReceipt().

    Decoding this receipt is beyond the scope of our support.

    See Application Receipt for more information.

    - + \ No newline at end of file diff --git a/docs/inappbilling/google/google-play-inapp-billing/index.html b/docs/inappbilling/google/google-play-inapp-billing/index.html index a618d423d48..ed75920a41a 100644 --- a/docs/inappbilling/google/google-play-inapp-billing/index.html +++ b/docs/inappbilling/google/google-play-inapp-billing/index.html @@ -13,7 +13,7 @@ - + @@ -40,7 +40,7 @@ contain the user's ID in cleartext. We recommend that you use a one-way hash to generate a string from the user's ID and store the hashed string in this field.

    For added security, you should perform the checking on your own secure server. Make sure to verify that the orderId is a unique value that you have not previously processed.

    - + \ No newline at end of file diff --git a/docs/inappbilling/google/testing/index.html b/docs/inappbilling/google/testing/index.html index 4848dc4db9b..1a8a4c44b38 100644 --- a/docs/inappbilling/google/testing/index.html +++ b/docs/inappbilling/google/testing/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Testing Google Play Billing

    In order to test Google Play Billing you simply need to add an apk to a test channel and sign in to a device using a user who has signed up for this channel.

    A couple of notes:

    • Ensure you have completed the setup of your products, they must have been through review before they will appear correctly;
    • Ensure you have uploaded and have pushed to a test channel at least one apk of with the billing permission in the manifest;
    • Ensure your user has completely signed up for the beta, they need to be added to a test user group and then actually join the test channel (generally through a link);
    - + \ No newline at end of file diff --git a/docs/inappbilling/huawei/add-the-extension/index.html b/docs/inappbilling/huawei/add-the-extension/index.html index 92fe1a0f563..5090096ed1b 100644 --- a/docs/inappbilling/huawei/add-the-extension/index.html +++ b/docs/inappbilling/huawei/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Huawei AppGallery In-App Purchases

    About

    Huawei AppGallery is Huawei official Android Application store.

    Huawei In-App Purchases (IAP) aggregates multiple payment methods for global payments, and can be easily integrated into your app to help you increase revenue. Using IAP, you can sell a variety of products or services, including digital goods and subscriptions, directly within your app.

    Google

    Huawei devices use a variant of Android. Some may include both Google Play and the Huawei AppGallery so you may need to support both.

    This section describes how to setup your AIR application to use Huawei In-App Purchases with this extension.

    Install

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the package by running:

    apm install com.distriqt.InAppBilling-AppGallery

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ assets
    | |____ android
    | | |____ grs_sdk_global_route_config_apptouchupdatesdk.json
    | | |____ grs_sdk_global_route_config_hmscoreInstallerSDK.json
    | | |____ grs_sdk_global_route_config_opensdkService.json
    | | |____ grs_sdk_global_route_config_updatesdk.json
    | | |____ grs_sdk_server_config.json
    | | |____ grs_sp.bks
    | | |____ hmsincas.bks
    | | |____ hmsrootcas.bks
    |____ ane
    | |____ com.distriqt.InAppBilling.AppGallery.ane # InAppBilling Huawei extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

    • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/android folder to the root of your Android application package. (It contains a series of files that Huawei services require to correctly operate). You do not need to add this to your iOS application package.

      These assets are required by the Huawei SDK and if not included an error will be dispatched when calling setup().

    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    caution

    Only install one variant of an package. The base variant is installed when no variant is specified and cannot be included alongside another variant. You will likely get an error if you attempt to install multiple variants with apm

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (InAppBilling.isSupported)
    {
    // Functionality here
    }
    note

    This only checks if there is some functionality supported, not whether a particular billing service is available.

    - + \ No newline at end of file diff --git a/docs/inappbilling/huawei/huawei-appgallery/index.html b/docs/inappbilling/huawei/huawei-appgallery/index.html index 34ffc2b0365..a1dcde7f4b2 100644 --- a/docs/inappbilling/huawei/huawei-appgallery/index.html +++ b/docs/inappbilling/huawei/huawei-appgallery/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Huawei AppGallery

    The following outlines the steps required to enable AppGallery in app purchases in your application.

    Signing Certificate Fingerprint

    A signing certificate fingerprint is used to verify the authenticity of an app when it attempts to access HMS Core (APK) through the HMS SDK. Before using HMS Core (APK), you must locally generate a signing certificate fingerprint and configure it in AppGallery Connect.

    Generate

    The following command retrieves the signature for the specified certificate and password. Replace the path and password to match your certificate.

    You will need the "SHA-256" fingerprint for Huawei services.

    macOS:

    keytool -exportcert -keystore PATH_TO_CERTIFICATE.p12 -storepass PASSWORD -list -v -storetype PKCS12

    windows:

    keytool.exe -exportcert -keystore PATH_TO_CERTIFICATE.p12 -storepass PASSWORD -list -v -storetype PKCS12

    The keytool program will be located in the bin folder of your JDK installation. Generally this should be available in your path.

    Configure

    • Sign in to AppGallery Connect and select My projects.
    • Find your project from the project list and click the app on the project card.
    • On the Project Setting page, set SHA-256 certificate fingerprint to the SHA-256 fingerprint.

    Enable Services

    • Sign in to AppGallery Connect and select My projects.
    • Find your project from the project list and click the app for which you need to enable a service on the project card.
    • Click the Manage APIs tab and toggle the "In-App Purchases" switch

    AppGallery Connect Configuration File

    • Sign in to AppGallery Connect and select My projects.
    • Find your project from the project list and click the app.

    • Go to Project settings > App information.
    • Click agconnect-services.json to download the configuration file.

    • Add agconnect-services.json to the root of your application and ensure it is packaged.
    danger

    You must make sure the agconnect-services.json is packaged at the root of your application otherwise you will find the service will unexpectedly fail.

    Setting up a Billing Service

    The following is in addition to the documentation in Setting up a Billing Service.

    When setting up your service you will need to specify the InAppBillingServiceTypes.HUAWEI_APP_GALLERY service type and provide your Huawei AppGallery Public key. The public key is used to verify purchases to provide a level of fraud protection:

    var service:BillingService = new BillingService( InAppBillingServiceTypes.HUAWEI_APP_GALLERY )
    .setHuaweiIAPPublicKey( HUAWEI_APPGALLERY_INAPP_PUBLIC_KEY );

    var success:Boolean = InAppBilling.service.setup( service );

    You should wait for the InAppBillingEvent.SETUP_SUCCESS event to ensure the AppGallery is correctly initialised and available on the device.

    - + \ No newline at end of file diff --git a/docs/inappbilling/huawei/testing/index.html b/docs/inappbilling/huawei/testing/index.html index bc5e5a74047..ce437ae1ab9 100644 --- a/docs/inappbilling/huawei/testing/index.html +++ b/docs/inappbilling/huawei/testing/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Testing Huawei AppGallery

    Huawei AppGallery In-App Purchases

    https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/iap-sandbox-testing-v4

    Set Installer Package

    In order to correctly detect that the app was installed via the Huawei AppGallery you must set the installer package when installing your debug application. This is done normally by the App Gallery.

    When installing your application you will need to use the following commands using the adb terminal command:

    adb push YOURAPP.apk /data/local/tmp/app.apk
    adb shell pm install -i "com.huawei.appmarket" -r /data/local/tmp/app.apk
    adb shell rm /data/local/tmp/app.apk

    Change YOURAPP.apk to be the path to your application. This command will set the installer package name to be the Huawei AppGallery's package name com.huawei.appmarket.

    If you don't set this and rely on the default detection then you will find debugging may default to the Google Play Billing implementation.

    - + \ No newline at end of file diff --git a/docs/inappbilling/in-app-updates/index.html b/docs/inappbilling/in-app-updates/index.html index 5676db5abcf..bff4fddb336 100644 --- a/docs/inappbilling/in-app-updates/index.html +++ b/docs/inappbilling/in-app-updates/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    In App Updates

    In-App Updates is a method for your application to check with the store as to whether there is a newer version of your application available. Although some users enable background updates when their device is connected to an unmetered connection, other users may need to be reminded to update.

    This feature allows you to check and prompt active users to update your app.

    Additional Requirements

    There may be some additional requirements here depending on how you installed the extension.

    Nothing additional required if using apm.

    Usage

    Check if supported

    Only certain services support In-App Updates:

    • Google Play
    • Huawei AppGallery

    You can use the isSupported flag to check whether the current device and service supported In App Updates:

    if (InAppBilling.service.inAppUpdates.isSupported)
    {
    // In-App Updates are supported
    }

    Check for an update

    To check for an update, call checkAppUpdate() and await one of the events:

    • InAppUpdatesEvent.CHECK_APP_UPDATES_SUCCESS: dispatched when the check was completed successfully
    • InAppUpdatesEvent.CHECK_APP_UPDATES_FAILED: dispatched if there was an error performing the check.
    InAppBilling.service.inAppUpdates.addEventListener( InAppUpdatesEvent.CHECK_APP_UPDATES_SUCCESS, successHandler );
    InAppBilling.service.inAppUpdates.addEventListener( InAppUpdatesEvent.CHECK_APP_UPDATES_FAILED, failedHandler );

    InAppBilling.service.inAppUpdates.checkAppUpdate();

    If successful you can use the details in the event to determine if there is an update available:

    function successHandler( event:InAppUpdatesEvent ):void
    {
    if (event.updateAvailability == InAppUpdateAvailablity.UPDATE_AVAILABLE)
    {
    // An update is available
    trace( "info: " + (event.updateInfo == null ? "null" : event.updateInfo.toString()) );
    }
    else
    {
    // No update available
    }
    }

    If an error occurred you can use the errorCode and message fields to understand the issue:

    function checkAppUpdates_failedHandler( event:InAppUpdatesEvent ):void
    {
    trace( "errorCode: " + event.errorCode );
    trace( "message: " + event.message );
    }

    Start an update

    If there is an update available, you can start the in app update process by calling startAppUpdate():

    InAppBilling.service.inAppUpdates.startAppUpdate();

    Testing

    Google Play

    With internal app sharing, you can quickly share an app bundle or APK with your internal team and testers by uploading the app bundle you want to test to the Play Console.

    You can also use internal app sharing to test in-app updates, as follows:

    1. On your test device, make sure you've already installed a version of your app that meets the following requirements:
    • The app was installed using an internal app sharing URL
    • Supports in-app updates
    • Uses a version code that's lower than the updated version of your app
    1. Follow the Play Console instructions on how to share your app internally. Make sure you upload a version of your app that uses a version code that's higher than the one you have already installed on the test device.

    2. On the test device, only click the internal app-sharing link for the updated version of your app. Do not install the app from the Google Play Store page you see after clicking the link.

    3. Open the app from the device's app drawer or home screen. The update should now be available to your app, and you can test your implementation of in-app updates.

    - + \ No newline at end of file diff --git a/docs/inappbilling/index.html b/docs/inappbilling/index.html index 57423cf1fcd..1aa2c8f1633 100644 --- a/docs/inappbilling/index.html +++ b/docs/inappbilling/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ provides functionality to purchase items from stores through your application.

    Identical code base can be used across all supported platforms allowing you to concentrate on your application and not device specifics.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    More information here:

    com.distriqt.InAppBilling

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/inappbilling/introductory-prices/index.html b/docs/inappbilling/introductory-prices/index.html index 0cfe596b46e..df5d4057e4e 100644 --- a/docs/inappbilling/introductory-prices/index.html +++ b/docs/inappbilling/introductory-prices/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Introductory Prices

    Offer introductory pricing for auto-renewable subscriptions to eligible users.

    Available through Google Play Billing and Apple In-App Purchases

    Apps with auto-renewable subscriptions can offer a discounted introductory price, including a free trial, to eligible users. You can make introductory offers to customers who haven’t previously received an introductory offer for the given product, or for any products in the same subscription group.

    • Free trial period: An amount of time during which a user may access a subscription without being billed. A free trial period is a way to entice users to try your subscription before committing to purchase it.

    • Introductory price: The price of the subscription over a certain number of initial, "introductory" billing periods. Introductory price is a way to entice users to try your subscription while simultaneously gaining some revenue. The Introductory price must be less than the subscription's normal price.

    Start by setting up introductory offers in App Store Connect or the Google Play Console.

    The process then follows:

    • Retrieving subscription offers
    • Determine eligibility
    • Display the offer
    • Make Purchase

    On iOS you will need to determine if the user is eligible to receive an introductory offer. When the app queries the App Store for a list of available products, display the introductory pricing if the user is eligible to receive them.

    Before you can display introductory offers and free trials in your app, you must first configure the offers in App Store Connect and the Google Play Console.

    Introductory Prices and Free trials are implemented as a Subscription Offer on a subscription product. You will follow the same approach as a normal offer to purchase and display these.

    See Subscription Offers for more information.

    - + \ No newline at end of file diff --git a/docs/inappbilling/make-a-purchase/index.html b/docs/inappbilling/make-a-purchase/index.html index 8858eeca615..f37154d0729 100644 --- a/docs/inappbilling/make-a-purchase/index.html +++ b/docs/inappbilling/make-a-purchase/index.html @@ -13,7 +13,7 @@ - + @@ -37,7 +37,7 @@ for example, if you wish to validate the purchase using the transaction receipt with your application server.

    // The service must be setup and a list of products retrieved.

    InAppBilling.service.addEventListener( PurchaseEvent.PURCHASES_UPDATED, purchases_updatedHandler );
    InAppBilling.service.addEventListener( PurchaseEvent.PURCHASE_FAILED, purchase_failedHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.FINISH_SUCCESS, finishPurchase_successHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.FINISH_FAILED, finishPurchase_failedHandler );


    var request:PurchaseRequest = new PurchaseRequest();
    request.productId = productId;
    request.quantity = 1;

    var success:Boolean = InAppBilling.service.makePurchase( request );

    trace( "makePurchase( "+productId+" ) = " + success );



    //
    // PURCHASE HANDLER
    //

    function purchases_updatedHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.data)
    {
    switch (purchase.transactionState)
    {
    // These transactions are in progress, so don't finish them unless you don't want them to complete
    case Purchase.STATE_PURCHASING:
    case Purchase.STATE_DEFERRED:
    break;

    // The purchased state should finished after you have delivered the product if applicable
    case Purchase.STATE_PURCHASED:
    {
    trace( "purchase success" );

    //
    // If you wish you can add the purchase to your inventory
    // and finish the purchase here
    addPurchaseToInventory( purchase );
    InAppBilling.service.finishPurchase( purchase );

    //
    // Alternatively hold onto this purchase so we can call
    // finish when you've delivered the product
    //
    // You would do this if you are validating the purchase on a server or
    // other operation that is required to complete before the product is delivered
    //_purchases.push( purchase );
    break;
    }


    // For all other states you should handle appropriately and call finish purchase
    case Purchase.STATE_FAILED:
    case Purchase.STATE_REFUNDED:
    case Purchase.STATE_RESTORED:
    case Purchase.STATE_REMOVED:
    case Purchase.STATE_CANCELLED:
    case Purchase.STATE_NOTALLOWED:
    InAppBilling.service.finishPurchase( purchase );
    break;
    }
    }
    }

    function purchase_failedHandler( event:PurchaseEvent ):void
    {
    // This transaction failed so you should notify your user and finish the purchase
    log( "purchase failed [" + event.errorCode + "] :: "+ event.message );
    if (event.data && event.data.length > 0)
    {
    InAppBilling.service.finishPurchase( event.data[0] );
    }

    //
    // Android may return this code if the item is already owned
    //
    if (event.errorCode == ErrorCodes.ITEM_ALREADY_OWNED)
    {
    // You should use getPurchases() to retrieve the users purchases
    // and then add them as missing from their current inventory
    InAppBilling.service.getPurchases();
    }

    }

    function finishPurchase_successHandler( event:InAppBillingEvent ):void
    {
    trace( "finish purchase complete" );
    }

    function finishPurchase_failedHandler( event:InAppBillingEvent ):void
    {
    trace( "finish failed: ["+event.errorCode+"]" + event.message );
    }


    Handling User Cancellations

    When a user cancels a purchase there are two avenues that you'll need to handle, due to the different ways that Android and iOS handle these cases.

    On iOS there will be a Purchase initiated immediately so when the user cancels the purchase you will receive a PurchaseEvent.PURCHASES_UPDATED and the purchases transaction state will be set to Purchase.STATE_CANCELLED. You will need to handle this case in your purchases updated handler and finish the purchase to remove it from the pending purchases queue.

    For example:

    function purchases_updatedHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.data)
    {
    switch (purchase.transactionState)
    {
    // Other states ...

    case Purchase.STATE_CANCELLED:
    // User Cancelled
    InAppBilling.service.finishPurchase( purchase );
    break;
    }
    }
    }

    On Android the purchase is not initiated so there is no Purchase to return, hence you will not receive a purchases updated event but instead a PurchaseEvent.PURCHASE_FAILED event will be dispatched. The error code on the failed event will be set to ErrorCodes.USER_CANCELLED or ErrorCodes.RESPONSE_CANCELLED so you can use this code to process the user cancellation. As this purchase was not initiated it does not need to be finished and will not appear in the pending purchases queue.

    For example:

    function purchase_failedHandler( event:PurchaseEvent ):void
    {
    switch (event.errorCode)
    {
    // Other error codes...

    case ErrorCodes.RESPONSE_CANCELLED:
    case ErrorCodes.USER_CANCELLED:
    // User cancelled
    break;
    }
    }

    You should ensure you handle both these cases in your application if you wish to handle user cancellations.


    Deferred Purchases

    Of special note are deferred purchases. Deferred purchases are purchases that are in progress and require further user action external to your application, such as a parental approval or payment in cash at a physical store.

    With Apple's In-App Purhcases:

    The transaction is in the queue, but its final status is pending external action such as Ask to Buy. Update your UI to show the deferred state, and wait for another callback that indicates the final status.

    With Google Play Billing the deferred state is equivalent to the "PENDING" purchase state where additional action is required before granting entitlement.

    For example, a user might choose to purchase your in-app product at a physical store using cash. This means that the transaction is completed outside of your app. In this scenario, you should grant entitlement only after the user has completed the transaction.

    In order to correctly handle deferred purchases you should not finish the purchase, but leave it in the queue until the user completes the external action.

    Once the user completes the action you will receive a purchases updated event and should process the purchase at that point. It is important however if you display some "purchase in progress" UI during the making a purchase process that you close that once you receive this event. You may wish to display a message appropriate to your application indicating that they need to take action outside the app.

    function purchases_updatedHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.data)
    {
    switch (purchase.transactionState)
    {
    // Do nothing with the deferred purchase. Ensure you close any "purchase in progress" UI
    case Purchase.STATE_DEFERRED:
    break;

    ...
    - + \ No newline at end of file diff --git a/docs/inappbilling/migration-v14/index.html b/docs/inappbilling/migration-v14/index.html index 5adf114e842..1a77cb70c7b 100644 --- a/docs/inappbilling/migration-v14/index.html +++ b/docs/inappbilling/migration-v14/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migration v14

    Version 14.0

    Version 14 implemented Google Play Billing client library v5.0.0

    This brings some major changes to subscriptions and some breaking API changes that you will need to update your application to manage.

    Subscription Offers

    Instead of "discounts" we have moved to the newer concept of "offers" to represent the different ways of purchasing a subscription. Offers allow much more flexibility in the ways you can allow your customers to purchase your subscriptions.

    Every subscription product now has at least one subscription offer associated with it. Each offer sets out different pricing phases for a subscription. Eg there may be one offer with a free introductory trial period followed by a recurring monthly subscription. The offer contains one or more subscription phases that has the cost and period information for different phases of the subscription.

    When purchasing as subscription you must now provide the subscription offer you wish to present to the user.

    var subscription:Product = ...;

    // You can either have some logic, or allow the user to select.
    // If you only have one offer for your subscriptions you can just use the first available

    var offer:SubscriptionOffer = subscription.subscriptionOffers[0];

    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( sub.id )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    );

    InAppBilling.service.makePurchase( request );

    To migrate it will depend if you were previously using product discounts (ProductDiscount) in your application to provide promotional discounts, free trials or introductory periods.

    Not using discounts

    If you haven't setup subscription offers on Google Play and aren't using any promotional discounts on iOS then to migrate to the new approach is to simply find the first offer in the subscription and supply that in the offer request.

    var offer:SubscriptionOffer = product.subscriptionOffers[0];

    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( sub.id )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    );

    InAppBilling.service.makePurchase( request );

    You need to do this on all platforms and services and we internally

    As you investigate offers you may wish to expand this, but this is a simple way to move to the latest subscription purchase approach.

    Using discounts

    If in the past you have used discounts and the ProductDiscount class then you will need to completely migrate to the new SubscriptionOffer approach.

    Check the documentation on Subscription Offers for more information.

    - + \ No newline at end of file diff --git a/docs/inappbilling/migration-v15/index.html b/docs/inappbilling/migration-v15/index.html index c24a0c75f20..da3649d4f40 100644 --- a/docs/inappbilling/migration-v15/index.html +++ b/docs/inappbilling/migration-v15/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migration v15

    Version 15.0

    Version 15 implemented Google Play Billing client library v6.0.0.

    Android only

    These changes only apply to Android and Google Play

    apm

    If you are using apm then all these changes will be handled for you. This only applies if you are manually updating your manifest additions.

    Firstly you will need to update the billing client version in your manifest additions:

    <meta-data android:name="com.google.android.play.billingclient.version" android:value="6.0.0" />

    Secondly add the following to your queries section:

    <intent>
    <action android:name="com.android.vending.billing.InAppBillingService.BIND" />
    </intent>

    You manifest should now contain all the following:

    <manifest android:installLocation="auto">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.android.vending.BILLING" />

    <queries>
    <intent>
    <action android:name="com.android.vending.billing.InAppBillingService.BIND" />
    </intent>
    </queries>

    <application>

    <activity
    android:name="com.distriqt.extension.inappbilling.activities.ProductViewActivity"
    android:exported="false"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />


    <!-- GOOGLE PLAY BILLING -->
    <meta-data android:name="com.google.android.play.billingclient.version" android:value="6.0.0" />
    <activity
    android:name="com.android.billingclient.api.ProxyBillingActivity"
    android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
    android:exported="false"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />


    </application>

    </manifest>
    - + \ No newline at end of file diff --git a/docs/inappbilling/migration/index.html b/docs/inappbilling/migration/index.html index c3ec9d5ecc2..35997a440f7 100644 --- a/docs/inappbilling/migration/index.html +++ b/docs/inappbilling/migration/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migration (v12 and below)

    Version 12.0

    Version 12 implemented Google Play Billing client library v3.0

    This brings some breaking changes to the developer payload, which is no longer supported! Any metadata that you wish to store about a purchase must now be done on a secure backend server that you maintain. You should associate this data with the purchase token (transactionIdentifier).

    To ensure metadata is associated in the case of purchase flow interruptions, Google recommends storing the metadata on your backend server prior to launching the purchase dialog and associating it with your user’s account ID, the SKU being purchased, and the current timestamp.

    You will still be able to retrieve developer payloads attached to purchases made with previous versions of the library.

    Manifest Additions

    Make sure you add the following to your application node in your android manifest additions:

    <meta-data android:name="com.google.android.play.billingclient.version" android:value="3.0.0" />

    Check Add the Extension for more information.

    In-App Updates

    If you are looking to add In-App Updates make sure you add the additional extensions and manifest additions as outlined in the documentation


    Version 8.0

    Version 8 implements the pending purchases and acknowledgement functionality for Google Play Billing that has been recently added, along with the re-implementation of the developer payload.

    Google Play Acknowledging Purchases

    Google Play supports purchasing products from inside of your app (in-app) or outside of your app (out-of-app). In order for Google Play to ensure a consistent purchase experience regardless of where the user purchases your product, you must acknowledge all purchases received through the Google Play Billing Library as soon as possible after granting entitlement to the user. If you do not acknowledge a purchase within three days, the user automatically receives a refund, and Google Play revokes the purchase.

    Purchases that have been completed but not yet acknowledged will be placed into a pending state and be available through the getPendingPurchases() method.

    In order to acknowledge that the purchase has been delivered to the user you call finishPurchase() on any purchases that are pending. We have implemented the acknowledge call in the finishPurchase() method as this should closely resemble the process of how you finish a purchase on iOS.

    These purchases will now be returned by the getPendingPurchases() method as well as the getPurchases() method.

    If you have an iOS version of your application already finishing purchases then that logic should remain the same.

    Google Play Pending Purchases

    Android's "Pending Purchases" are slightly different from the concept on iOS. On Android pending purchases are purchases that have not yet been made and have only been initiated, whereas on iOS pending purchases are completed awaiting the developer confirmation (i.e. finishPurchase() call).

    Google Play Billing uses this concept as a deferred payment state.

    For example, a user might choose to purchase your in-app product at a physical store using cash. This means that the transaction is completed outside of your app. In this scenario, you should grant entitlement only after the user has completed the transaction.

    For pending transactions (new in version 2.0), the three-day window (for acknowledging the purchase) starts when the purchase has moved to the SUCCESS state and does not apply while the purchase is in a PENDING state.

    To better match the concepts across Apple's In App Purchases and Google Play Billing, we represent Android Pending Purchases as Deferred Purchases, ie. a purchase will have the state STATE_DEFERRED.

    A deferred purchase means that it has been initiated and is awaiting a further process before it can continue, eg parental approval. We believe this closely matches the Android concept and the logic implemented in your application should already handle this case. The deferred state is really just informing you that the purchase UI process has completed with the user selecting a method that will complete at a later time.

    Note: Android Pending Purchases are not returned through the getPendingPurchases() call. Instead you should call getPurchases() and check for any purchases in the Purchase.STATE_DEFERRED state.

    You may need to update any logic that delivers products through the getPurchases() call. Previously you could have assumed that every purchase returned through getPurchases() was a product available to the user. You should now ensure you check the state of the purchase is STATE_PURCHASED before delivering a product:

    if (InAppBilling.service.isGetPurchasesSupported)
    {
    InAppBilling.service.addEventListener( PurchaseEvent.GET_PURCHASES_COMPLETE, getPurchasesCompleteHandler );
    InAppBilling.service.addEventListener( PurchaseEvent.GET_PURCHASES_FAILED, getPurchasesFailedHandler );

    var success:Boolean = InAppBilling.service.getPurchases();
    }


    function getPurchasesCompleteHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.data)
    {
    // Check the purchase state
    if (purchase.transactionState == Purchase.STATE_PURCHASED)
    {
    // Deliver product to user
    }
    }
    }

    Google Play Developer Payload

    The developer payload has been re-introduced in this version however it is different from using it in the past. It is now only attached when you acknowledge a purchase, rather than when it is initiated.

    You can attach a developer payload parameter to a purchase, but only when the purchase is acknowledged or consumed. This is unlike developer payload in the past, where the payload could be specified when launching the purchase flow. Because purchases can now be initiated from outside of your app, this change ensures that you always have an opportunity to add a payload to purchases.

    So to attach a developer payload you need to set the payload on a purchase when calling finishPurchase():

    purchase.developerPayload = "some_payload";

    InAppBilling.service.finishPurchase( purchase );

    This payload will now be returned in getPurchases() and other purchase related events.

    API changes

    We have changed the signature of the consume purchase API to better match other parts of the API. It now takes a Purchase parameter rather than the PurchaseRequest.

    This should be a simple change. Existing code using a request:

    var request:PurchaseRequest = var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( purchase.productId );

    var success:Boolean = InAppBilling.service.consumePurchase( request );

    becomes:

    var success:Boolean = InAppBilling.service.consumePurchase( purchase );

    or if you don't have a reference to the Purchase you can just use the product id:

    var success:Boolean = InAppBilling.service.consumePurchaseByProductId( productId );
    - + \ No newline at end of file diff --git a/docs/inappbilling/overview/index.html b/docs/inappbilling/overview/index.html index c46e0c9733d..60a74ec0b3b 100644 --- a/docs/inappbilling/overview/index.html +++ b/docs/inappbilling/overview/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Overview

    Implementing in-app billing / purchases can be a daunting task. There are several steps that you must go through.

    Here we will provide an overview of the process as way of introduction to the concepts in this extension. This assumes you have already been through the configuration of the service through the appropriate store console, and is focussed on the extension functionality you will be accessing.

    Setup

    Firstly you must always call setup() and specify a BillingService to use. The billing service specifies which app store you are intending to use and any details about that store, such as license keys for purchase verification.

    Products

    After setup you must retrieve a list of products. This does several things, firstly it informs the extension of the product and subscription identifiers and, secondly, it retrieves product information (price etc) from the store. Additionally any invalid identifiers will be detected including any products that may not be setup correctly.

    Once you have completed this step you are ready to access purchases.

    Making Purchases

    Next you will likely want to make a purchase.

    Making a purchase consists of several components

    • making a purchase request;
    • handling changes in a purchase state with the purchases updated events;
    • verifying a completed purchase with a server (optional);
    • delivering the product;
    • finishing the purchase;

    Once a purchase is "finished" the purchase is acknowledged as being delivered to the user, any managed stores will hold onto this purchase for the user and return information about it as required.

    Consuming Purchases

    If the purchase is for a consumable product (i.e. one that can be purchased multiple times), you must consume the purchase before attempting to purchase the product again. This should only be done after the purchase is finished. It can be done immediately, or at a later point, eg when the user actually consumes the product.

    Getting and Restoring purchases

    This differs between the services. Some services will allow you to query directly the purchases that a user has made and return a list. Apple is the main exception here.

    This functionality is provided through the Get Purchases functionality.

    Apple intend you to do this via a server, by sending the "Application Receipt" to your server and then communicating with Apple to verify and retrieve the list of user's purchases. We have provided an "Application Receipt" variant of this ANE which decodes the application receipt locally on the device and makes the get purchases functionality available. Be aware that this is not considered best practice but is something that we have found to be convenient.

    All services however provide a method of "restoring purchases". This is a process that must be triggered by a user interaction and is designed to be a way for a user to retrieve their purchases on another device. See Restoring Purchases for details.

    - + \ No newline at end of file diff --git a/docs/inappbilling/pending-purchases/index.html b/docs/inappbilling/pending-purchases/index.html index d85af888629..2c5000d78ff 100644 --- a/docs/inappbilling/pending-purchases/index.html +++ b/docs/inappbilling/pending-purchases/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Pending Purchases

    Interupted / Pending / Acknowledging Purchases

    Pending purchases are purchases that are currently still in progress and you are yet to deliver the appropriate product and call finishPurchase().

    Pending purchases may occur when a purchase is interupted, for example, the user left the application during a purchase, or they were initiated from an external source.

    Purchases will remain in the pending purchases queue until you call finishPurchase() with the appropriate purchase.

    The main reason for this process is to allow you to verify the transaction with your server before delivering the product to your user and informing the billing service that the purchase has been delivered to the user.

    From version 8, this process is applicable to Apple's In-App Purchases, Google Play Billing and Amazon In-App Purchases! The process continues to work across all services and platforms.

    The services use slightly different terminology in their documentation you may need to be aware of:

    • Apple uses "pending";
    • Google uses "acknowledged", i.e. an un-acknowledged purchase is a pending purchase,
      • when we finish a purchase we "acknowledge" the purchase;
    • Amazon uses "fulfilled", i.e. an un-fulfillled purchase is a pending purchase,
      • when we finish a purchase we "notify of fulfillment" of the purchase;

    Get Pending Purchases

    You can retrieve the list of pending purchases by calling the getPendingPurchases() function. This will return the array of Purchase objects that are currently 'pending'.

    // Check for any pending purchases
    var pendingPurchases:Array = InAppBilling.service.getPendingPurchases();
    for each (var p:Purchase in pendingPurchases)
    {
    // You should process any pending purchases here and then finish if necessary
    processPurchase( p );
    }

    Setup

    The pending purchases queue may not be initialised immediately, so you may find that in your InAppBillingEvent.SETUP_SUCCESS event handler that the pending purchases queue is empty even though there are pending purchases.

    The queue can be updated just after setup has completed which will be indicated by the normal PurchaseEvent.PURCHASES_UPDATED event. This is particularly true on iOS/tvOS where the payment queue update (which populates the pending purchases) will occur a short time after setup succeeds.

    We suggest you add event listeners for the PurchaseEvent.PURCHASES_UPDATED event before you call setup() to make sure you process all pending notifications at startup. You should also perform a check of the pending purchcases in your InAppBillingEvent.SETUP_SUCCESS handler. Purchases that are already available at startup may not trigger a purchases updated event so you must handling purchases in both cases.

    For example:

    // Add purchases updated handler
    InAppBilling.service.addEventListener( PurchaseEvent.PURCHASES_UPDATED, purchases_updatedHandler );

    InAppBilling.service.addEventListener( InAppBillingEvent.SETUP_SUCCESS, setup_successHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.SETUP_FAILURE, setup_failureHandler );

    InAppBilling.service.setup(
    new BillingService()
    .setGooglePlayPublicKey( GOOGLE_PLAY_INAPP_BILLING_KEY )
    );

    function setup_successHandler( event:InAppBillingEvent ):void
    {
    // Check for pending purchases that are already available
    for each (var p:Purchase in InAppBilling.service.getPendingPurchases())
    {
    processPurchase( p );
    }
    }

    function purchases_updatedHandler( event:PurchaseEvent ):void
    {
    // Your standard purchase queue handler

    for each (var purchase:Purchase in event.data)
    {
    processPurchase( p );
    }
    }

    Note: Do not rely on the PurchaseEvent.PURCHASES_UPDATED event as part of your flow. This event may not be dispatched if there aren't any pending purchases, or if they are available in the setup success handler.

    Google Play Billing Acknowledgement

    With Google Play Billing the call to finishPurchase() performs the acknowledgement of the purchase.

    It's very important to note that if you don't acknowledge a purchase (i.e. call finish purchase) it will be refunded.

    Google Play supports purchasing products from inside of your app (in-app) or outside of your app (out-of-app). In order for Google Play to ensure a consistent purchase experience regardless of where the user purchases your product, you must acknowledge all purchases received through the Google Play Billing Library as soon as possible after granting entitlement to the user. If you do not acknowledge a purchase within three days, the user automatically receives a refund, and Google Play revokes the purchase.

    - + \ No newline at end of file diff --git a/docs/inappbilling/products/index.html b/docs/inappbilling/products/index.html index d962bbcce29..d2d663f9dda 100644 --- a/docs/inappbilling/products/index.html +++ b/docs/inappbilling/products/index.html @@ -13,7 +13,7 @@ - + @@ -39,7 +39,7 @@ ids to the getProducts for example:

    InAppBilling.service.getProducts( 
    [ `com.distriqt.testProduct` ],
    [ `com.distriqt.testSubscription` ]
    );

    If you provide a subscription product id in the product array you may receive an invalid product event for that subscription and vice-versa.

    A subscription product may contain information about the subscription period. This is only supported through stores that return this information. Some stores assume you "know" this information (eg Apple In-App Purchasing) and don't return the information.

    If it is available product.subscriptionPeriod will be a valid instance of the SubscriptionPeriod class. If it is unavailable the subscriptionPeriod will be null.

    This class contains two properties:

    For example, if the numberOfUnits was 2 and the unit was SubscriptionPeriod.UNIT_WEEK then the subscription payment recurs every 2 weeks (fortnightly). Or if the numberOfUnits was 3 and the unit was SubscriptionPeriod.UNIT_MONTH, then the payment recurs every 3 months (or quarterly).

    Subscription Offers

    A Product that represents a subscription will contain information about available offers for the subscription.

    See the section on Subscription Offers and Introductory Prices for more information.

    Example code

    The following demonstrates calling setup and then getProducts on setup success:

    var products : Array;
    var productIds : Array = [ "com.distriqt.testProduct1", "com.distriqt.testProduct2" ];
    var subscriptionIds : Array = [ "com.distriqt.testSubscription1", "com.distriqt.testSubscription2" ];

    InAppBilling.service.addEventListener( InAppBillingEvent.SETUP_SUCCESS, setup_successHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.SETUP_FAILURE, setup_failureHandler );

    InAppBilling.service.addEventListener( InAppBillingEvent.PRODUCTS_LOADED, products_loadedHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.PRODUCTS_FAILED, products_failedHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.INVALID_PRODUCT, product_invalidHandler );

    InAppBilling.service.setup(
    new BillingService()
    .setGooglePlayPublicKey( GOOGLE_PLAY_INAPP_BILLING_KEY )
    );




    function setup_successHandler( event:InAppBillingEvent ):void
    {
    // Retrieve the product list
    InAppBilling.service.getProducts( productIds, subscriptionIds );
    }

    function products_loadedHandler( event:InAppBillingEvent ):void
    {
    // event.data will be an Array of Product instances for each product and subscription successfully loaded
    for each (var product:Product in event.data)
    {
    trace( product.toString() );
    }
    products = event.data;
    }
    - + \ No newline at end of file diff --git a/docs/inappbilling/promotions/index.html b/docs/inappbilling/promotions/index.html index 1359bad99f7..46c4e4225f2 100644 --- a/docs/inappbilling/promotions/index.html +++ b/docs/inappbilling/promotions/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ For example, you may need to cancel a transaction if the user has already unlocked the product they are trying to buy.

    If you respond with true the purchase flow UI will start, similar to if you called makePurchase with a similar purchase request. If you respond false the purchase will be cancelled and no UI will be presented.

    function shouldAddPurchaseHandler( event:PurchaseRequestEvent ):void 
    {
    //
    // Do any checks to see whether this should be added to the queue

    var request:PurchaseRequest = event.request;
    var shouldAddPurchaseToQueue:Boolean = true;

    InAppBilling.service.shouldAddPurchase( request, shouldAddPurchaseToQueue );
    }

    You can hold onto the event.request property and call the shouldAddPurchase() function at a later point if you wish to delay the initiation of the purchase until your application is ready to process the purchase.

    For example, you may need to defer a transaction if the user is in the middle of onboarding, and continue it after onboarding is completed.

    Warning

    This delay will not work across application restarts or disposal of the extension.

    Application State

    If your app is not installed when the user taps or clicks Buy, the App Store automatically downloads the app or prompts the user to buy it. If the installed version of your app is an older version that doesn’t support in-app purchase promotions, the App Store prompts the user to upgrade the app. If your application is not running, the app will be started.

    When your application was not running you won't immediately receive the PurchaseRequestEvent.SHOULD_ADD_PURCHASE event. You should start your application normally and add a listener for the event before you call setup() (this is similar to how you should be handling pending purchases with the PurchaseEvent.PURCHASES_UPDATED event).

    InAppBilling.service.addEventListener( 
    PurchaseRequestEvent.SHOULD_ADD_PURCHASE,
    shouldAddPurchaseHandler );

    // OTHER EVENT LISTENERS

    InAppBilling.service.setup(
    new BillingService()
    .setGooglePlayPublicKey( GOOGLE_PLAY_INAPP_BILLING_KEY )
    );

    If your application was started from a promotion purchase you will receive the event after the call to setup() so you should be prepared to handle it at this stage, or at least prepared to store the request until your application is ready.

    Testing

    iOS

    You can open the following link on a device to replicate the promotional purchase (changing the product and bundle ID's appropriately):

    itms-services://?action=purchaseIntent&bundleId=com.example.app&productIdentifier=com.example.product_id

    Send this URL to yourself in an email or iMessage and open it from your device. You will know the test is running when your app opens automatically. You can then test your promoted in-app purchase.

    Customising Promotions

    From your application you can control some aspects of the promotions displayed to your user. This can be useful to emphasise different promotions as your user progresses through your application or game, and to hide promotions that are no longer or not yet applicable to your user.

    For example, your user may have to reach a certain level in your game before a certain promotion is available to them.

    The default order and visibility of in-app purchases are set in iTunes Connect. Your overrides are per device, and are not synced to an iCloud account. Note that this feature relies on local device storage, and the API can only run after the app has launched on a device at least once.

    Implementing these advanced features is optional. They are not required for your in-app purchases to appear on the App Store.

    Visibility

    To get whether a promotion is visible to a user you can use the getStoreVisibility() function with the product id of the promotion. This call will dispatch one of two events:

    The visibility property is one of either:

    InAppBilling.service.promotions.addEventListener( 
    PromotionsEvent.GET_STORE_VISIBILITY_COMPLETE,
    getStoreVisbility_completeHandler);
    InAppBilling.service.promotions.addEventListener(
    PromotionsEvent.GET_STORE_VISIBILITY_ERROR,
    getStoreVisbility_errorHandler);

    InAppBilling.service.promotions.getStoreVisibility( "com.example.product_id" );

    function getStoreVisbility_completeHandler( event:PromotionsEvent ):void
    {
    // event.visibility contains the visibility property
    }

    function getStoreVisbility_errorHandler( event:PromotionsEvent ):void
    {
    // There was an error
    trace( event.error );
    }

    You can change the visibility by using the updateStoreVisibility() function passing the product id of the promotion and the new visibility value to use

    InAppBilling.service.promotions.addEventListener( 
    PromotionsEvent.UPDATE_STORE_VISIBILITY_COMPLETE,
    updateStoreVisbility_completeHandler );
    InAppBilling.service.promotions.addEventListener(
    PromotionsEvent.UPDATE_STORE_VISIBILITY_ERROR,
    updateStoreVisbility_errorHandler );

    InAppBilling.service.promotions.updateStoreVisibility(
    "com.distriqt.example_id",
    PromotionVisibility.SHOW );

    function updateStoreVisbility_completeHandler( event:PromotionsEvent ):void
    {
    // event.visibility contains the visibility property
    }

    function updateStoreVisbility_errorHandler( event:PromotionsEvent ):void
    {
    // There was an error
    trace( event.error );
    }

    Display Order Override

    You can override the order of promoted in-app purchases on the App Store product page, per device. For example, you can promote an in-app purchase product that unlocks a specific level in your game when a user reaches the level immediately before the specified level.

    To override the default product order for in-app purchases, put the product identifier for the subset of products you want to reorder into an array, in the order you want them to appear in. Pass the array to the updateStoreOrder function.

    var productOrder:Array = [ "com.example.product_1", "com.example.product_2" ];

    InAppBilling.service.promotions.addEventListener(
    PromotionsEvent.UPDATE_STORE_ORDER_COMPLETE,
    updateStoreOrder_completeHandler );
    InAppBilling.service.promotions.addEventListener(
    PromotionsEvent.UPDATE_STORE_ORDER_ERROR,
    updateStoreOrder_errorHandler);

    InAppBilling.service.promotions.updateStoreOrder( productOrder );

    function updateStoreOrder_completeHandler( event:PromotionsEvent ):void
    {
    for each (var productId:String in event.productIdOrder)
    {
    trace( "storeOrder: " + productId );
    }
    }

    function updateStoreOrder_errorHandler( event:PromotionsEvent ):void
    {
    // There was an error
    trace( event.error );
    }

    To read a product order override as it will appear on a given device, call the getStoreOrder method. You should receive an array of products whose order is overridden. If you get an empty array, you have not set any overrides and the products are in the default order.

    InAppBilling.service.promotions.addEventListener( 
    PromotionsEvent.GET_STORE_ORDER_COMPLETE,
    getStoreOrder_completeHandler );
    InAppBilling.service.promotions.addEventListener(
    PromotionsEvent.GET_STORE_ORDER_ERROR,
    getStoreOrder_errorHandler);

    InAppBilling.service.promotions.getStoreOrder();

    function getStoreOrder_completeHandler( event:PromotionsEvent ):void
    {
    for each (var productId:String in event.productIdOrder)
    {
    trace( "storeOrder: " + productId );
    }
    }

    function getStoreOrder_errorHandler( event:PromotionsEvent ):void
    {
    // There was an error
    trace( event.error );
    }

    Offer Codes

    Offer codes can help you acquire, retain, and win back subscribers by providing a subscription at a discount or for free for a limited time.

    You'll distribute offer codes using your channels, such as email or offline marketing campaigns. Consider which channels might be most effective at reaching your intended customers and be sure to mention eligibility or availability limits.

    You can provide a place in your application to redeem offer codes by presenting the offer code redemption dialog via the following:

    var success:Boolean = 
    InAppBilling.service.promotions.showCodeRedemptionDialog();

    The value of success will be true if the redemption dialog is presented or false if the current platform / version doesn't support offer codes, eg iOS < 14.

    Imports

    import com.distriqt.extension.inappbilling.promotions.Promotions;
    import com.distriqt.extension.inappbilling.promotions.PromotionVisibility;
    import com.distriqt.extension.inappbilling.PurchaseRequest;
    import com.distriqt.extension.inappbilling.events.PromotionsEvent;
    import com.distriqt.extension.inappbilling.events.PurchaseRequestEvent;
    - + \ No newline at end of file diff --git a/docs/inappbilling/restore-purchases/index.html b/docs/inappbilling/restore-purchases/index.html index ee494fe3be2..80f30f224c7 100644 --- a/docs/inappbilling/restore-purchases/index.html +++ b/docs/inappbilling/restore-purchases/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ or reinstalled your application and hence need to gain access to their purchases again. It should not be an automatic process but one done through user interaction.

    App Store Review

    This process must be available to your users and must initiated by user interaction in order to pass App Store review.

    To satisfy this requirement, you must provide a button somewhere in your application to initiate this restore process. Generally somewhere like your application settings is an appropriate place to have a restore purchases functionality.

    For more information on the concepts you can read the Apple documentation here.

    For retrieving purchases without user interaction see the Get Purchases functionality.

    The restoring purchases process starts by calling the restorePurchases function and concludes with either a success (InAppBillingEvent.RESTORE_PURCHASES_SUCCESS) or failure (InAppBillingEvent.RESTORE_PURCHASES_FAILED) event.

    After calling restorePurchases you will a receive PurchaseEvent.PURCHASES_UPDATED dispatched which will contained Purchase objects in the restored state having the original purchase variable representing the original purchase transaction.

    // The service must be setup and a list of products retrieved.

    // Make sure you have added your purchases handler
    InAppBilling.service.addEventListener( PurchaseEvent.PURCHASES_UPDATED, purchases_updatedHandler );

    InAppBilling.service.addEventListener( InAppBillingEvent.RESTORE_PURCHASES_SUCCESS, restorePurchases_successHandler );
    InAppBilling.service.addEventListener( InAppBillingEvent.RESTORE_PURCHASES_FAILED, restorePurchases_failedHandler );

    // Start the restore process
    InAppBilling.service.restorePurchases();


    //
    //
    //

    function purchases_updatedHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.data)
    {
    switch (purchase.transactionState)
    {

    // Other states...


    case Purchase.STATE_RESTORED:
    // The originalPurchase property will contain all the
    // information on the original transaction allowing
    // you to restore the user's product

    addPurchaseToInventory( purchase.originalPurchase );
    InAppBilling.service.finishPurchase( purchase );

    // Again you could hold on to this purchase and check it against
    // your application server before calling finishPurchase
    break;


    }
    }
    }


    //
    // RESTORE PURCHASE EVENTS
    //

    function restorePurchases_successHandler( event:InAppBillingEvent ):void
    {
    // Called when all purchases have been restored
    // This event contains no data
    }

    function restorePurchases_failedHandler( event:InAppBillingEvent ):void
    {
    // Called if there was an error restoring purchases
    }
    - + \ No newline at end of file diff --git a/docs/inappbilling/samsung/add-the-extension/index.html b/docs/inappbilling/samsung/add-the-extension/index.html index 4fa23ae294f..f6492e58818 100644 --- a/docs/inappbilling/samsung/add-the-extension/index.html +++ b/docs/inappbilling/samsung/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Samsung In-App Purchasing

    About

    Samsung In-App Purchase (IAP) is a payment service that makes it possible to sell a variety of items in applications for Samsung Galaxy Store and internally manages communication with supporting IAP services in the Samsung ecosystem, such as Samsung Account, Samsung Checkout, and Samsung Rewards.

    This section describes how to setup your AIR application to use Samsung In-App Purchase (IAP) with this extension.

    Install

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the package by running:

    apm install com.distriqt.InAppBilling-Samsung

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.InAppBilling.ane # InAppBilling extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    caution

    Only install one variant of an package. The base variant is installed when no variant is specified and cannot be included alongside another variant. You will likely get an error if you attempt to install multiple variants with apm

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (InAppBilling.isSupported)
    {
    // Functionality here
    }
    note

    This only checks if there is some functionality supported, not whether a particular billing service is available.

    - + \ No newline at end of file diff --git a/docs/inappbilling/samsung/samsung-in-app-purchases/index.html b/docs/inappbilling/samsung/samsung-in-app-purchases/index.html index ef93771e4ae..a84f6c07381 100644 --- a/docs/inappbilling/samsung/samsung-in-app-purchases/index.html +++ b/docs/inappbilling/samsung/samsung-in-app-purchases/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Setup Samsung Galaxy Store

    Samsung devices use a variant of Android. Some may include both Google Play and the Samsung Galaxy Store.

    The following outlines the steps required to enable Galaxy Store in app purchases in your application.

    Developer console

    Samsung have created a guide here to setup an application for IAP. Below we will summarise the key points.

    Setup an new application with an identifier different from the app registered in other app stores.

    caution

    If package names are not different, app update malfunctions and problems with marketing and promotional support may occur.

    Generate an application package to upload to the store as a "dummy" application to go through the process of setting up your application's in-app items and start testing locally. (Ensure you have added the extension to this dummy application so that you have the correct manifest settings).

    info

    You do not need to publish either to beta or live before testing. However make sure you have correctly set your testing users as per testing.

    Register an app and in-app items

    1. Sign in to Seller Portal using your Samsung account.
    2. Click Add New App

    1. Click Android, select the default language, and click Next.

    note

    After entering information in each tab, click Save.

    1. In the Binary tab, upload your app APK.

    1. In the App Information tab, enter fundamental app details.

    2. In the Country / Region & Price tab, specify a free or paid app, a paid app price, and countries to sell your items.

    3. In the In App Purchase tab, register one or more in-app items:

    a. Click Add Item

    b. Enter in-app item information.

    c. Click Save.

    note

    For a subscription item, ensure your item registration information is correct. After saving a subscription item, you can only change its item title.

    d. Verify the item is listed

    Setting up a Billing Service

    The following is in addition to the documentation in Setting up a Billing Service.

    When setting up your service you will need to specify the InAppBillingServiceTypes.SAMSUNG_INAPP_PURCHASE service type. You will also want to set the "operation mode". This is a setting that allows testing of samsung In-App Purchases and should be disabled in production builds (or set to BillingService.OPERATION_MODE_PRODUCTION).

    var service:BillingService = new BillingService( InAppBillingServiceTypes.SAMSUNG_INAPP_PURCHASE )
    .setOperationMode( BillingService.OPERATION_MODE_TEST );

    var success:Boolean = InAppBilling.service.setup( service );

    You should wait for the InAppBillingEvent.SETUP_SUCCESS event to ensure the Samsung In-App Purchases are correctly initialised and available on the device.

    - + \ No newline at end of file diff --git a/docs/inappbilling/samsung/testing/index.html b/docs/inappbilling/samsung/testing/index.html index dd006e1b6bb..68318a8a858 100644 --- a/docs/inappbilling/samsung/testing/index.html +++ b/docs/inappbilling/samsung/testing/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Samsung Galaxy Store - Testing

    Users

    Important

    Testers must be registered as a License Tester in the seller's Seller Portal profile. If you do not do this you will experience issues when testing your implementation.

    Operation Mode

    Samsung In-App Purchase uses "operation modes" to test your application in various states.

    The operation mode is set through the Billing Service:

    var service:BillingService = 
    new BillingService( InAppBillingServiceTypes.SAMSUNG_INAPP_PURCHASE )
    .setOperationMode( BillingService.OPERATION_MODE_TEST );

    InAppBilling.service.setup( service );

    The type of responses from the store is determined by the state of the application and the operation mode as per the table below:

    IAP TestTransactionsIAP Operating ModeApp Status
    Always Successful Side LoadNo chargeOPERATION_MODE_TESTRegistering
    Always Fail Side LoadNo chargeOPERATION_MODE_TEST_FAILURERegistering
    Production Closed BetaNo charge or Charge (depends on type of tester)OPERATION_MODE_PRODUCTIONBeta Deployed
    caution

    Do not test when the IAP operating mode is OPERATION_MODE_PRODUCTION and the app status is Registering. IAP functionality is not supported under these conditions.

    For more information on these modes and the transaction charges for different user types, see the guide here.

    - + \ No newline at end of file diff --git a/docs/inappbilling/subscription-offers/index.html b/docs/inappbilling/subscription-offers/index.html index f97ff384063..2a4a970435a 100644 --- a/docs/inappbilling/subscription-offers/index.html +++ b/docs/inappbilling/subscription-offers/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Subscription Offers

    A subscription represents a set of benefits users can access during a specified time period. For example, a subscription might entitle a user to access a music streaming service.

    You can have multiple subscriptions within the same app, either to represent different sets of benefits, or different tiers of a single set of benefits ("Silver" and "Gold" tiers, for example).

    Through base plans and offers, you can create multiple configurations for the same subscription product. For example, you can create an introductory offer for users who have never subscribed to your app.

    Retrieving Subscription Offers

    Information on the offers for a subscription are retrieved as part of the getProducts() call.

    Every subscription will have at least one available SubscriptionOffer. These are retrieved for each Product in the subscriptionOffers property which is an array of SubscriptionOffer objects.

    InAppBilling.service.addEventListener( 
    InAppBillingEvent.PRODUCTS_LOADED,
    products_loadedHandler );

    InAppBilling.service.getProducts( [ productId ] );


    function products_loadedHandler( event:InAppBillingEvent ):void
    {
    for each (var product:Product in event.data)
    {
    if (product.subscriptionOffers != null)
    {
    for each (var offer:SubscriptionOffer in product.subscriptionOffers)
    {
    trace( "OFFER: " + offer.id + "[" + offer.tags.join( "," ) + "]" )
    for each (var phase:SubscriptionPhase in offer.pricingPhases)
    {
    trace( "\t PHASE: " + phase.priceString + " - " + phase.numberOfPeriods + "/" + phase.recurrenceMode
    + " @ [" + phase.subscriptionPeriod.numberOfUnits + " " + phase.subscriptionPeriod.unit + "]" );

    }
    }
    }
    }
    }

    Phases

    Each SubscriptionOffer contains a series of SubscriptionPhase's. Each phase describes a period of the subscription that has a specific price and period.

    For example, you may have a free trial phase followed by the normal subscription:

    • phase 1 : price $0, period 1 week;
    • phase 2 : price $X, period 1 month;

    Each offer will contain at least 1 phase.

    Determine Eligibility

    Depending on the store, you may need to determine whether the current user is eligible for the discount. You can check this by inspecting the storeDeterminedEligible flag on the SubscriptionOffer instance.

    This flag indicates whether the current user is determined to be eligible for the discount by the source store.

    If this value is true then you can assume the user is eligible for the discount. If it is false then you will need to use the process defined by the current store to determine user eligibility.

    For example, Google Play Billing only provides details on these offers to users who are eligible for the discount and so this value will be true.

    As opposed to Apple In-App Purchases where you must determine eligibility by determining if the user has previously purchased a subscription.

    Google Play Billing

    The discount will only be available in the subscriptionOffers array if the user is eligible for the offer.

    Apple In-App Purchases

    Introductory Offers

    Introductory offers will have the offer id set to introductoryOffer.

    To determine if a user is eligible for an introductory offer, check their receipt:

    • Validate the receipt as described in Validating Receipts with the App Store.
    • Send the receipt to your server;
    • Call the Apple verify receipt end point;
    • Process the response;
    • In the receipt, check the values of the is_trial_period and the is_in_intro_offer_period for all in-app purchase transactions. If either of these fields are true for a given subscription, the user is not eligible for an introductory offer on that subscription product or any other products within the same subscription group.

    Based on the receipt, you will find that new and returning customers are eligible for introductory offers, including free trials:

    • New subscribers are always eligible.
    • Lapsed subscribers who renew are eligible if they haven't previously used an introductory offer for the given product (or any product within the same subscription group).

    Promotional Offers

    There are two aspects to determining a user’s eligibility for an Apple promotional subscription offer:

    • The App Store deems all customers with an existing or expired subscription in the app eligible to redeem a subscription offer. You can check whether the receipt contains any existing or expired subscription purchases to identify these current or lapsed subscribers.

    • You determine any additional eligibility criteria for a specific subscription offer. Eligibility can be contingent on a wide range of business logic determined by your business needs.

    note

    Customers can redeem subscription offers only on devices running iOS 12.2 and later, macOS 10.14.4 and later, and tvOS 12.2 and later. Consider providing messaging prompting your customer to update their OS if they try to redeem a subscription offer in your app on a device running an older OS version.

    With Apple, some offers require the generation of a signature on your server. You can check this by checking the value of the requiresSignature property on the SubscriptionOffer. If this is true then the offer represents an Apple promotional subscription offer and you need to generate a signature as per the following diagram:

    See Generate Signature for more information.

    Display Offer

    Once you determine the user is eligible for an introductory discount, query the extension for available products, and inspect the subscriptionOffers property.

    You will have to display the alternate pricing based on whether you determined the user to be eligible.

    There may be more than one offer, so ensure that you display information on all of them. Eg, you may have a free trial period, followed by an introductory price discount, before the normal subscription price is applied. It is considered very important by the store policies that all this information is clearly displayed.

    Make the Purchase

    To make a purchase of a subscription product you must provide details on the SubscriptionOffer to purchase by adding a SubscriptionOfferRequest to your PurchaseRequest:

    var product:Product = ...;
    var offer:SubscriptionOffer = ...;

    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( product.id )
    .setApplicationUsername( applicationUsername )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    );

    if (InAppBilling.service.checkPurchaseRequestValid( request ))
    {
    InAppBilling.service.makePurchase( request );
    }

    The flow of the purchase will then proceed as a normal purchase.

    Generate Signature

    Once you have decided a user is eligible for the subscription offer, you can check if the offer requires a signature by looking at the requiresSignature property on the SubscriptionOffer. If this is true then you must construct a signature for the SubscriptionOfferRequest on your server.

    The signature information required includes:

    • keyIdentifier - the identifier of the subscription key used to sign the discount;
    • nonce - a throwaway value generated along with the signature;
    • signature - the actual signature;
    • timestamp - the timestamp when the signature was generated.

    This information is then passed when purchasing the subscription by using the setSignature() method on the SubscriptionOfferRequest:

    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( product.id )
    .setApplicationUsername( applicationUsername )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    .setSignature( key, nonce, signature, timestamp )
    );

    The subscription key is generated through Apple's AppStoreConnect, in the "Users and Access" section.

    On your server you must generate the signature using the following parameters:

    • appBundleID: The app bundle identifier.
    • keyIdentifier : A string that identifies the private key you use to generate the signature. You can find this identifier in App Store Connect Users and Access > Keys, in the KEY ID column for the subscription key you generated.
    • productIdentifier : The subscription product identifier, productIdentifier. The app can provide this value.
    • offerIdentifier : The subscription discount identifier, identifier. The app can provide this value.
    • applicationUsername : An optional string value that you define; may be an empty string. The app can provide this value and uses it in applicationUsername.
    • nonce : A unique UUID value that your server defines. This value is cached for 24 hours. The string representation of the nonce used in the signature must be in lowercase.
    • timestamp : A timestamp your server generates in UNIX epoch time format, in milliseconds; the timestamp keeps the offer active for 24 hours.

    You use all of this information to create the signature as per the Apple documentation. See the example below for a simple NodeJS implementation.

    NodeJS Example

    The following is a basic NodeJS example accepting the required information in the get parameters and returning the signature information in the JSON output. You will need to place the private key that you created and downloaded alongside this script in the subscription_certificate.p8 file.

    const http = require('http');
    const url = require('url');
    const express = require('express');
    const app = express();
    const uuid4 = require('uuid4');
    const fs = require('fs');

    const EC = require("elliptic").ec;
    const ec = new EC("secp256k1");
    const crypto = require('crypto');

    const port = 8080;



    function generateSignatureHandler(req, res) {

    // https://developer.apple.com/documentation/storekit/in-app_purchase/generating_a_signature_for_subscription_offers

    // Params
    const appBundleID = req.query.appBundleID
    const keyIdentifier = req.query.keyIdentifier
    const productIdentifier = req.query.productIdentifier
    const offerIdentifier = req.query.offerIdentifier
    const applicationUsername = req.query.applicationUsername

    const nonce = uuid4()
    const timestamp = Math.floor(new Date())

    // Combine the parameters into a UTF-8 string with
    // an invisible separator ('\u2063') between them,
    // in the order shown:
    // appBundleId + '\u2063' + keyIdentifier + '\u2063' + productIdentifier +
    // '\u2063' + offerIdentifier + '\u2063' + applicationUsername + '\u2063' +
    // nonce + '\u2063' + timestamp

    let payload =
    appBundleID + '\u2063'
    + keyIdentifier + '\u2063'
    + productIdentifier + '\u2063'
    + offerIdentifier + '\u2063'
    + applicationUsername + '\u2063'
    + nonce+ '\u2063'
    + timestamp;

    // Sign the combined string
    // Private Key - p8 file downloaded
    // Algorithm - ECDSA with SHA-256

    const keyPem = fs.readFileSync('subscription_certificate.p8', 'ascii');

    // Step 4
    // Base64-encode the binary signature
    const signature = crypto.createSign('RSA-SHA256')
    .update(payload)
    .sign(keyPem, 'base64');

    let response1 = {
    "signature": signature,
    "nonce": nonce,
    "timestamp": timestamp,
    "keyIdentifier": keyIdentifier
    }
    res.type('json').send(response1);

    }

    app.get( '/', generateSignatureHandler );
    app.listen( port, () => console.log(`Listening on port ${port}!`) );


    // http://localhost:8080?appBundleID=ASDFASDF&keyIdentifier=JZCXH9P46S&productIdentifier=asdf&offerIdentifier=asdf&applicationUsername=asdf

    This could be used in your AIR application as below, (however you will most likely need to implement a more robust solution for a production application):

    var product:Product = ...;
    var offer:SubscriptionOffer = ...;

    generateSignature(
    product,
    offer,
    applicationUsername,
    function(key:String, nonce:String, signature:String, timestamp:Number):void
    {
    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( product.id )
    .setApplicationUsername( applicationUsername )
    .setSubscriptionOfferRequest(
    new SubscriptionOfferRequest()
    .setSubscriptionOffer( offer )
    .setSignature( key, nonce, signature, timestamp )
    );

    if (InAppBilling.service.checkPurchaseRequestValid( request ))
    {
    InAppBilling.service.makePurchase( request );
    }
    }
    );

    function generateSignature(
    product:Product,
    offer:SubscriptionOffer,
    applicationUsername:String,
    callback:Function ):void
    {
    var vars:URLVariables = new URLVariables();
    vars.appBundleID = "com.distriqt.test";
    vars.keyIdentifier = Config.APPLE_KEY_IDENTIFIER;
    vars.productIdentifier = product.id;
    vars.offerIdentifier = offer.id;
    vars.applicationUsername = applicationUsername;

    var request:URLRequest = new URLRequest();
    request.url = Config.APPLE_DISCOUNT_SIGNATURE_SERVER;
    request.method = URLRequestMethod.GET;
    request.data = vars;

    var loader:URLLoader = new URLLoader();
    loader.addEventListener( Event.COMPLETE, function ( event:Event ):void
    {
    event.currentTarget.removeEventListener( event.type, arguments.callee );

    var data:Object = JSON.parse( loader.data );

    var key:String = data.keyIdentifier;
    var nonce:String = data.nonce;
    var signature:String = data.signature;
    var timestamp:Number = data.timestamp;

    callback( key, nonce, signature, timestamp );
    } );
    loader.load( request );
    }

    Policy Guidelines

    There are some policy guidelines you will need to adhere to when displaying the subscription offers, mainly around the information that is displayed to the user when asking them to subscribe. Make sure you have read and followed the guidelines when implementing subscription offers:

    Imports

    import com.distriqt.extension.inappbilling.Product;
    import com.distriqt.extension.inappbilling.PurchaseRequest;
    import com.distriqt.extension.inappbilling.SubscriptionOffer;
    import com.distriqt.extension.inappbilling.SubscriptionOfferRequest;
    import com.distriqt.extension.inappbilling.SubscriptionPhase;

    import com.distriqt.extension.inappbilling.event.InAppBillingEvent;
    - + \ No newline at end of file diff --git a/docs/inappbilling/testing/index.html b/docs/inappbilling/testing/index.html index 5a2a921540e..f89f3cb36cd 100644 --- a/docs/inappbilling/testing/index.html +++ b/docs/inappbilling/testing/index.html @@ -13,7 +13,7 @@ - + @@ -32,7 +32,7 @@ again shortly after launch; this time, let your app respond normally.

    Verify that your app correctly delivers the product and completes the transaction.

    This is only applicable for services that require calling finishPurchase, mainly the Apple's In-App Purchases.

    Verify That Purchases Are Finished

    Locate where your app calls the finishPurchase method. You should call this whether or not the service you are using requires it.

    Verify that all work related to the transaction has been completed before the method is called and that the method is called for every transaction, whether it succeeded or failed.

    - + \ No newline at end of file diff --git a/docs/inappbilling/user-data/index.html b/docs/inappbilling/user-data/index.html index 58f5a24799d..9301f01b2c9 100644 --- a/docs/inappbilling/user-data/index.html +++ b/docs/inappbilling/user-data/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    User Data

    Some services attach some information to the user that can be retrieved and may be necessary to validate receipts.

    Currently this is supported on the following services:

    • Amazon

    You retrieve this data by using the getUserData() function and listening for the response.

    This function will return false if user data is not supported with the current service.

    var success:Boolean = InAppBilling.service.getUserData();
    if (!success)
    {
    // User data not supported
    }

    If it returns true, then one of two events will be dispatched:

    • UserDataEvent.GET_SUCCESS: Indicates the user data was successfully retrieved;
    • UserDataEvent.GET_FAILED: Indicates there was a failure when retrieving the data;
    InAppBilling.service.addEventListener( UserDataEvent.GET_SUCCESS, getUserData_successHandler );
    InAppBilling.service.addEventListener( UserDataEvent.GET_FAILED, getUserData_failedHandler );

    InAppBilling.service.getUserData();


    function getUserData_successHandler( event:UserDataEvent ):void
    {
    // Success
    trace( "USER ID: " + event.userData.userId );
    }

    function getUserData_failedHandler( event:UserDataEvent ):void
    {
    // Failure handler - retry after a delay or inform user of the issue
    }
    - + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index bdb69c28ce2..498406fb46f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Native Extensions

    Get started quickly and easily with distriqt's native extensions and focus on building great games and apps.

    Note on terminology

    We develop across several platforms (AIR, Unity, Flutter etc). Each platform uses their own name for a native extension:

    • AIR has ANEs (AIR Native Extensions);
    • Unity has Unity Native Plugins;
    • Flutter has Plugin packages;

    We use the name "extension" to represent all these concepts.

    Getting Started

    If you are new to extensions, check the tutorials and FAQs sections for information on starting out with native extensions.

    Find your extension
    • Select the extension from the list on the left;
    • Look through the popular extensions below;
    • Try the search at the top of the page.

    Common Extensions

    Adverts

    Banners, interstitials and rewarded video ads

    Native WebView

    Native webview for better web rendering support

    In-App Billing

    Monetise your app with in-app purchases through multiple services

    Notifications

    Simple user engagement through local notifications

    Share

    Sharing images and urls through the native share dialogs

    Firebase

    Firebase platform, including analytics, auth and database functionality

    Free Extensions

    IronSource

    IronSource advertising

    IDFA

    Access the Advertising Identifiers

    System Gestures

    Control the screen edge gestures and home indicator

    Branch

    Branch IO deep linking and universal objects
    - + \ No newline at end of file diff --git a/docs/ironsource/add-the-extension/index.html b/docs/ironsource/add-the-extension/index.html index a6df788a318..7a29f45d6de 100644 --- a/docs/ironsource/add-the-extension/index.html +++ b/docs/ironsource/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ impacted by ATS on iOS 9 devices, while NSAllowsArbitraryLoadsForMedia and NSAllowsAribtraryLoadsInWebContent are required to make sure your ads are not impacted by ATS on iOS 10 devices.

    Example:

    <iPhone>
    <InfoAdditions><![CDATA[
    <key>UIDeviceFamily</key>
    <array>
    <string>1</string>
    <string>2</string>
    </array>

    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsForMedia</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    </dict>

    <key>GADApplicationIdentifier</key>
    <string>ca-app-pub-AAAAAAAAAAAAAAAA~XXXXXXXXXX</string>
    ]]></InfoAdditions>
    <requestedDisplayResolution>high</requestedDisplayResolution>
    <Entitlements>
    <![CDATA[
    ]]>
    </Entitlements>
    </iPhone>

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (IronSource.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/ironsource/banner-ads/index.html b/docs/ironsource/banner-ads/index.html index 5e38a402c99..988c51885a8 100644 --- a/docs/ironsource/banner-ads/index.html +++ b/docs/ironsource/banner-ads/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Banner Ads

    A banner ad is a rectangular ad that is typically displayed on the top or bottom of the screen and remains in place for the entire user session. Banner ads can be static or dynamic.

    Load a Banner Ad

    To load a banner ad, call the loadBanner() function with the required banner size and position:

    IronSource.instance.loadBanner( 
    IronSourceBannerSize.BANNER,
    IronSource.POSITION_BOTTOM
    );

    When loading the banner, make sure to configure your Banner Size:

    • IronSourceBannerSize.BANNER: Standard Banner, Best for Phones & Tablets;
    • IronSourceBannerSize.LARGE: Large Banner, Best for Tablets and Larger Devices;
    • IronSourceBannerSize.RECTANGLE: Large Rectangular Banner, Best for Scrollable Feeds or Between Game Levels;
    • IronSourceBannerSize.SMART: Smart Banner, Renders ads that automatically resize to fit the device’s size and orientation;

    and position:

    • IronSource.POSITION_TOP: Banner will be positioned at the top center of the screen;
    • IronSource.POSITION_BOTTOM: Banner will be positioned at the bottom center of the screen;

    We support placements, as well as capping and pacing for Banners on the ironSource dashboard. Learn how to set up placements, capping and pacing for Banners to optimize your app’s user experience here.

    If you’ve set up placements for your Banner, call the following method to serve a Banner ad in a specific location:

    IronSource.instance.loadBanner( 
    IronSourceBannerSize.BANNER,
    IronSource.POSITION_BOTTOM,
    "placement_name"
    );

    Load Events

    After you call load you will receive one of two events:

    • BannerAdEvent.LOADED: Dispatched once the banner has loaded;
    • BannerAdEvent.LOAD_FAILED: Dispatched if there was an error loading the banner ad;

    For example:

    IronSource.instance.addEventListener( BannerAdEvent.LOADED, onBannerAdLoaded );
    IronSource.instance.addEventListener( BannerAdEvent.LOAD_FAILED, onBannerAdLoadFailed );


    IronSource.instance.loadBanner( IronSourceBannerSize.BANNER, IronSource.POSITION_BOTTOM );


    function onBannerAdLoaded(event:BannerAdEvent):void
    {
    // Banner is loaded and can now be displayed
    IronSource.instance.displayBanner();
    }

    function onBannerAdLoadFailed(event:BannerAdEvent):void
    {
    var errorCode:String;
    var errorDescription:String;
    if (event.data)
    {
    var error:Object = JSON.parse(event.data);
    errorDescription = error.error_description;
    errorCode = error.error_code;
    }
    }

    Hide and Display Banner

    In order to provide maximum flexibility in the ad experience, you now have the ability to hide and present banners on your app.

    Once you’ve loaded and served a banner, you can choose to hide this banner and re-show it at a later point in your app.

    To hide the banner, call this function:

    IronSource.instance.hideBanner();

    To then show this same banner again, call this function:

    IronSource.instance.displayBanner();

    Destroy

    Once you’ve successfully served a banner, we recommend calling the below function to destroy the banner.

    IronSource.instance.destroyBanner();

    After you call this method, the banner in question can no longer be used. In the case you want to serve another banner, you will need to request a new Banner using the loadBanner() method.

    Events

    The ironSource Air Plugin fires several events to inform you of ad availability and activity. To listen to any event, call the addEventListener method.

    The event names are defined in the BannerAdEvent class.

    • BannerAdEvent.CLICKED: Dispatched when the user clicks the banner;
    • BannerAdEvent.SCREEN_PRESENTED: Notifies the presentation of a full screen content following user click;
    • BannerAdEvent.SCREEN_DISMISSED: Notifies the presented screen has been dismissed;
    • BannerAdEvent.LEFT_APPLICATION: Invoked when the user leaves the app;

    You add listeners for these as follows:

    IronSource.instance.addEventListener( BannerAdEvent.CLICKED, onBannerAdClicked );
    IronSource.instance.addEventListener( BannerAdEvent.SCREEN_PRESENTED, onBannerAdScreenPresented );
    IronSource.instance.addEventListener( BannerAdEvent.SCREEN_DISMISSED, onBannerAdScreenDismissed );
    IronSource.instance.addEventListener( BannerAdEvent.LEFT_APPLICATION, onBannerAdLeftApplication );

    private function onBannerAdClicked(event:DataEvent):void
    {

    }

    private function onBannerAdScreenPresented(event:DataEvent):void
    {

    }

    private function onBannerAdScreenDismissed(event:DataEvent):void
    {

    }

    private function onBannerAdLeftApplication(event:DataEvent):void
    {

    }

    Errors

    See the complete description of the ironSource errors here.

    - + \ No newline at end of file diff --git a/docs/ironsource/changelog/index.html b/docs/ironsource/changelog/index.html index ece62aa4d40..092a8b92716 100644 --- a/docs/ironsource/changelog/index.html +++ b/docs/ironsource/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.11.07 [v2.18.1]

    fix(ironsource): correct parameter names used for banner size objects (resolves #55)

    2023.11.07 [v2.18.1]

    fix(ironsource): correct parameter names used for banner size objects (resolves #55)

    2023.09.14 [v2.18.0]

    feat(ironsource): add impression data events and details for mediation network impression data (resolves #52)
    feat(ironsource): move to latest event callback system, add AdInfo information to rewarded video and interstitial events
    feat(ironsource): update android sdk v7.5.1, update ios sdk v7.5.0

    feat(adcolony): update sdk: android v4.3.15 (v4.8.0) ios v4.3.17 (v4.9.0)
    feat(applovin): update sdk: android v4.3.39 (v11.10.1) ios v4.3.40 (v11.10.1)
    feat(chartboost): update sdk: android v4.3.12 (v9.3.1) ios v4.3.15 (v9.2.0)
    feat(digitalturbine): update sdk: android v4.3.26 (v8.2.3) ios v4.3.31 (v8.2.4)
    feat(facebookaudience): update sdk: android v4.3.45 (v6.16.0) ios v4.3.42 (v6.14.0)
    feat(unityads): update sdk: android v4.3.31 (v4.8.0) ios v4.3.31 (v4.8.0)
    feat(vungle): update sdk: android v4.3.21 (v6.12.1) ios v4.3.28 (v7.0.1)

    2023.05.02 [v2.16.0]

    feat(ironsource): add setUserId functionality (resolves #46)

    2023.03.30 [v2.15.3]

    fix(chartboost): correct required dependencies and update docs

    2023.03.27 [v2.15.2]

    feat(chartboost,unityads): fix missing swift compat references

    2023.03.22 [v2.15.1]

    fix(unityads): add missing android dependency

    2023.03.22 [v2.15.0]

    Update IronSource SDK

    - Android v7.3.0
    - iOS v7.3.0

    feat(ironsource): update sdk android v7.3.0, ios v7.3.0
    feat(adcolony): update sdk: android v4.3.14 (v4.8.0) ios v4.3.16 (v4.9.0)
    feat(admob): update sdk: android v4.3.35 (v21.5.0) ios v4.3.41 (v10.1.0)
    feat(applovin): update sdk: android v4.3.37 (v11.7.1) ios v4.3.38 (v11.7.1)
    feat(chartboost): update sdk: android v4.3.11 (v9.2.0) ios v4.3.13 (v9.2.0)
    feat(digitalturbine): update sdk: android v4.3.24 (v8.2.2) ios v4.3.28 (v8.1.9)
    feat(facebookaudience): update sdk: android v4.3.39 (v6.12.0) ios v4.3.39 (v6.12.0)
    feat(tapjoy): update sdk: android v4.1.24 (v12.11.1) ios v4.1.24 (v12.11.1)
    feat(unityads): update sdk: android v4.3.26 (v4.6.0) ios v4.3.27 (v4.6.0)
    feat(vungle): update sdk: android v4.3.20 (v6.12.1) ios v4.3.25 (v6.12.3)

    removed deprecated amazon mediator (as of September 30, 2021 Amazon deprecated Amazon Mobile Ads Network)

    2023.02.17 [v2.14.2]

    feat(ios): strip bitcode from dynamic frameworks that haven't been updated yet

    2023.01.27 [v2.14.1]

    fix(mediators): update mediator airpackages dependency on ironsource (resolves #43)

    2023.01.20 [v2.14.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.10.19 [v2.13.0]

    feat(unityads): update unity ads sdk: android v4.3.23 (v4.4.1) ios v4.3.23 (v4.3.0)
    feat(digitalturbine): add mediation adapter for digital turbine (fyber) android v4.3.22 (v8.2.0) ios v4.3.25 (v8.1.5)

    2022.10.19 [v2.12.0]

    feat(unityads): update unity ads sdk: android v4.3.23 (v4.4.1) ios v4.3.23 (v4.3.0)
    feat(digitalturbine): add mediation adapter for digital turbine (fyber) android v4.3.22 (v8.2.0) ios v4.3.25 (v8.1.5)

    2022.10.09 [v2.12.0]

    fix(ironsource): correct airpackage dependencies 
    feat(vungle): add vungle mediator: android v4.3.18 (v6.12.0) ios v4.3.22 (v6.12.0)

    2022.10.05 [v2.11.0]

    feat(ironsource): add setmetadata function (resolves #34)

    feat(adcolony): update adcolony sdk: android v4.3.13 (v4.8.0) ios v4.3.15 (v4.9.0)
    feat(applovin): update applovin sdk: android v4.3.34 (v11.5.0) ios v4.3.35 (v11.5.0)
    fix(admob): correct dependencies to include AppSet library (resolves #38)

    2022.08.30 [v2.10.0]

    feat(ironsource): update sdk
    - Android v7.2.4
    - iOS v7.2.4

    feat(ironsource): add setAdaptersDebug function to enable debug logs for mediation adapters

    feat(admob): update admob sdk: android v4.3.29 (support for v21 of Google AbMob) (resolves #32)
    feat(applovin): update applovin sdk: android v4.3.33 (v11.4.4) ios v4.3.34 (v11.4.3)
    feat(facebookaudience): update facebook audience sdk: android v4.3.37 (v6.11.0) ios v4.3.37 (v6.11.2)
    feat(tapjoy): update tapjoy sdk: android v4.1.21 (v12.10.0) ios v4.1.21 (v12.10.0)
    feat(unityads): update unity sdk: android v4.3.22 (v4.3.0) ios v4.3.23 (v4.3.0)
    feat(chartboost): update chartboost sdk: android v4.3.9 (v9.0.0)

    2022.06.28 [v2.9.0]

    Update IronSource SDK

    - Android v7.2.2
    - iOS v7.2.2.1

    feat(unity): update unity sdk: android v4.3.21 (v4.1.0) ios v4.3.22 (v4.2.1)
    feat(tapyjoy): update tapjoy sdk: android v4.1.20 (v12.9.1) ios v4.1.19 (v12.9.1)
    feat(facebook): update facebook audience sdk: android v4.3.36 (v6.11.0) ios v4.3.36 (v6.11.1)
    feat(applovin): update applovin sdk: android v4.3.32 (v11.4.3) ios v4.3.32 (v11.4.1)
    feat(adcolony): update adcolony sdk: android v4.3.12 (v4.7.1) ios v4.3.14 (v4.8.0)

    2022.03.09 [v2.8.0]

    Update IronSource SDK
    - Android v7.2.0
    - iOS v7.2.0

    Updated AdColony: Android v4.3.10, iOS v4.3.12
    Updated AdMob: Android v4.3.26, iOS v4.3.30
    Updated AppLovin: Android v4.3.30, iOS v4.3.29
    Updated Chartboost: Android v4.3.8, iOS v4.3.10
    Updated Facebook Audience: Android v4.3.34, iOS v4.3.33
    Updated Tapjoy: Android v4.1.19, iOS v4.1.18
    Updated UnityAds: Android v4.3.20, iOS v4.3.19

    2022.02.08 [v2.7.0]

    Update docs to use apm
    Minor fixes for manifests in air packages

    2021.09.06 [v2.7.0]

    Added AIR packages 

    Updated ironSource SDK:
    - Android v7.1.10
    - iOS v7.1.10

    Updated UnityAds: Android v4.3.14 iOS v4.3.13
    Updated Tapjoy: Android v4.1.18 iOS v4.1.18
    Updated Facebook: Android v4.3.30 iOS v4.3.29
    Updated Chartboost: Android v4.3.9 iOS v4.3.8
    Updated AppLovin: Android v4.3.28 iOS v4.3.28
    Updated Amazon: Android v4.3.4 iOS v4.3.6
    Updated AdMob: Android v4.3.22 iOS v4.3.27
    Updated AdColony: Android v4.3.9 iOS v4.3.10

    2021.07.12 [v2.6.1]

    Corrected docs on new dependencies, fixed issue with rewarded placement info not available

    2021.07.09 [v2.6.0]

    Updated SDK:
    - Android v7.1.7
    - iOS v7.1.7

    Facebook Audience: Added setAdvertiserTrackingEnabled and setDataProcessingOptions to set additional settings for Facebook (resolves #27)

    Updated mediation adapters to latest versions

    2021.05.10 [v2.5.0]

    Added reward information to REWARD event (resolves #24)

    Updated SDK:
    - Android v7.1.5.1
    - iOS v7.1.5

    Updated mediation adapters

    2021.02.26 [v2.4.1]

    Corrected some build errors (resolves #22)

    2021.01.22 [v2.4.0]

    Updated SDK:
    - Android v7.1.0.1
    - iOS v7.1.0
    Updated mediation adapters
    Corrected iron source swc release (resolves #20)

    2020.11.03 [v2.3.0]

    Implemented Banner Ads (resolves #18)
    Implemented Offerwall (resolves #17)

    2020.10.16 [v2.2.0]

    Updated SDK + mediator SDKs to latest builds

    2020.10.05 [v2.1.0]

    Added Mediation Adapters:
    - AdColony
    - AdMob
    - Amazon
    - AppLovin
    - Chartboost
    - Facebook Audience
    - Tapjoy
    - UnityAds

    2020.08.28 [v2.0.001]

    Updated SDK:
    - iOS v7.0.0
    - Android v7.0.0

    Facebook Audience mediator updated:
    - iOS v5.10.1
    - Android v5.11.0

    2020.04.29 [v1.3.000]

    Updated SDK:
    - iOS v6.16.0
    - Android v6.16.0

    Added Facebook Audience mediation adapter to resolve issues with the version from IronSource

    2020.03.21 [v1.2.053]

    Android X migration (resolves #12) 
    Updated SDK:
    - iOS v6.15.0
    - Android v6.15.0

    2019.11.12 [v0.2.046]

    Updated docs

    2019.11.11 [v0.2.046]

    Updated docs

    2019.09.25 [v0.2.046]

    Fixed iOS issue with resuming from IronSource rewarded video

    2019.09.17 [v0.2.024]

    Updated SDK:
    - iOS v6.8.5
    - Android v6.10.0
    Added availability to RewardedVideoAdEvent (resolves #3)

    2019.08.16 [v0.1.018]

    Android 64bit support (resolves #8)
    Fixed user id issue (resolves #7)
    Updated minimum iOS version to 9.0

    2019.04.15 [v0.0.015]

    Added getAdvertiserId functionality (resolves #2)

    2019.03.19 [v0.0.010]

    Initial release

    2019.03.19 [v0.0.010]

    Initial release
    - + \ No newline at end of file diff --git a/docs/ironsource/errors/index.html b/docs/ironsource/errors/index.html index 5ed0f544aa2..49ce167a8d8 100644 --- a/docs/ironsource/errors/index.html +++ b/docs/ironsource/errors/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Errors

    ironSource provides an error code mechanism to help you understand errors you may run into during integration or live production. Extract the error data from the Event object as follows:

    var errorCode:String;
    var errorDescription:String;

    if(event.data)
    {
    var error:Object = JSON.parse(event.data);
    errorDescription = error.error_description;
    errorCode = error.error_code;
    }

    Error Codes

    ironSource provides an error feedback mechanism to provide explanation for any failure in the SDK integration. You will receive these errors when something went wrong or an aspect of the integration wasn’t completed correctly.

    The ironSource Error object contains an error code and message. These are all the possible errors and their message based on their functions:

    Error CodesAd UnitDescription
    508N/A- Init failure of the mediation/Network
    - Calling a Demand Only API in non Demand Only mode
    - Calling a non Demand Only API in Demand Only mode
    509Interstital
    Rewarded Video
    Offerwall
    Show Fail: No ads to show
    510InterstitialLoad Fail: Server response failed
    Load Fail: Adapters loading failure
    520InterstitialShow Fail: No internet connection;
    ShouldTrackNetworkState is enabled
    Rewarded Video
    Offerwall
    Show Fail: No internet connection
    524Interstitial
    Rewarded Video
    Offerwall
    Show Fail: Placement %@ has reached its limit as defined per pace
    Show Fail: Placement %@ has reached its capping limit
    526Interstitial
    Rewarded Video
    Show Fail: Ad unit has reached its daily cap per session
    527Interstitial
    Rewarded Video
    Load Fail: Instance does not exist in the waterfall
    Show Fail: Instance does not exist in the waterfall
    1022Rewarded VideoShow Fail: Cannot show an RV while another RV is showing
    1023Rewarded VideoShow Fail: Show RV called when there are no available ads to show
    1036InterstitialShow Fail: Cannot show an interstitial while another interstitial is showing
    1037InterstitialLoad Fail: Cannot load an interstitial while another interstitial is showing
    - + \ No newline at end of file diff --git a/docs/ironsource/index.html b/docs/ironsource/index.html index 64db1b58a08..33fd60cd713 100644 --- a/docs/ironsource/index.html +++ b/docs/ironsource/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:

    ❤️ Sponsor

    IronSource

    IronSource is an AIR Native Extension to access the IronSource advertising SDK for in app monetisation.

    The biggest game developers in the industry trust ironSource with their app businesses because we provide everything they need in one powerful platform.

    IronSource does provide an offical ANE. We developed this extension so we can update it to match the latest native versions without waiting for updates from IronSource directly, which seem to lag behind the native SDKs.

    Features

    • Monetization - One of the industry’s largest in-app ad networks leveraging all available ad units to drive revenue and user engagement.
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference
    • Mediation:
      • AdColony
      • AdMob
      • AppLovin
      • Chartboost
      • Facebook Audience
      • Tapjoy
      • UnityAds

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    IronSource.instance.init( Config.IRONSRC_APP_KEY, [ IronSource.REWARDED_VIDEO ] );

    if (IronSource.instance.isRewardedVideoAvailable())
    {
    IronSource.instance.showRewardedVideo();
    }

    More information here:

    com.distriqt.IronSource

    Native Extensions

    The highest quality and widest range of Native Extensions for Adobe AIR

    With many native extensions available, we are the largest provider of native extensions for AIR developers. Our mobile solutions allow developers to fast-forward development and focus on building great games and apps.

    https://airnativeextensions.com

    - + \ No newline at end of file diff --git a/docs/ironsource/initialisation/index.html b/docs/ironsource/initialisation/index.html index 20aa449c0f7..5a9b6aa0c08 100644 --- a/docs/ironsource/initialisation/index.html +++ b/docs/ironsource/initialisation/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Initialisation

    Before starting to use the Iron Source SDK you must call init() with your Iron Source application key and specify the ad unit types you will be using in your application.

    For example:

    IronSource.instance.init( IRONSRC_APP_KEY,
    [
    IronSource.REWARDED_VIDEO,
    IronSource.INTERSTITIAL
    ]
    );

    Validate Integration

    You can test the state of the integration by calling the validateIntegration() function.

    IronSource.instance.validateIntegration();

    This will output information about the current SDK integration to the native device log. Check here for information on how to access device logs.

    - + \ No newline at end of file diff --git a/docs/ironsource/interstitials/index.html b/docs/ironsource/interstitials/index.html index 9e6a59a88d4..3a5e52e8146 100644 --- a/docs/ironsource/interstitials/index.html +++ b/docs/ironsource/interstitials/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Interstitials

    An interstitial ad is a full-screen static, video or interactive (playable) ad unit that offers users the option to exit and skip. They engage users with rich content at natural pauses in the app’s flow, ensuring minimum disruption to user experience while maximizing user engagement and revenue.

    Load Interstitial

    IronSource.instance.loadInterstitial();

    This will dispatch one of two events when complete:

    • InterstitialAdEvent.READY: If the interstitial was loaded and is now ready to display;
    • InterstitialAdEvent.FAILED: if there was an error loading the advert;
    IronSource.instance.addEventListener( InterstitialAdEvent.READY, onInterstitialAdReady );
    IronSource.instance.addEventListener( InterstitialAdEvent.FAILED, onInterstitialAdLoadFailed );

    IronSource.instance.loadInterstitial();


    function onInterstitialAdReady( event:DataEvent ):void
    {
    trace( "onInterstitialAdReady" );
    }

    function onInterstitialAdLoadFailed( event:DataEvent ):void
    {
    trace( "onInterstitialAdLoadFailed" );
    }

    Check State Of Interstitial

    You can use the isInterstitialReady() flag to determine if an interstitial is loaded and ready to display.

    if (IronSource.instance.isInterstitialReady())
    {
    // Interstitial is loaded and ready to display
    }

    Show Interstitial

    When you are ready to show your interstitial simply call showInterstitial():

    IronSource.instance.showInterstitial();

    Displaying an interstitial will dispatch several events:

    • InterstitialAdEvent.OPENED: The interstitial was opened and is visible to the user;
    • InterstitialAdEvent.CLOSED: The ad was closed by the user;
    • InterstitialAdEvent.SHOW_SUCCEEDED: The interstitial was shown and is visible to the user;
    • InterstitialAdEvent.SHOW_FAILED: There was an error showing the interstitial;
    • InterstitialAdEvent.CLICKED: If the user clicked on the advert;

    For example:

    IronSource.instance.addEventListener( InterstitialAdEvent.OPENED, onInterstitialAdOpened );
    IronSource.instance.addEventListener( InterstitialAdEvent.CLOSED, onInterstitialAdClosed );
    IronSource.instance.addEventListener( InterstitialAdEvent.SHOW_SUCCEEDED, onInterstitialAdShowSucceeded );
    IronSource.instance.addEventListener( InterstitialAdEvent.SHOW_FAILED, onInterstitialAdShowFailed );
    IronSource.instance.addEventListener( InterstitialAdEvent.CLICKED, onInterstitialAdClicked );


    if (IronSource.instance.isInterstitialReady())
    {
    IronSource.instance.showInterstitial();
    }

    function onInterstitialAdOpened( event:DataEvent ):void
    {
    trace( "onInterstitialAdOpened" );
    }

    function onInterstitialAdClosed( event:DataEvent ):void
    {
    trace( "onInterstitialAdClosed" );
    }

    function onInterstitialAdShowFailed( event:DataEvent ):void
    {
    trace( "onInterstitialAdShowFailed" );
    }

    function onInterstitialAdClicked( event:DataEvent ):void
    {
    trace( "onInterstitialAdClicked" );
    }

    function onInterstitialAdShowSucceeded( event:DataEvent ):void
    {
    trace( "onInterstitialAdShowSucceeded" );
    }

    Errors

    See the complete description of the ironSource errors here.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/adcolony/index.html b/docs/ironsource/mediation/adcolony/index.html index f8893475dd9..48d207c7348 100644 --- a/docs/ironsource/mediation/adcolony/index.html +++ b/docs/ironsource/mediation/adcolony/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Mediation - AdColony

    This guide shows how to add mediation through AdColony to your IronSource integration.

    Step 1: Create an AdColony Account

    1. Create an account with AdColony. You can do so here.

    2. Once your account has been verified, you can log in to their partner login here.

    Step 2: Create an Application and Ad Zone in AdColony

    To gain access to AdColony’s inventory within ironSource’s Mediation platform, you must first add your app and set up Ad Zones in your AdColony account.

    https://developers.ironsrc.com/ironsource-mobile/android/adcolony-mediation-guide/#step-2

    Step 3: Activate AdColony in the SDK Networks Setup Module

    There are a few parameters from your AdColony account which need to be inserted into your SDK Network Setup Module on the ironSource platform in order for AdColony to work correctly in connection with ironSource.

    See the following guide for more information:

    https://developers.ironsrc.com/ironsource-mobile/android/adcolony-mediation-guide/#step-3

    Step 4: Add the AdColony Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.AdColony

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.AdColony.ane # AdColony mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    • You will need to set the usage description strings for use in the authorisation dialogs. Call the following to step through the configuration values for this extension:
    apm project config set com.distriqt.ironsource.AdColony

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/admob/index.html b/docs/ironsource/mediation/admob/index.html index 112e1d25af0..69b79c90087 100644 --- a/docs/ironsource/mediation/admob/index.html +++ b/docs/ironsource/mediation/admob/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ and you need to ensure they are packaged with your application.

    You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/amazon/index.html b/docs/ironsource/mediation/amazon/index.html index 38dde90b41c..04b86b2ac93 100644 --- a/docs/ironsource/mediation/amazon/index.html +++ b/docs/ironsource/mediation/amazon/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Mediation - Amazon

    Important!

    As of September 30, 2021 Amazon deprecated Amazon Mobile Ads Network.

    The extension has been removed and this documentation only applies to legacy versions of the extension.

    This guide shows how to add mediation through Amazon to your IronSource integration.

    Step 1: Create an Amazon Account

    1. To access Amazon’s ad inventory through ironSource‘s mediation platform, you must create an account with Amazon. You can do so here.

    Step 2: Create an Application in Amazon

    Next, you must add the app in your Amazon account.

    https://developers.ironsrc.com/ironsource-mobile/android/amazon-mobile-ad-network-integration-guide/#step-2

    Step 3: Activate Amazon in Your ironSource Network Setup Module

    Serving Amazon’s ads through the ironSource mediation platform has never been this easy. Sign in to your Amazon account when setting up Amazon on the ironSource SDK Networks setup page and we’ll automatically retrieve all the necessary parameters to run Amazon’s Banners for you!

    See the following guide for more information:

    https://developers.ironsrc.com/ironsource-mobile/android/amazon-mobile-ad-network-integration-guide/#step-3

    Step 4: Add the Amazon Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.Amazon

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.Amazon.ane # Amazon mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/applovin/index.html b/docs/ironsource/mediation/applovin/index.html index 39e10eda55e..ae7994f936a 100644 --- a/docs/ironsource/mediation/applovin/index.html +++ b/docs/ironsource/mediation/applovin/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Mediation - AppLovin

    This guide shows how to add mediation through AppLovin to your IronSource integration.

    Step 1: Create an AppLovin Account

    1. Create an account with AppLovin. You can do so here.

    2. Once your account has been verified you can login at their partner login here.

    Step 2: Retrieve Your AppLovin SDK and Report Keys

    There are 2 pieces of data from the AppLovin account which need to be inserted into your ironSource Network Setup Module in order for AppLovin to work correctly in connection with ironSource:

    • Report Key: This is a unique identifier for your AppLovin account, which allows your ironSource Mediation Platform to import performance data from your AppLovin account to use in reporting & optimization.
    • SDK Key: This is a unique identifier for your AppLovin account. This is used by the ironSource Mediation SDK to Init the AppLovin Adapter for your apps.

    Once you obtain this information, you must configure the AppLovin parameters in your ironSource Account. By adding the above information correctly, you will be able to take full advantage of AppLovin’s ad inventory and reporting data on ironSource’s Mediation platform.

    https://developers.ironsrc.com/ironsource-mobile/android/applovin-mediation-guide/#step-2

    Step 3: Activate AppLovin on the ironSource SDK Networks Module

    Configure AppLovin’s Parameters into ironSource Account

    See the following guide for more information:

    https://developers.ironsrc.com/ironsource-mobile/android/applovin-mediation-guide/#step-3

    Step 4: Add the AppLovin Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.AppLovin

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.AppLovin.ane # AppLovin mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/chartboost/index.html b/docs/ironsource/mediation/chartboost/index.html index df10ea56f06..4708b3e1675 100644 --- a/docs/ironsource/mediation/chartboost/index.html +++ b/docs/ironsource/mediation/chartboost/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ and you need to ensure they are packaged with your application.

    You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 6: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/digitalturbine/index.html b/docs/ironsource/mediation/digitalturbine/index.html index 0b717370eea..dbab9c944bc 100644 --- a/docs/ironsource/mediation/digitalturbine/index.html +++ b/docs/ironsource/mediation/digitalturbine/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Once your application has been added, you can create an Ad Spot. In Digital Turbine system Ad Spots defines the Placement & Ad Unit to which Digital Turbine delivers ads.
    1. Setup Ad Unit:
    1. Save Ad Unit
    2. Continue twice

    Step 3: Activate Digital Turbine in the SDK Networks Setup Module

    https://developers.is.com/ironsource-mobile/android/fyber-mediation-integration-guide/#step-3

    Step 4: Add the Digital Turbine Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.DigitalTurbine

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ assets
    | |____ android # android assets
    | | |____ ...
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.DigitalTurbine.ane # DigitalTurbine mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

    • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/android folder to the root of your Android application package, i.e. the files in the android folder must be at the root level alongside your swf.

    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Network Security Settings

    info

    This applies to Android only. You will be adding an android resource to your application.

    Digital Turbine SDK requires clear text traffic permission to localhost, when targeting Android P and using video ads. This should be done by adding an exception rule to 'localhost', that can be found in your apps Network Security Configuration.

    Define the Network Security Configuration xml, by creating a file in your resources folder: res/xml/network_security_config.xml and populating it with the following:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
    <base-config cleartextTrafficPermitted="true">
    <trust-anchors>
    <certificates src="system" />
    <certificates src="user" />
    </trust-anchors>
    </base-config>
    <debug-overrides>
    <trust-anchors>
    <certificates src="user" />
    </trust-anchors>
    </debug-overrides>
    <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">127.0.0.1</domain>
    </domain-config>
    </network-security-config>

    You must ensure this resource is packaged correctly with your application. See the tutorial on this process here.

    If you haven't already generated an additional manifest for apm to merge in your application descriptor then run:

    apm generate config android

    Edit the file at config/android/AndroidManifest.xml and add the following:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">

    ...

    <application android:networkSecurityConfig="@xml/network_security_config">

    ...

    Regenerate your app descriptor to apply this additional configuration:

    apm generate app-descriptor src/MyApp-app.xml
    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/facebook-audience/index.html b/docs/ironsource/mediation/facebook-audience/index.html index 4c2732bd788..26e4da6c1a8 100644 --- a/docs/ironsource/mediation/facebook-audience/index.html +++ b/docs/ironsource/mediation/facebook-audience/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Mediation - Facebook Audience

    This guide shows how to add mediation through Facebook Audience to your IronSource integration.

    Step 1: Set up Facebook Audience Network

    Setup Facebook Audience network:

    https://developers.ironsrc.com/ironsource-mobile/air/facebook-mediation-guide/#step-1

    Step 2: Configure mediation settings in IronSource

    There are 3 pieces of Data from the Facebook Audience Network account which need to be inserted into your ironSource Network Setup Module in order for Facebook Audience Network to work correctly in connection with ironSource. See the IronSource guide for more information:

    https://developers.ironsrc.com/ironsource-mobile/air/facebook-mediation-guide/#step-7

    Step 3: Import the Facebook Audience Network SDK and adapter ANE

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.FacebookAudience

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ assets
    | |____ android # android assets
    | | |____ audience_network.dex
    | |____ ios # ios assets
    | | |____ Frameworks
    | | | |____ FBAudienceNetwork.framework
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.FacebookAudience.ane # FacebookAudience mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

    • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/android folder to the root of your Android application package (contains the audience_network.dex file) and the assets/ios folder to the root of your iOS application package (contains the Frameworks folder with required dynamic frameworks).

    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    If you are using an old version of AIR you will need to resign your application following the guide below otherwise your build will likely fail signing validation. AIR 33.1.1.476 or higher do not need this additional step.

    Step 4: Additional code required

    There is no additional code required.

    Step 5: Facebook Additional Settings

    CCPA Support

    If you are using Facebook adapter 4.3.17+, make sure to follow Facebook Audience Network instructions, as described here. Please note that setting FAN Limited Data Use flag, should be done before initializing ironSource Mediation.

    To set this in actionscript call the setDataProcessingOptions() method on the AdSettings instance.

    To explicitly not enable Limited Data Use (LDU) mode, use:

    FacebookAudience.instance.adSettings.setDataProcessingOptions( [] ); 

    To enable LDU for users and specify user geography, use:

    • Country: 1 to indicate USA
    • State: 1000 to indicate California.
    FacebookAudience.instance.adSettings.setDataProcessingOptions( ["LDU"], 1, 1000 ); 

    To enable LDU for users with geolocation, use:

    • Country: 0 to request that we geolocate that event
    • State: 0 to request that we geolocate that event.
    FacebookAudience.instance.adSettings.setDataProcessingOptions( ["LDU"], 0, 0 ); // enable LDU for users with geolocation

    iOS 14+ Support

    If you are using Facebook adapter 4.3.20+, and building for iOS14+, FAN requires you to set the setAdvertiserTrackingEnabled flag. This allows you to inform Facebook whether to use the data to deliver personalized ads. If the flag is set to false FAN will not be able to deliver personalized ads.

    Please note that setting the setAdvertiserTrackingEnabled flag should be done before initializing ironSource Mediation. Learn more about Advertising Tracking Enabled for Audience Network here.

    FacebookAudience.instance.adSettings.setAdvertiserTrackingEnabled( true );

    Signing your iOS application

    This is no longer required since AIR AIR 33.1.1.476

    With AIR 27 Adobe partially added the ability to use dynamic frameworks in your iOS application, which works fine with frameworks you control however still has issues with third party frameworks.

    Everything will work up to a point, however AIR will incorrectly sign your IPA and it will fail AppStore submission with an error from the Application Loader tool and installing development builds with a signature validation error.

    To get around this, before you upload or install your application you will need to run a script to resign your IPA. This script is available in the repository alongside the ANE in the scripts directory.

    This script will only work on a macOS machine with Xcode installed and your certificate installed in Keychain

    Copy this script to a directory in your development environment.

    Firstly edit the script to change the details of the IPA, provisioning profile and signing identity for your application. These details are located at the top of the script.

    #####################################
    ## CONFIG

    # You need to set the values below for your application
    # We suggest they are full paths to the files.

    # The path to the ipa generated from your AIR application packaging
    IPA="/path/to/yourApp.ipa"

    # The distribution provisioning profile for your application
    PROVISIONING_PROFILE="/path/to/profile.mobileprovision"

    # The name of the signing identity. You get this by running the following in a terminal
    # and selecting the name of your distribution certificate:
    #
    # security find-identity -v -p codesigning
    SIGNING_IDENTITY="iPhone Distribution: XXXXXXXXX (XXXXX)"

    Now open a Terminal at the script location. You will need to run the script from this directory.

    ./resign

    This should output a few informational items to the console and then once complete you should have a new IPA file in the directory named: yourApp_resigned.ipa. If there were any errors or warnings displayed, make sure the information above is all correct.

    This resigned IPA is the file you should use.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/tapjoy/index.html b/docs/ironsource/mediation/tapjoy/index.html index c7410565b00..fccf72b0368 100644 --- a/docs/ironsource/mediation/tapjoy/index.html +++ b/docs/ironsource/mediation/tapjoy/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Mediation - Tapjoy

    This guide shows how to add mediation through Tapjoy to your IronSource integration.

    Step 1: Create a Tapjoy Account

    1. Create an account with Tapjoy. You can do so here.

    2. Click on the link in the confirmation email to verify your account. Once your account has been verified, you can log in to their partner login here.

    Step 2: Create an Application in Tapjoy

    To gain access to Tapjoy’s inventory within ironSource‘s Mediation platform, you must first add your app and set up Ad Zones in your Tapjoy account.

    https://developers.ironsrc.com/ironsource-mobile/android/tapjoy-mediation-guide/#step-2

    Step 3: Add Placement, Virtual Currency and Content

    https://developers.ironsrc.com/ironsource-mobile/android/tapjoy-mediation-guide/#step-3

    Step 4: Activate Tapjoy on ironSource SDK Networks Module

    There are a few pieces of data from your Tapjoy account which need to be inserted into your ironSource Network Setup Module in order for Tapjoy to work correctly in connection with ironSource

    See the following guide for more information:

    https://developers.ironsrc.com/ironsource-mobile/android/tapjoy-mediation-guide/#step-4

    Step 5: Add the Tapjoy Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.Tapjoy

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.Tapjoy.ane # Tapjoy mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/unityads/index.html b/docs/ironsource/mediation/unityads/index.html index e52acd2df32..eafbe91820e 100644 --- a/docs/ironsource/mediation/unityads/index.html +++ b/docs/ironsource/mediation/unityads/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Mediation - UnityAds

    This guide shows how to add mediation through UnityAds to your IronSource integration.

    Step 1: Create a UnityAds Account

    1. Create an account with UnityAds. You can do so here.

    2. Once your account has been verified you can log in at their partner login here.

    Step 2: Create an Application and Placement in UnityAds

    Follow these steps to create your UnityAds application:

    https://developers.ironsrc.com/ironsource-mobile/android/unityads-mediation-guide/#step-2

    Step 3: Activate UnityAds on ironSource Network SDK Setup

    https://developers.ironsrc.com/ironsource-mobile/android/unityads-mediation-guide/#step-3

    Step 4: Add the UnityAds Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.UnityAds

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.UnityAds.ane # UnityAds mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Additional code required

    There is no additional code required.

    - + \ No newline at end of file diff --git a/docs/ironsource/mediation/vungle/index.html b/docs/ironsource/mediation/vungle/index.html index 80d1cf25c48..922fea64a1f 100644 --- a/docs/ironsource/mediation/vungle/index.html +++ b/docs/ironsource/mediation/vungle/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Mediation - Vungle

    This guide shows how to add mediation through Vungle to your IronSource integration.

    Step 1: Create a Vungle Account

    1. Create an account with Vungle. You can do so here.

    2. Once your account has been verified you can log in at their partner login here.

    Step 2: Create an Application in Vungle

    Follow these steps to create your Vungle application:

    https://developers.is.com/ironsource-mobile/android/vungle-mediation-guide/#step-2

    Step 3: Add a Placement

    https://developers.is.com/ironsource-mobile/android/vungle-mediation-guide/#step-3

    Step 4: Activate Vungle on ironSource SDK Networks Module

    https://developers.is.com/ironsource-mobile/android/vungle-mediation-guide/#step-4

    Step 5: Add the Vungle Adapter to Your Build

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Add the Extension

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ironsource.Vungle

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.IronSource.ane # IronSource extension
    | |____ com.distriqt.ironsource.Vungle.ane # Vungle mediation extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Step 5: Vungle Additional Settings

    COPPA User status

    ironSource's mediation lets publishers communicate Vungle COPPA settings directly to the Vungle network. This feature is enabled using ironSource SDK 7.1.12+, Vungle Android Adapter 4.3.15+. Read more about Vungle COPPA API here.

    Use the following syntax, to update Vungle's COPPA User Status with the parameter “True”:

    IronSource.service.setMetaData( "Vungle_coppa", "true" );

    Use the following syntax, to update Vungle's COPPA User Status with the parameter “False”:

    IronSource.service.setMetaData( "Vungle_coppa", "false" );
    - + \ No newline at end of file diff --git a/docs/ironsource/migrating-to-androidx/index.html b/docs/ironsource/migrating-to-androidx/index.html index 285d952f4fa..02e46353eb4 100644 --- a/docs/ironsource/migrating-to-androidx/index.html +++ b/docs/ironsource/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/ironsource/offerwall/index.html b/docs/ironsource/offerwall/index.html index 6b0ff4bb1b4..7188cadc6a7 100644 --- a/docs/ironsource/offerwall/index.html +++ b/docs/ironsource/offerwall/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Offerwall

    The offerwall is an in-app advertising unit that app developers use to monetize their apps. It acts like a mini-store in an app, listing multiple “offers” that users can complete in exchange for receiving an in-app reward. For example, users can receive extra in-app coins if they choose to register a username, get to level 25 on a game, make an in-app purchase, and more on the offerwall.

    Availability

    You can check whether the offerwall is currently available at any time by checking the isOfferwallAvailable() method:

    if (IronSource.instance.isOfferwallAvailable())
    {
    // Offerwall is available
    }

    You can also listen for the OfferwallEvent.AVAILABLE to respond to changes in the availability of the offerwall.

    IronSource.instance.addEventListener( OfferwallEvent.AVAILABLE, offerwallAvailabilityHandler );

    function offerwallAvailabilityHandler( event:OfferwallEvent ):void
    {
    // Offerwall availability has changed

    if (IronSource.instance.isOfferwallAvailable())
    {
    // Offerwall is available
    }
    }

    Present the Offerwall

    Once the Offerwall is available you can call showOfferwall() to present the offerwall to your user (typically done after a user clicks on some in-app button).

    IronSource.instance.showOfferwall();

    You should always check if the offerwall is available before showing and react accordingly:

    if (IronSource.instance.isOfferwallAvailable())
    {
    IronSource.instance.showOfferwall();
    }
    else
    {
    // Inform user feature not available currently
    }

    There are several events associated with the display of the offerwall:

    • OfferwallEvent.OPENED: Dispatched when the Offerwall is opened;
    • OfferwallEvent.CLOSED: Dispatched when the Offerwall is closed;
    • OfferwallEvent.SHOW_FAILED: Dispatched if the Offerwall failed to show;
    IronSource.instance.addEventListener( OfferwallEvent.OPENED, openedHandler );
    IronSource.instance.addEventListener( OfferwallEvent.CLOSED, closedHandler );
    IronSource.instance.addEventListener( OfferwallEvent.SHOW_FAILED, errorHandler );

    if (IronSource.instance.isOfferwallAvailable())
    {
    IronSource.instance.showOfferwall();
    }


    function openedHandler( event:OfferwallEvent ):void
    {
    // Offerwall opened
    }

    function closedHandler( event:OfferwallEvent ):void
    {
    // Offerwall closed
    }

    function errorHandler( event:OfferwallEvent ):void
    {
    // Check event details for error information
    }

    Reward the User

    There are 2 methods of rewarding your user, using:

    • Client side callbacks;
    • Server side callbacks;

    Client side

    Proactive polling

    You can poll at any time to retrieve the user's total credits and any new credits.

    To do this call the getOfferwallCredits() function and await the following events:

    • OfferwallEvent.AD_CREDITED: Dispatched when the call completes successfully, the event will contain the current user credits;
    • OfferwallEvent.GETOFFERWALLCREDITS_FAILED: Dispatched if there was an error retrieving the user's credits;
    IronSource.instance.addEventListener( OfferwallEvent.AD_CREDITED, adCreditedHandler );
    IronSource.instance.addEventListener( OfferwallEvent.GETOFFERWALLCREDITS_FAILED, errorHandler );

    IronSource.instance.getOfferwallCredits();


    function adCreditedHandler( event:OfferwallEvent ):void
    {
    trace( " credits=" + event.credits );
    trace( " totalCredits=" + event.totalCredits );
    trace( " totalCreditsFlag=" + event.totalCreditsFlag );
    }

    function errorHandler( event:OfferwallEvent ):void
    {
    // Check event details for error information
    }

    The details retrieved in the event are:

    • credits : The number of credits the user has earned since the last OfferwallEvent.AD_CREDITED event. Note that the credits may represent multiple completions;
    • totalCredits : The total number of credits ever earned by the user;
    • totalCreditsFlag : In some cases, we won’t be able to provide the exact amount of credits since the last event (specifically if the user clears the app’s data). In this case the credits will be equal to the totalCredits, and this flag will be true;

    Automatic Events

    You can also enable automatic client side events by calling setIronSourceClientSideCallbacks( true ) before you initialise the IronSource SDK.

    Setting automatic client-side callbacks will make sure that you’re notified about the user’s credit status at specific points in the Offerwall’s lifecycle.

    IronSource.instance.setIronSourceClientSideCallbacks(true);

    IronSource.instance.init( ... );

    Important! This code MUST be implemented before calling the init.

    Using this method the OfferwallEvent.AD_CREDITED will be dispatched automatically as part of the offerwall lifecycle.

    Server side

    See the ironSource documentation for details on server side callbacks and rewarding users.

    If you turn on server-to-server callbacks in addition to the client-side callbacks, remember not to reward the user more than once for the same completion. ironSource will fire both the client-side callback and the server-to-server callback. You will get two notifications for each completion.

    Errors

    See the complete description of the ironSource errors here.

    - + \ No newline at end of file diff --git a/docs/ironsource/rewarded-video/index.html b/docs/ironsource/rewarded-video/index.html index cf24995abcf..6894ba5e580 100644 --- a/docs/ironsource/rewarded-video/index.html +++ b/docs/ironsource/rewarded-video/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Rewarded Video

    Rewarded videos are opt-in ad units that encourage users to watch a video in order to receive in-app rewards.

    Availability

    To check if a rewarded video is available use the isRewardedVideoAvailable() flag:

    if (IronSource.instance.isRewardedVideoAvailable())
    {
    // Rewarded Video available
    }

    You can also listen for the RewardedVideoAdEvent.AVAILABILITY_CHANGED event to determine when the value of this flag changes.

    IronSource.instance.addEventListener( RewardedVideoAdEvent.AVAILABILITY_CHANGED, onRewardedVideoAvailabilityChanged );

    function onRewardedVideoAvailabilityChanged( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAvailabilityChanged: " + event.availability );
    }

    Show Rewarded Video

    To display a rewarded video once one is available you call the showRewardedVideo() function:

    if (IronSource.instance.isRewardedVideoAvailable())
    {
    IronSource.instance.showRewardedVideo();
    }

    This will dispatch several events at different stages of the video:

    • RewardedVideoAdEvent.OPENED: The rewarded video ad was opened;
    • RewardedVideoAdEvent.CLOSED: The rewarded video ad was closed by the user;
    • RewardedVideoAdEvent.STARTED: The rewarded video playback started;
    • RewardedVideoAdEvent.ENDED: The rewarded video playback ended;
    • RewardedVideoAdEvent.REWARDED: Dispatched when you should reward your user;
    • RewardedVideoAdEvent.SHOW_FAILED: The rewarded video failed to be displayed;
    • RewardedVideoAdEvent.CLICKED: Dispatched if the user clicks the rewarded video ad;

    Example

    IronSource.instance.addEventListener( RewardedVideoAdEvent.OPENED, onRewardedVideoAdOpened );
    IronSource.instance.addEventListener( RewardedVideoAdEvent.CLOSED, onRewardedVideoAdClosed );
    IronSource.instance.addEventListener( RewardedVideoAdEvent.STARTED, onRewardedVideoAdStarted );
    IronSource.instance.addEventListener( RewardedVideoAdEvent.ENDED, onRewardedVideoAdEnded );
    IronSource.instance.addEventListener( RewardedVideoAdEvent.REWARDED, onRewardedVideoAdRewarded );
    IronSource.instance.addEventListener( RewardedVideoAdEvent.SHOW_FAILED, onRewardedVideoAdShowFailed );
    IronSource.instance.addEventListener( RewardedVideoAdEvent.CLICKED, onRewardedVideoAdClicked );


    if (IronSource.instance.isRewardedVideoAvailable())
    {
    IronSource.instance.showRewardedVideo();
    }


    function onRewardedVideoAdShowFailed( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdShowFailed" );
    }

    function onRewardedVideoAdOpened( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdOpened" );
    }

    function onRewardedVideoAdClosed( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdClosed" );
    }

    function onRewardedVideoAdStarted( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdStarted" );
    }

    function onRewardedVideoAdEnded( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdEnded" );
    }

    function onRewardedVideoAdRewarded( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdRewarded" );
    }

    function onRewardedVideoAdClicked( event:RewardedVideoAdEvent ):void
    {
    trace( "onRewardedVideoAdClicked" );
    }

    Errors

    See the complete description of the ironSource errors here.

    - + \ No newline at end of file diff --git a/docs/isallmediators/changelog/index.html b/docs/isallmediators/changelog/index.html index cc38936211c..6b4e14fa514 100644 --- a/docs/isallmediators/changelog/index.html +++ b/docs/isallmediators/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2022.10.04 [v1.1.0]

    feat(adcolony): update adcolony sdk: android v4.3.13 (v4.8.0) ios v4.3.15 (v4.9.0)
    feat(applovin): update applovin sdk: android v4.3.34 (v11.5.0) ios v4.3.35 (v11.5.0)
    fix(admob): correct missing appset dependency
    - + \ No newline at end of file diff --git a/docs/jobscheduler/add-the-extension/index.html b/docs/jobscheduler/add-the-extension/index.html index b6deb480a62..95c57e437b6 100644 --- a/docs/jobscheduler/add-the-extension/index.html +++ b/docs/jobscheduler/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.JobScheduler

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.JobScheduler.ane # JobScheduler extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (JobScheduler.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/jobscheduler/application-termination/index.html b/docs/jobscheduler/application-termination/index.html index 621d1bd56b0..8a964ab6344 100644 --- a/docs/jobscheduler/application-termination/index.html +++ b/docs/jobscheduler/application-termination/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Application Termination

    Schedule Termination

    To schedule a termination, call the scheduleTermination method. The method takes one parameter which is the delay (in milliseconds) before termination will occur.

    Calling this function will schedule a job with the Android system that will be called at the specified delay.

    For example to terminate the application in 4 seconds:

    JobScheduler.instance.scheduleTermination( 4000 );

    Cancel Termination

    If you wish to cancel the schedule termination simply call cancelTermination. This will remove the scheduled job from the system.

    JobScheduler.instance.cancelTermination();
    - + \ No newline at end of file diff --git a/docs/jobscheduler/changelog/index.html b/docs/jobscheduler/changelog/index.html index d39da812dee..3bc9327a4e8 100644 --- a/docs/jobscheduler/changelog/index.html +++ b/docs/jobscheduler/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v1.1.0]

    feat(airpackage): update to support latest Core extension with major Android / iOS updates

    2021.12.06 [v1.0.24]

    Add airpackage

    2021.03.12 [v1.0.023]

    Updated to latest build process  
    Added Android-x64 support

    2020.03.24 [v1.0.019]

    Android X migration (resolves #6)

    2019.07.04 [v0.0.017]

    Android 64bit support (resolves #5)

    2018.08.09 [v0.0.015]

    Rebuild to ensure updated default lib implementation (#1)

    2018.08.09 [v0.0.011]

    Initial release
    - + \ No newline at end of file diff --git a/docs/jobscheduler/index.html b/docs/jobscheduler/index.html index 009c1024126..7cfbc583a5a 100644 --- a/docs/jobscheduler/index.html +++ b/docs/jobscheduler/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    JobScheduler

    The JobScheduler extension is an AIR Native Extension that allows you to schedule particular tasks.

    This extension was developed for usage in resolution of the Adobe AIR Android ANR issue, as discussed:

    Features

    • Schedule application termination;
    • Cancel application termination;

    Documentation

    Latest documentation can be found in the documentation site along with the asdocs.

    Quick Example:

    JobScheduler.instance.scheduleTermination( 2000 );
    - + \ No newline at end of file diff --git a/docs/localauth/add-the-extension/index.html b/docs/localauth/add-the-extension/index.html index 0bde46dcd89..b205d68164b 100644 --- a/docs/localauth/add-the-extension/index.html +++ b/docs/localauth/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Android Support

    The Android Support libraries encompass the Android Support, Android X and common Google libraries.

    These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

    This extension requires the following extensions:

    You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

    Note: if you have been using the older com.distriqt.androidsupport.* (Android Support) extensions you should remove these extensions and replace it with the androidx extensions listed above. This is the new version of the android support libraries and moving forward all our extensions will require AndroidX.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (LocalAuth.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/localauth/biometric-authentication/index.html b/docs/localauth/biometric-authentication/index.html index 39e4f677b4e..37d45a0ddda 100644 --- a/docs/localauth/biometric-authentication/index.html +++ b/docs/localauth/biometric-authentication/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ once. You should respect this decision and provide the ability for the user to authenticate using your normal method.

    You can also specify the biometry type to be used if you require:

    LocalAuth.service.authenticateWithBiometryType( 
    "Unlock access to locked feature",
    BiometryType.FINGERPRINT
    );
    note

    Specifying the biometry type may return false when the biometry type is not supported

    Cancel Authentication

    If you wish to programatically cancel the authentication process you can call cancelAuthenticate.

    LocalAuth.service.cancelAuthenticate();

    After calling this you should receive an AUTH_FAILED event to indicate the failure of the authentication process (if an authentication process was occurring at the time).

    - + \ No newline at end of file diff --git a/docs/localauth/changelog/index.html b/docs/localauth/changelog/index.html index 3b4f82b2129..492c2d471e0 100644 --- a/docs/localauth/changelog/index.html +++ b/docs/localauth/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.23 [v3.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.02.08 [v3.0.11]

    Update package descriptions
    Update docs to use apm

    2021.10.07 [v3.0.10]

    Add air package

    2021.10.07 [v3.0.10]

    Add air package

    2021.04.23 [v3.0.008]

    Updated documentation (resolves #15) Android x64 support

    2020.03.20 [v3.0.006]

    Android X migration (resolves #13)

    2019.08.15 [v2.0.002]

    Android 64bit support (resolves #11)
    Updated minimum iOS version to 9.0

    2019.03.02 [v1.2.044]

    Updated minimum iOS version to 8.0 (resolves #10)
    Embedded iOS bitcode

    2018.11.13 [v1.1.042]

    FaceID integration (resolves #7)

    2017.07.10 [v1.0.038]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.03.16 [v1.0.037]

    Fixed issue with canAuthenticateWithFingerprint (#5)

    2017.03.14 [v1.0.034]

    Fixed issue with canAuthenticateWithFingerprint (#5)

    2017.02.07 [v1.0.033]

    Added ability to cancel authentication process (resolves #3)

    2017.01.12 [v1.0.028]

    Updated documentation

    2016.12.30 [v1.0.027]

    Initial release

    2016.12.30 [v0.0.026]

    Updated documentation
    - + \ No newline at end of file diff --git a/docs/localauth/index.html b/docs/localauth/index.html index c6ded81b8d4..88ddda65b97 100644 --- a/docs/localauth/index.html +++ b/docs/localauth/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ application ensuring that unauthorised users aren't gaining access to sensitive information.

    The API is very simple and the underlying extension handles all of the authentication and uses a universal UI that your users will be familiar with.

    Features

    Support

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    if (LocalAuth.service.canAuthenticateWithFingerprint())
    {
    LocalAuth.service.addEventListener( LocalAuthEvent.AUTH_SUCCESS, authSuccessHandler );
    LocalAuth.service.addEventListener( LocalAuthEvent.AUTH_FAILED, authFailedHandler );
    LocalAuth.service.authenticateWithFingerprint( "Unlock access to locked feature" );
    }

    More information here:

    com.distriqt.LocalAuth

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/localauth/migrating-to-androidx/index.html b/docs/localauth/migrating-to-androidx/index.html index 2fa7141d287..1acab671175 100644 --- a/docs/localauth/migrating-to-androidx/index.html +++ b/docs/localauth/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/localauth/request-authorisation/index.html b/docs/localauth/request-authorisation/index.html index 35e1d969d39..c4eca68e261 100644 --- a/docs/localauth/request-authorisation/index.html +++ b/docs/localauth/request-authorisation/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Authorisation

    Usage Description

    On iOS when the first attempt to use biometric authorisation is performed the user will be presented an authorisation dialog. You can customise this dialog by setting the NSFaceIDUsageDescription. The image below is an example of the authorisation dialog:

    You set these values through adding the usage description keys to your info additions or simply by setting up your configuration options in your apm project.

    caution

    If you don't set this value your application may be terminated by the OS when you attempt to authenticate.

    - + \ No newline at end of file diff --git a/docs/location/add-the-extension/index.html b/docs/location/add-the-extension/index.html index a6929407091..857e632f56c 100644 --- a/docs/location/add-the-extension/index.html +++ b/docs/location/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Background Location

    On Android, if you require access to the location data in the background or if you are using geofences then you must also add the background permission:

    <!-- NEEDED FOR BACKGROUND LOCATION AND GEOFENCES -->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

    To add this you need to add some additional configuration to apm. Firstly add a custom Android configuration file by running:

    apm generate config android

    Edit the config/android/AndroidManifest.xml file that was generated to resemble the following, adding the required permissions, i.e.:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

    </manifest>

    You can add any other additions you require in your application here and these will be merged by apm when you generate your application descriptor (see above).

    iOS Background Updates

    If you are planning to setup your application to receive background updates then you should include the UIBackgroundModes key, (however it is not required). If it is enabled, you will be able to receive updates in the background to trigger an event when your application is running in the background (and you have been granted the ALWAYS authorisation by the user, see later). If you don't add it, then you will only receive the updates when the application is running in the foreground.

    Currently due to an AIR bug we can't receive location updates on iOS when the application isn't running. This is due to a bug where AIR applications cannot "start into the background" on iOS.

    To add these additions you need to add some additional configuration. Firstly add a custom iOS configuration file by running:
    apm generate config ios

    Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the UIBackgroundModes node:

    <plist version="1.0">
    <dict>

    <!-- Required if you wish to receive background location updates -->
    <key>UIBackgroundModes</key>
    <array>
    <string>location</string>
    </array>

    </dict>
    </plist>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    - + \ No newline at end of file diff --git a/docs/location/changelog/index.html b/docs/location/changelog/index.html index afd44f306c2..1c8e5209c43 100644 --- a/docs/location/changelog/index.html +++ b/docs/location/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.07.05 [v5.0.0]

    feat(android): update to android location services v21.0.1 including some changes to the location request

    2023.05.18 [v4.5.1]

    fix(android): remove unused encryption code

    2023.01.23 [v4.5.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
    feat(android): Move to new permissions request process

    2022.03.28 [v4.4.0]

    Update documentation for Android 31
    Update Android permissions process to support new location permissions

    2022.02.08 [v4.3.1]

    Update package and docs for Android 31
    Update docs to use apm
    Fix missing dependency in air packages

    2021.11.09 [v4.3.0]

    Add isMockLocation detection on reported location (resolves #66)

    2021.10.07 [v4.2.20]

    Add air package
    Update Android permission requests
    Add security flag to auth activity
    Remove iOS minimum version flag

    2020.08.12 [v4.1.009]

    Corrected documentation on AndroidX (resolves #61)
    Moved to latest version of Core iOS dependencies

    2020.03.20 [v4.0.006]

    Android X migration (resolves #58)

    2019.08.15 [v3.0.002]

    Android 64bit support (resolves #54)
    Updated minimum iOS version to 9.0

    2019.02.13 [v2.2.045]

    Added geocoding docs

    2019.02.11 [v2.2.044]

    Geocoder implementation
    Embedded bitcode

    2018.11.27 [v2.1.018]

    Updated to Google Play Services v16.0.5
    Removed application keys

    2018.09.10 [v2.0.016]

    Android: Added persistInBackground to run background updates in a foreground service (resolves #48)
    Android: Resolved issue with updates on Android 8+ (resolves #51)

    2018.06.29 [v1.6.093]

    iOS: Removed preferences references due to Apple review policy change (#50)

    2018.06.25 [v1.6.090]

    iOS: Removed preferences references due to Apple review policy change (#50)

    2018.03.16 [v1.6.089]

    Documentation update

    2018.03.16 [v1.6.089]

    Android: Added checkLocationSettings to turn on settings from app (resolves #47) 

    2018.01.29 [v1.6.070]

    Updated documentation for iOS 11 (#45)

    2017.12.15 [v1.6.070]

    iOS: Corrected heading issue (resolves #44)

    2017.09.04 [v1.6.067]

    iOS: Fixed duplicate region entry events (resolves #39)

    2017.09.01 [v1.6.063]

    Added ability to set priority on iOS (#38)

    2017.08.24 [v1.6.059]

    Android: Added ability to start app on geofence entry
    Android: Added restoring geofences on boot (resolves #31)
    iOS: Corrected display settings on iOS 10+ (#33)
    Android: Corrected null api issues (resolves #30)
    Android: Corrected starting multiple geofences (resolves #27)
    Added distance calculations between positions

    2017.08.14 [v1.5.027]

    Documentation update + minor fix for Android

    2017.08.10 [v1.5.026]

    Removed references to old docs (resolves #29)

    2017.07.10 [v1.5.022]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.06.21 [v1.5.021]

    Added minimum interval for update calls (#26)

    2017.06.21 [v1.4.017]

    Added documentation on update Url (#26)

    2017.05.06 [v1.4.017]

    Updated documentation (resolves #23)

    2017.04.28 [v1.4.017]

    Android: Fixed issue with flight mode incorrectly reporting not available (resolves #18)

    2017.04.28 [v1.3.015]

    Added handling of outdated Google Play Services (resolves #21)

    2017.01.31 [v1.2.011]

    Updated documentation + update to Google Play Services v10.0.1

    2017.01.18 [v1.2.009]

    iOS: Added some checks for corrupted regions (#13)

    2017.01.16 [v1.2.008]

    Updated documentation, minor log output changes

    2016.12.29 [v1.2.002]

    Latest SDKs + Updated documentation

    2016.11.14 [v1.2.002]

    Added ability to display the location settings

    2016.10.30 [v1.1.003]

    Corrected IN_USE definition (resolves #4)
    iOS: Corrected operation with removal of UIBackgroundModes (resolves #5)

    2016.09.09 [v1.1.001]

    Corrected Android runtime permissions (resolves #1)

    2016.09.08 [v1.0.002]

    Android: Corrected authorisation status (resolves #1)

    2016.08.24 [v1.0.001]

    Updated documentation

    2016.08.24 [v1.0.001]

    Release v1.0

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support
    - + \ No newline at end of file diff --git a/docs/location/device-location-settings/index.html b/docs/location/device-location-settings/index.html index 0d56a3b4839..abae694a0e6 100644 --- a/docs/location/device-location-settings/index.html +++ b/docs/location/device-location-settings/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Device Location Settings

    Device settings are separate from authorisation. While your application may be authorised to access the user's location they may have disabled their devices GPS or WiFi making receiving location updates difficult or impossible.

    There are several utility functions in this extension to aid in this process.

    • isAvailable: Checks to see if the GPS / WiFi services are enabled
    • displayLocationSettings: Redirects the user to the location settings
    • checkLocationSettings: Android utility to enable services directly from your application

    Is Available

    The available flag will check whether the location services are enabled on the device.

    • iOS: This checks the CLLocationManager locationServicesEnabled flag. The user can enable or disable location services from the Settings app by toggling the Location Services switch in General.

    • Android: This checks if GPS and WiFi are enabled and the state of the airplane mode on the device.

    var available:Boolean = Location.service.isAvailable();

    Display Settings

    If the services aren't available you can ask your user to enable them and then use the displayLocationSettings function to redirect them to the appropriate place in the settings.

    For example if the services aren't available:

    if (Location.service.isAvailable()) 
    {
    Location.service.displayLocationSettings();
    }

    This will redirect them to the following screens:

    AndroidiOS

    Note: From iOS 11 you can only get redirected to the application settings screen not the location settings

    Change Settings

    On Android you have the ability to ask the user to change the location services directly from your application.

    Calling checkLocationSettings with your LocationRequest will check if the device currently has the correct services enabled to support the location request. The major factor here is the priority of the request which specifies which services will need to be enabled.

    var request:LocationRequest = new LocationRequest();
    request.priority = LocationRequest.PRIORITY_HIGH_ACCURACY;

    var success:Boolean = Location.service.checkLocationSettings( request );

    The return value of this function indicates whether the current device platform and version supports the settings check. If it returns false you should not expect any changes to the settings automatically and you'll need to open the device settings as above.

    If it returns true then you can expect one of two events:

    • LocationSettingsEvent.SUCCESS : Location settings are now valid for the specified location request
    • LocationSettingsEvent.FAILED : location settings check failed for the specified location request. The user probably denied enabling the services.

    During this process there may be a dialog presented to the user to ask to enable the required services, if they currently are disabled:

    For example:

    var request:LocationRequest = new LocationRequest();
    request.priority = LocationRequest.PRIORITY_HIGH_ACCURACY;

    Location.service.addEventListener( LocationSettingsEvent.SUCCESS, checkLocationSettingsHandler );
    Location.service.addEventListener( LocationSettingsEvent.FAILED, checkLocationSettingsHandler );

    var success:Boolean = Location.service.checkLocationSettings( request );
    if (!success)
    {
    Location.service.displayLocationSettings();
    }

    function checkLocationSettingsHandler( event:LocationSettingsEvent ):void
    {
    trace( event.type );
    }
    - + \ No newline at end of file diff --git a/docs/location/geocoding/index.html b/docs/location/geocoding/index.html index 3206612cba4..e7819ac310d 100644 --- a/docs/location/geocoding/index.html +++ b/docs/location/geocoding/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Geocoding

    Geocoding is the process of transforming a street address or other description of a location into a (latitude, longitude) coordinate. Reverse geocoding is the process of transforming a (latitude, longitude) coordinate into a (partial) address. The amount of detail in a reverse geocoded location description may vary, for example one might contain the full street address of the closest building, while another might contain only a city name and postal code.

    Geocoding is provided through the Location.service.geocoder variable which is an instance of the Geocoder interface.

    Support

    Not every device will support geocoding. Android devices require a backend service that is not included in the core android framework, however most of the major handset providers do provide this.

    In order to determine if geocoding is available you should check the isSupported flag.

    if (Location.service.geocoder.isSupported)
    {
    // Geocoding supported
    }

    If geocoding returns false you should not expect any of the other functionality of the Geocoder implementation to function.

    Reverse Geocoding

    Reverse-geocoding requests take a latitude and longitude value and find a user-readable address.

    This is done by using the getFromLocation() function and passing the latitude and longitude of interest.

    This function will return either true or false indicating whether the operation was started successfully. You also need to pass in a maxResults value, indicating the maximum number of results you wish to be returned.

    var success:Boolean = Location.service.geocoder.getFromLocation( -27.493222, 152.9912969, 5 );

    Calling getFromLocation() will result in an event being dispatch when the geocoding is complete:

    • GeocoderEvent.GET_FROM_LOCATION_COMPLETE: Dispatched when the call has completed and geocoding results are available

    When the complete event is dispatched the event will contain the array of geocoded addresses. An address is represented by the Address class:

    Location.service.geocoder.addEventListener( GeocoderEvent.GET_FROM_LOCATION_COMPLETE, completeHandler );
    Location.service.geocoder.getFromLocation( -27.493222, 152.9912969, 5 );

    function completeHandler( event:GeocoderEvent ):void
    {
    for each (var address:Address in event.addresses)
    {
    for (var i:int = 0; i < address.addressLines.length; i ++)
    {
    message( "ADDRESS: " + address.addressLines[i] );
    }
    message( "ADDRESS: locality : " + address.locality );
    message( "ADDRESS: postCode : " + address.postCode );
    message( "ADDRESS: country : " + address.countryName );
    }
    }

    Forward Geocoding

    Forward-geocoding requests take a user-readable address and find the corresponding latitude and longitude value. Forward-geocoding requests may also return additional information about the specified location, such as a point of interest or building at that location.

    This is done by using the getFromLocationName() function and passing the string description of the location.

    This function will return either true or false indicating whether the operation was started successfully. You also need to pass in a maxResults value, indicating the maximum number of results you wish to be returned.

    var success:Boolean = Location.service.geocoder.getFromLocationName( "Parliament Dr, Canberra ACT 2600", 5 );

    Calling getFromLocation() will result in an event being dispatch when the geocoding is complete:

    • GeocoderEvent.GET_FROM_LOCATION_NAME_COMPLETE: Dispatched when the call has completed and geocoding results are available

    When the complete event is dispatched the event will contain the array of geocoded addresses. An address is represented by the Address class:

    Location.service.geocoder.addEventListener( GeocoderEvent.GET_FROM_LOCATION_NAME_COMPLETE, completeHandler );
    Location.service.geocoder.getFromLocationName( "Parliament Dr, Canberra ACT 2600", 5 );

    function completeHandler( event:GeocoderEvent ):void
    {
    for each (var address:Address in event.addresses)
    {
    for (var i:int = 0; i < address.addressLines.length; i ++)
    {
    message( "ADDRESS: " + address.addressLines[i] );
    }
    message( "ADDRESS: locality : " + address.locality );
    message( "ADDRESS: postCode : " + address.postCode );
    message( "ADDRESS: country : " + address.countryName );
    }
    }
    - + \ No newline at end of file diff --git a/docs/location/geofences/index.html b/docs/location/geofences/index.html index 86a69b28aac..1983aa33595 100644 --- a/docs/location/geofences/index.html +++ b/docs/location/geofences/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Geofences

    Authorisation

    In order to use Geofences you should request the ALWAYS authorisation. Apps with geofencing capabilities should use Always authorization due to the need to monitor geofences even when the app isn’t running in the foreground.

    Additionally you need to have added the location UIBackgroundModes on iOS.

    Start Monitoring a Geofence Region

    To start monitoring a region you create a Region instance representing the Geofenced region. This object has a location (latitude and longitude) and a radius to specify the location and size of the region, and you should also assign a region a unique identifier so you can later identify the region that was entered/exited.

    The radius represents the distance in meters from the specified location, at which the system will trigger the notification.

    Once you have defined your region you start monitoring by calling startMonitoringRegion. You can call this multiple times if you wish to monitor several regions.

    Location.service.geofences.addEventListener( RegionEvent.START_MONITORING, startMonitoringHandler );
    Location.service.geofences.addEventListener( RegionEvent.ENTER, enterHandler );
    Location.service.geofences.addEventListener( RegionEvent.EXIT, exitHandler );

    var region:Region = new Region();
    region.identifier = "some-unique-id";
    region.latitude = 14.123456;
    region.longitude = 12.345678;
    region.radius = 100;

    var success:Boolean = Location.service.geofences.startMonitoringRegion( region );

    function startMonitoringHandler( event:RegionEvent ):void
    {
    trace( "start monitor: "+event.region.identifier );
    }


    function enterHandler( event:RegionEvent ):void
    {
    trace( "region enter: "+event.region.identifier );
    }

    function exitHandler( event:RegionEvent ):void
    {
    trace( "region exit: "+event.region.identifier );
    }

    Android

    On Android you can trigger your application to start if it is not running by setting the startApplicationOnEnter flag on the region. If you set this flag to true then when the device enters the region your application will be automatically started.

    var region:Region = new Region();
    region.startApplicationOnEnter = true;

    The default is false.

    Stop Monitoring a Geofence Region

    Stopping location updates is simply a matter of calling stopMonitoringRegion and passing the same Region used to start monitoring the region. This will dispatch a RegionEvent.STOP_MONITORING event when successful.

    Location.service.geofences.addEventListener( RegionEvent.STOP_MONITORING, stopMonitoringHandler );

    var success:Boolean = Location.service.geofences.stopMonitoringRegion( region );


    function stopMonitoringHandler( event:RegionEvent ):void
    {
    trace( "stop monitor: "+event.region.identifier );
    }

    If you have finished listening to geofences you should also remove any RegionEvent listeners you may have been using.

    Location.service.geofences.removeEventListener( RegionEvent.START_MONITORING, startMonitoringHandler );
    Location.service.geofences.removeEventListener( RegionEvent.STOP_MONITORING, stopMonitoringHandler );
    Location.service.geofences.removeEventListener( RegionEvent.ENTER, enterHandler );
    Location.service.geofences.removeEventListener( RegionEvent.EXIT, exitHandler );

    Operation Notes and Caveats

    The entry and exit events are generated whenever the OS determines that a region is entered or exited. The conditions for this vary on the operating systems and can vary from a few seconds to a few minutes.

    iOS

    An app can register up to 20 regions at a time. In order to report region changes in a timely manner, the region monitoring service requires network connectivity.

    To work around this limit, consider registering only those regions in the user’s immediate vicinity. As the user’s location changes, you can remove regions that are now farther way and add regions coming up on the user’s path.

    Regions with a radius between 1 and 400 meters work better on iPhone 4S or later devices. On these devices, an app can expect to receive the appropriate region entered or region exited notification within 3 to 5 minutes on average, if not sooner.

    The system doesn’t report boundary crossings until the boundary plus a system-defined cushion distance is exceeded. This cushion value prevents the system from generating numerous entered and exited events in quick succession while the user is traveling close the edge of the boundary.

    Android

    Android entry/exit events are dispatched somewhat faster than on iOS.

    - + \ No newline at end of file diff --git a/docs/location/index.html b/docs/location/index.html index 28881aafeec..444e7bf1fac 100644 --- a/docs/location/index.html +++ b/docs/location/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ look at the DeviceMotion extension.

    The altitude is the most inaccurate coordinate. Due to the way GPS works the vertical accuracy is the least precise (http://gpsinformation.net/main/altitude.htm)

    Altitude is reported as the height above the WGS84 ellipsoid and not sea level which can change around the world. You can read more on this here: http://www.gpspassion.com/forumsen/topic.asp?TOPIC_ID=10915

    Documentation

    The documentationn site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    var request:LocationRequest = new LocationRequest();
    request.accuracy = LocationRequest.ACCURACY_NEAREST_TEN_METERS;
    request.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
    request.interval = 5000;

    var success:Boolean = Location.service.startLocationMonitoring( request );

    More information here:

    com.distriqt.Location

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/location/initialise-the-extension/index.html b/docs/location/initialise-the-extension/index.html index 4c3de0cd319..b1733db6ceb 100644 --- a/docs/location/initialise-the-extension/index.html +++ b/docs/location/initialise-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Initialise the Extension

    Supported

    You should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    if (Location.isSupported)
    {
    // Functionality here
    }

    Check Google Play Services Availability

    This extension requires the use of Google Play Services.

    You should use the GoogleApiAvailability helper in the com.distriqt.playservices.Base ANE. The documentation for this class is available in the Google Play Services wiki.

    For example:

    import com.distriqt.extension.playservices.base.ConnectionResult;
    import com.distriqt.extension.playservices.base.GoogleApiAvailability;
    var result:int = GoogleApiAvailability.instance.isGooglePlayServicesAvailable();
    if (result != ConnectionResult.SUCCESS)
    {
    if (GoogleApiAvailability.instance.isUserRecoverableError( result ))
    {
    GoogleApiAvailability.instance.showErrorDialog( result );
    }
    else
    {
    trace( "Google Play Services aren't available on this device" );
    }
    }
    else
    {
    trace( "Google Play Services are Available" );
    }

    If Google Play Services aren't available then you won't be able to use the functionality in this extension.

    - + \ No newline at end of file diff --git a/docs/location/ios-location-simulation/index.html b/docs/location/ios-location-simulation/index.html index 63613e2e797..e0a00b6053a 100644 --- a/docs/location/ios-location-simulation/index.html +++ b/docs/location/ios-location-simulation/index.html @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ of the predefined default locations.

    If you switch to your AIR application now you should find it reporting this new location.

    Note: this may time out after a minute or so as we haven't set up the test application for background operation, however we find this enough for testing most situations.

    If it stops reporting, just switch back to the test application and select the debug location simlation again.

    - + \ No newline at end of file diff --git a/docs/location/location-monitoring/index.html b/docs/location/location-monitoring/index.html index 49ddc25ab7a..f1c455af1ed 100644 --- a/docs/location/location-monitoring/index.html +++ b/docs/location/location-monitoring/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ location information whenever a location update is received.

    This can be useful in situations where the application is running in the background (or even terminated on Android) the update url will still be contacted where AS3 code may not run.

    var request:LocationRequest = new LocationRequest()
    .setAccuracy( LocationRequest.ACCURACY_NEAREST_TEN_METERS )
    .setPriority( LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY );

    request.setServerUpdate(
    "http://example.com/locationupdate",
    "YOUR_CUSTOM_DATA_STRING"
    );

    Location.service.startLocationMonitoring( request );

    The extension will send a json payload to the url containing the following structure:

    {
    "location": {
    "altitude": 0.00,
    "latitude": 0.00,
    "longitude": 0.00,
    "timestamp": 000000000
    },
    "data": "YOUR_CUSTOM_DATA_STRING"
    }

    Mock Locations

    In some circumstances it is possible for a user to download an app and send mock locations to your application.

    We can detect if the location reported is from a mock location provider by checking the isMockLocation property of the reported Position:

    function location_updateHandler( event:LocationEvent ):void
    {
    if (event.position.isMockLocation)
    {
    // This is a mock location - handle as appropriate for your application
    }
    }

    If you are using the location for some specific user tracking you may find it important to ignore any mock location values.

    note

    Currently supported on Android only. iOS will always return false for this value

    - + \ No newline at end of file diff --git a/docs/location/location-utils---distance/index.html b/docs/location/location-utils---distance/index.html index 25847a33035..7233f7fe717 100644 --- a/docs/location/location-utils---distance/index.html +++ b/docs/location/location-utils---distance/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Location Utils - Distance

    Calculating distance

    You can use the utilities to calculate the distance between two geographic positions.

    var from:Position = ...;
    var to:Position = ...;

    var distance:Number = Location.service.locationUtils.distanceBetween( from, to );

    This method measures the distance between the two locations by tracing a line between them that follows the curvature of the Earth. The resulting arc is a smooth curve and does not take into account specific altitude changes between the two locations.

    Distance is defined in meters using the WGS84 ellipsoid.

    - + \ No newline at end of file diff --git a/docs/location/migrating-to-androidx/index.html b/docs/location/migrating-to-androidx/index.html index 74dd52bb841..dd5b8f6ef35 100644 --- a/docs/location/migrating-to-androidx/index.html +++ b/docs/location/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/location/migrating-to-v4.5/index.html b/docs/location/migrating-to-v4.5/index.html index d63bc8fa9ba..67550d63a6b 100644 --- a/docs/location/migrating-to-v4.5/index.html +++ b/docs/location/migrating-to-v4.5/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v4.5

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/location/request-authorisation/index.html b/docs/location/request-authorisation/index.html index 06f5e07c8e3..e8f00d63025 100644 --- a/docs/location/request-authorisation/index.html +++ b/docs/location/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ or AuthorisationStatus.IN_USE access. If you want to be able to receive notifications in the background you must use ALWAYS otherwise you will only receive updates when the application is in use.

    Usage Description

    This applies to the iOS implementation

    You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

    The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

    You set these values through adding the usage description keys to your application descriptor's info additions or simply by setting up your configuration options in your apm project.

    Background Authorisation

    This applies to the Android implementation

    Requesting "always" or "background" location access on Android has changed with recent releases of Android.

    When requesting permission your user will firstly be presented with the "in use" permission request, which will allow the user to select the accuracy of your location requests and allow or deny the request:

    If you have included the background permission in your manifest and request the "always" permission then an additional step is required where the user will need to manually change the location permission to be "Allow all the time":

    You should step through this process for your user, firstly requesting the "in use" permission and then explaining the need for the background permission before requesting the "always" permission.

    If you simply request the "always" permission to start with, then the extension will firstly show the "in use" dialog and then, if granted, will display the settings for the user to change to the "always" permission.

    info

    It is worth noting that if a user removes a location permission your Android application will likely be restarted by the system to ensure these decreased permission levels are applied.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/add-the-extension/index.html b/docs/mediaplayer/add-the-extension/index.html index e6fda8c8865..ec45d7f6eae 100644 --- a/docs/mediaplayer/add-the-extension/index.html +++ b/docs/mediaplayer/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Android Support

    The Android Support libraries encompass the Android Support, Android X and common Google libraries.

    These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

    This extension requires the following extensions:

    You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

    Note: if you have been using the older com.distriqt.androidsupport.* (Android Support) extensions you should remove these extensions and replace it with the androidx extensions listed above. This is the new version of the android support libraries and moving forward all our extensions will require AndroidX.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Background Audio

    If you require playback of background audio, i.e. if you plan to support playing audio when your application is not in the foreground. This is generally not required however if you are making a music player application then this may be applicable.

    To enable background audio on iOS you need to add the audio string to the UIBackgroundModes as below.

    To add these additions you need to add some additional configuration. Firstly add a custom iOS configuration file by running:
    apm generate config ios

    Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the UIBackgroundModes node:

    <plist version="1.0">
    <dict>

    <key>UIBackgroundModes</key>
    <array>
    <string>audio</string>
    </array>

    </dict>
    </plist>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (MediaPlayer.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/mediaplayer/audio-player---background-audio/index.html b/docs/mediaplayer/audio-player---background-audio/index.html index a5f100cf258..f630c7dc18d 100644 --- a/docs/mediaplayer/audio-player---background-audio/index.html +++ b/docs/mediaplayer/audio-player---background-audio/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Audio Player - Background Audio

    The Audio Player can be used to play back audio files using the native audio player in the background. This allows you to introduce background audio playback, and remote control center display of audio media information.

    Background Audio

    The process to play audio while your application is in the background varies on the different operating systems.

    There are some general rules here.

    • Only use one AudioPlayer instance with the background audio enabled. Using multiple players with background audio enabled can have undesired affects
    • When using background audio the extension may display the remote controls automatically as this is required by some platforms (Android in particular requires you to display a notification showing the playback)

    In order to enable background audio on a player you need to enable the option in the AudioPlayerOptions:

    var options:AudioPlayerOptions = new AudioPlayerOptions()
    .enableBackgroundAudio();

    Creating a background audio player will enable the remote command center for this player and automatically enable the play and pause commands.

    If you wish to set more advance controls including setting the media information and artwork, please see the dedicated documentation on the "Remote Command Center". Using the "Remote Command Center" events allows you to create a more complete player experience for your user across multiple files and players.

    iOS

    In order to play audio in the background you will firstly need to add the audio background mode to the UIBackgroundModes key in your info additions section of your application descriptor.

    <key>UIBackgroundModes</key>
    <array>
    <string>audio</string>
    </array>

    See Add the Extension

    Secondly you will have to inform the ANE to change the audio session to support background audio. This is done by enabling the background audio in the AudioPlayerOptions as above. This will change the audio session mode to support background audio.

    caution

    Be aware that this mode change will affect your entire application not just this player.

    Android

    On Android, background audio will be played through a service using a completely different implementation from the normal audio playback. This is a requirement of Android to continue playback of audio when the application loses focus.

    Additionally, it is a requirement that a notification be displayed indicating the playback. This will be automatically created for you and you can modify it's contents through the Remote Command Center.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/audio-player/index.html b/docs/mediaplayer/audio-player/index.html index 0c652550b74..90af42e33b2 100644 --- a/docs/mediaplayer/audio-player/index.html +++ b/docs/mediaplayer/audio-player/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ and pass this instance to the createAudioPlayer function:

    var options:AudioPlayerOptions = new AudioPlayerOptions()
    .enableBackgroundAudio();

    var player:AudioPlayer = MediaPlayer.service.createAudioPlayer( options );

    You can create multiple players to playback different audio files simultaneously and control their playback individually

    Once you have created the player you will need to load a file into the player, which will prepare the player for playback loading the file as neccessary.

    For example, to load a file from the applicationStorageDirectory named audio-file.mp3:

    var file:File = File.applicationStorageDirectory.resolvePath("audio-file.mp3");

    player.load( file.nativePath );

    Playing Audio

    Once you have created an AudioPlayer instance and called load to specify the audio file, playing the audio is simply a matter of calling play

    player.play();

    The player will dispatch the following events:

    player.addEventListener( AudioPlayerEvent.COMPLETE, audioPlayer_completeHandler );
    player.addEventListener( MediaErrorEvent.ERROR, audioPlayer_errorHandler );

    function audioPlayer_errorHandler( event:MediaErrorEvent ):void
    {
    trace( "error: [" + event.code + "] " + event.description );
    }

    function audioPlayer_completeHandler( event:AudioPlayerEvent ):void
    {
    trace( "complete" );
    }

    To pause playback you can call the pause function on the player.

    player.pause();

    This will pause playback but not change the current playback position, so calling play again will resume play from the same position.

    To change the current playback position you can call seek and pass the new playback position.

    player.seek( 10.2 );

    Playback Speed

    The playback speed can be controlled by using the setPlaybackSpeed function. In order for this functionality to work however you must first have enabled the player to support changing the playback speed by enabling in the player options.

    var options:AudioPlayerOptions = new AudioPlayerOptions()
    .enablePlaybackSpeed();

    var player:AudioPlayer = MediaPlayer.service.createAudioPlayer( options );

    Once you have enabled the playback speed option you can call setPlaybackSpeed, the speed should be a value between 0.5 and 2:

    player.setPlaybackSpeed( 0.5 );

    Headphones

    When headphones are plugged in the audio will continue playing through the headphones. However when they are removed the standard process is that audio will be paused.

    If you wish to alter this behaviour the AudioPlayerEvent.AUDIO_BECOMING_NOISY will be dispatched at this point. This event is dispatched when the application audio would become "noisy", for example the headphones were removed and play would continue through the device speakers. However instead the system automatically pauses playback and you can use this event to trigger playback again.

    player.addEventListener( AudioPlayerEvent.AUDIO_BECOMING_NOISY, audioBecomingNoisyHandler );

    function audioBecomingNoisyHandler( event:AudioPlayerEvent ):void
    {
    player.play();
    }

    Audio Interruptions

    Interuptions may occur when a user receives a phone call or when another app requests audio focus.

    You are expected to be a "good app citizen" and not continue playing audio in these scenarios so you should listen for the AudioPlayerEvent.INTERRUPTION_START event on your audio player and ensure that you respond appropriately, pausing any active playback as a minimum.

    player.removeEventListener( AudioPlayerEvent.INTERRUPTION_START, interruptionHandler );

    function interruptionHandler( event:AudioPlayerEvent ):void
    {
    // Respond to audio interruption
    player.pause();
    }

    You may also receive a AudioPlayerevent.INTERRUPTION_END, depending on the circumstances, to signal the end of the interruption. This event is not guaranteed to be delivered on all platforms and in all scenarios, so it can be used but do not rely on it.

    player.removeEventListener( AudioPlayerEvent.INTERRUPTION_END, interruptionEndHandler );

    function interruptionEndHandler( event:AudioPlayerEvent ):void
    {
    // Application has regained audio focus and can resume or start playback
    }

    Other Applications

    If you play music in your application it is a good idea to check whether there is another application currently playing audio before starting your own audio. For example if there is a background music player application actively playing music.

    You can use the isOtherAudioPlaying flag to check this in your application:

    if (MediaPlayer.service.isOtherAudioPlaying)
    {
    // Other application is playing audio
    }

    In this case it is generally advised to disable your audio or at least any music that your application may play.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/changelog/index.html b/docs/mediaplayer/changelog/index.html index 41ad8d60604..5015e89e08c 100644 --- a/docs/mediaplayer/changelog/index.html +++ b/docs/mediaplayer/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.19 [v4.8.0]

    feat(android): update exoplayer to v2.19.1 (#235)

    2023.01.24 [v4.7.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
    feat(android): update exoplayer library to v2.18.2 (#230)

    2022.03.09 [v4.6.0]

    Android update to exoplayer v2.17.0 (resolves #183) (potential: #209 #213 #215 #119)
    - more information https://github.com/google/ExoPlayer/blob/release-v2/RELEASENOTES.md

    Update docs to use apm and for Android 31 changes

    Fixes:
    - Android: Fixed issue with multiple players loading in incorrect views (resolves #217)

    2021.10.07 [v4.4.8]

    Add air package
    Returned better error messages from exoplayer on android
    Added system control stop functionality

    2021.04.08 [v4.4.006]

    Corrected issue with displaying initial video frame when destroying a media player (resolves #204)
    Removed ios minimum version linker option

    2021.03.05 [v4.4.003]

    Added system control events allowing control of another media player on Android

    2020.10.12 [v4.3.010]

    Updated docs

    2020.10.12 [v4.3.010]

    Android: Added some checks around exoplayer view creation (resolves #196)
    Reduced progress event load with no active listeners

    2020.08.19 [v4.2.065]

    Corrected issue with iOS 13+ remote command center (resolves #194)

    2020.04.15 [v4.1.044]

    Android: Changed click event to touch down event (resolves #185)

    2020.04.14 [v4.1.043]

    Android: Corrected click event dispatch with new exoplayer implementation (resolves #185)

    2020.04.13 [v4.1.035]

    Added flag to detect audio from other applications

    2020.03.20 [v4.0.031]

    Android X migration (resolves #182)

    2019.09.17 [v3.0.019]

    Added progress events to the AudioPlayer (resolves #169)
    Fixed issue with createAudioPlayer and null options

    2019.08.15 [v3.0.014]

    Android 64bit support (resolves #165)
    Updated minimum iOS version to 9.0
    Resolved crash with AIR 32 and thumbnail generation (resolves #153)
    Automatically correct viewport position and size to integers (resolves #162)
    Corrected issue with progress events when using auto play option (resolves #166)
    Added audio output to specify speaker or receiver output (resolves #167)

    2019.03.12 [v2.6.203]

    Embedded iOS bitcode
    Removed application keys
    Resolved issue with second load event (resolves #158)

    2019.03.05 [v2.5.196]

    Android: Corrected sound pool continuous looping (resolves #157)

    2019.02.27 [v2.5.188]

    Android: Corrected sound pool volume levels + updates for loops on audio player
    Updated minimum iOS version to 8.0 (resolves #156)

    2019.01.17 [v2.4.163]

    Added very simple audio player FLA example (#150)

    2018.11.26 [v2.4.161]

    Updated duration value on iOS (resolves #141)
    Added checks for exceptions with seeks (eg with streaming media)

    2018.11.18 [v2.4.158]

    Documentation update

    2018.11.18 [v2.4.158]

    Android: Added interruption events for loss of audio focus (resolves #139)

    2018.11.09 [v2.3.154]

    Added Audio Player PAUSED and PLAYING events (resolves #136)
    Android: Fixed ANR when creating player but not loading content (resolves #126)

    2018.10.27 [v2.2.142]

    Added AUDIO_BECOMING_NOISY event for audio players when the headphones are removed (resolves #106) 
    Android: Added customisation of notification icon (resolves #135)
    Android: Added ability to close notification by swiping when paused (resolves #105)
    Android: Added documentation on the android.permission.FOREGROUND_SERVICE requirement
    Android: Add Next / Previous track buttons to notification (resolves #115)
    Android: Corrected notification doesn't close on app termination (resolves #124)

    2018.09.13 [v2.1.117]

    iOS: Updated loading events and seek operation for remote mp3 (#120)

    2018.09.11 [v2.1.114]

    Android: Corrected launching of application from notification when activity dismissed (resolves #121)

    2018.09.07 [v2.1.108]

    iOS: Corrected disconnection from command centre for background audio players (resolves #116)
    iOS: Added skip forward / backward controls

    2018.08.21 [v2.1.092]

    Android: Set default volume control stream (resolves #111)

    2018.08.12 [v2.1.088]

    Fixed destruction issue with audio player (resolves #107)

    2018.07.26 [v2.1.084]

    Added the MediaPlayerView interface to allow multiple players and individual control
    Added the AudioPlayer for audio playback (including streaming audio)
    Complete rewrite of Android and iOS video player implementations
    Added Apple tvOS implementation (resolves #69)
    Added the RemoteCommandCenter for controls on lock screen / notification (resolves #42)

    Updates:
    - Moved to the iOS AVPlayer framework (resolves #30, resolves #11, resolves #84)
    - Moved to the Android ExoPlayer library (resolves #29, resolves #24, resolves #9, resolves #6, resolves #88)
    - Android: Corrected removing player after complete (resolves #50)
    - Android: Better rotation handling (resolves #86)
    - Android: Auto-fit video to player dimensions (resolves #6)
    - Player volume controls (resolves #73)
    - Background colour (resolves #62)

    2018.04.27 [v1.18.071]

    Android: Added some additional checks for state when player sent to background (#88)

    2017.10.19 [v1.18.070]

    Corrected issue with iOS 11 player (resolves #76)

    2017.07.10 [v1.18.054]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.30 [v1.16.002]

    Android fix for thumbnails on 7+, updated SDKs + new documentation

    2016.09.02 [v1.15.014]

    iOS: Corrected using file:// url paths

    2016.08.17 [v1.15.012]

    iOS: Correction for exiting fullscreen on playback start (#64)

    2016.07.20

    Corrected loading of urls with '%' in parameters (resolves #57)

    2016.04.12

    iOS: Corrected generated thumbnail orientation (resolves #55)

    2016.04.12

    2016.04.05

    Added media utils to generate video thumbnail (resolves #53)

    2015.11.13

    Updated documentation (resolves #47)

    2015.11.03

    Updated documentation link (resolves #41)

    2015.11.03

    Added setOptions to set background audio mode (resolves #40)

    2015.08.31

    Android: Corrected depth order with other native components (resolves distriqt/ANE-NativeWebView#12)

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources

    2015.06.02

    Repackaged to test distriqt/ANE-Calendar#10

    2015.05.12

    Android: Fixed scaling method with fullscreen (resolves #26)

    2015.03.17

    Changed class structure to support FlashBuilder 4.6
    Android: Fixed error when removing player before player ready (resolves #17)
    Added click event for detecting user interaction with video

    2015.02.02

    Added check for .debug suffix in application id

    2014.12.22

    Added 'position' to retrieve the current playback position (resolves #4)
    Android: Implemented a CONTROLS_BASIC that shows only a Play/Pause button and the Scrubber (resolves #5)

    2014.12.22

    iOS: Included arm64 support (resolves #3) 
    Android: Corrected crash with removePlayer while controls are visible (resolves #1)
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.05

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    New application based key check, removing server checks
    - + \ No newline at end of file diff --git a/docs/mediaplayer/index.html b/docs/mediaplayer/index.html index eabce8a099f..7e6d633b6d3 100644 --- a/docs/mediaplayer/index.html +++ b/docs/mediaplayer/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ combination of the audio player for longer sounds such as music and the sound pool for shorter sound effects.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    More information here:

    com.distriqt.MediaPlayer

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/media-player---control-playback/index.html b/docs/mediaplayer/media-player---control-playback/index.html index cbf51e65731..373e6d447a5 100644 --- a/docs/mediaplayer/media-player---control-playback/index.html +++ b/docs/mediaplayer/media-player---control-playback/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Media Player - Control Playback

    Controlling playback

    To start playback of a player call the play() function:

    player.play();

    To pause playback call the pause() function:

    player.pause();

    To stop playback and reset the player position to the beginning call stop():

    player.stop();

    To move the current playback position use the seek() function and pass required new playback position :

    player.seek( time );

    where time is the new playback position in seconds. The time must be less than the total duration of the media, otherwise nothing is done.

    Fullscreen

    You can change the player view to display as a fullscreen view by calling the setFullscreen() function.

    player.setFullscreen( true );

    Similarly you can minimise the fullscreen view using the same process:

    player.setFullscreen( false );

    You can also listen for the fullscreen events, to determine when the view enters and exits fullscreen. These will be dispatched if the user caused the fullscreen change or if it occurred through the programatic method above.

    player.addEventListener( MediaPlayerEvent.FULLSCREEN_ENTER, fullscreenEnterHandler );
    player.addEventListener( MediaPlayerEvent.FULLSCREEN_EXIT, fullscreenExitHandler );

    function fullscreenEnterHandler( event:MediaPlayerEvent ):void
    {
    trace( "fullscreen enter" );
    }

    function fullscreenExitHandler( event:MediaPlayerEvent ):void
    {
    trace( "fullscreen exit" );
    }
    - + \ No newline at end of file diff --git a/docs/mediaplayer/media-player---create/index.html b/docs/mediaplayer/media-player---create/index.html index 90867192656..87776790fde 100644 --- a/docs/mediaplayer/media-player---create/index.html +++ b/docs/mediaplayer/media-player---create/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Media Player - Create

    Media Player View

    The MediaPlayerView represents an instance of a media player and it's view. This can be used to present a visible player in your application with playback controls.

    Create

    You create an instance of a MediaPlayerView by calling the createPlayerView function and passing a MediaPlayerOptions instance. The options class is used to specify any options on the view, including it's initial size and the type of controls to display.

    For example, the following will create a player with initial dimensions 100x100 located in the top left corner:

    var player:MediaPlayerView = MediaPlayer.service.createPlayerView(
    new MediaPlayerOptions()
    .setViewport( new Rectangle( 0, 0, 100, 100 ) )
    );

    The coordinates here are native coordinates so if you are utilising stage scaling at all you must take that into account when specifying the size and position of the player.

    Options

    The options you pass to the creation function specify how the player will be displayed and some playback features.

    Auto Play

    If you wish the video playback to commence as soon as the video is loaded set the autoPlay option to true:

    var options:MediaPlayerOptions = new MediaPlayerOptions()
    setAutoPlay( true );

    Controls

    You specify whether to display the controls with the the MediaPlayerOptions.controlsEnabled option and the showControls() helper:

    var options:MediaPlayerOptions = new MediaPlayerOptions()
    showControls();

    The exact controls and appearance vary across different platforms and versions, as they match the native ui of the system.

    If you wish no controls to be displayed you can set this to false:

    var options:MediaPlayerOptions = new MediaPlayerOptions()
    showControls( false );

    Chaining

    All the functions in the options class are designed to be chained to allow easy creation of options to pass to the createPlayerView function. This is so you can simply create a player in your code as below:

    var player:MediaPlayerView = MediaPlayer.service.createPlayerView(
    new MediaPlayerOptions()
    .setViewport( new Rectangle( 0, 0, 100, 100 ) )
    .setBackgroundColour( 0xFFFFFFFF )
    .showControls()
    );

    This is the equivalent of the more traditional code below:

    var options:MediaPlayerOptions = new MediaPlayerOptions();
    options.viewport = new Rectangle( 0, 0, 100, 100 );
    options.backgroundColour = 0xFFFFFFFF;
    options.controlsEnabled = true;

    var player:MediaPlayerView = MediaPlayer.service.createPlayerView( options );

    You can use whichever method you choose.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/media-player---loading-media/index.html b/docs/mediaplayer/media-player---loading-media/index.html index c85357ef687..d2c4e5f517d 100644 --- a/docs/mediaplayer/media-player---loading-media/index.html +++ b/docs/mediaplayer/media-player---loading-media/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Media Player - Loading Media

    Once you have created a MediaPlayerView instance then you will need to load your media into the player. In the following code player is assumed to be the MediaPlayerView instance you created:

    var player:MediaPlayerView = MediaPlayer.service.createPlayerView(
    new MediaPlayerOptions()
    .setViewport( new Rectangle( 0, 0, 100, 100 ) )
    );

    Loading media is done with the load() function. This function takes a path parameter.

    player.load( path );

    The path can either be a path to a local file or a url to a remote file. For example a local video:

    var path:String = File.applicationStorageDirectory.resolvePath( "video.mp4" ).nativePath;

    Or a remote file:

    var path:String = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
    - + \ No newline at end of file diff --git a/docs/mediaplayer/media-player---playback-events/index.html b/docs/mediaplayer/media-player---playback-events/index.html index 604a15313bf..9d8ffa01236 100644 --- a/docs/mediaplayer/media-player---playback-events/index.html +++ b/docs/mediaplayer/media-player---playback-events/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Media Player - Playback Events

    There are 3 main types of events associated with the media player: status, progress and errors.

    Status Events

    Status events are dispatched using the MediaPlayerEvent class. These events include playback status, (playing, paused, stopped etc), player ready event, completion event, and fullscreen events.

    You add a listener to your MediaPlayerView instance to receive these events, for example to register for the READY events:

    var player:MediaPlayerView = ...;

    player.addEventListener( MediaPlayerEvent.READY, readyHandler );

    function readyHandler( event:MediaPlayerEvent ):void
    {
    trace( "ready" );
    }

    Progress Events

    Progress events are dispatched using the MediaProgressEvent class. This class includes the current playback position and the total time of the media.

    It's dispatched approximately 5 times a second.

    player.addEventListener( MediaProgressEvent.PROGRESS, progressHandler );

    function progressHandler( event:MediaProgressEvent ):void
    {
    trace( "progress: " + event.current + " / " +event.total );
    }

    Error Events

    Error events are dispatched using the MediaErrorEvent class.

    This event will contain more information on the error, but generally it's either due to incorrect file path or a network problem (for network streamed media).

    player.addEventListener( MediaErrorEvent.ERROR, errorHandler );

    function errorHandler( event:MediaErrorEvent ):void
    {
    trace( "error: "+ event.code + "::"+event.description );
    }
    - + \ No newline at end of file diff --git a/docs/mediaplayer/migrating-from-version-1/index.html b/docs/mediaplayer/migrating-from-version-1/index.html index 48576e83f9f..6f5666098bf 100644 --- a/docs/mediaplayer/migrating-from-version-1/index.html +++ b/docs/mediaplayer/migrating-from-version-1/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating from version 1

    Version 2 completely changes the way media players are created and displayed. Migration is simple as laid out below.

    The major difference is that you now will create an MediaPlayerView instance and use this to configure, load and control media playback. Whereas you used to only have access to a single player, you can now create multiple and use as required. This means that you will need to hold onto an instance of your MediaPlayerView to set properties, listen for events, load, and control media playback.

    Dependencies

    There are new ANE dependencies with version 2. In particular the Android support libraries are now required. Check the details in the Add the Extension section.

    Creating a Player

    Previously there was only one instance of a player handled internally to the ANE. You now have to retrieve a reference to a player and hold onto a reference, by changing any calls to createPlayer to the new createPlayerView.

    So the following code:

    var path:String = "...";
    var view:Rectangle = new Rectangle( 0, 0, stage.stageWidth, 480 );

    MediaPlayer.service.createPlayer(
    path,
    view.x,
    view.y,
    view.width,
    view.height,
    false,
    MediaPlayer.CONTROLS_NONE,
    false
    );

    becomes:

    var path:String = "...";
    var view:Rectangle = new Rectangle( 0, 0, stage.stageWidth, 480 );

    var player:MediaPlayerView = MediaPlayer.service.createPlayerView(
    new MediaPlayerOptions()
    .setViewport( view )
    .showControls( false )
    );
    player.load( path );

    Note: we have separated the loading call (load()) from the creation (createPlayerView()). This means you no longer need to pass the path when creating a player. However you can call load immediately if you wish initialise your player with media.

    Events

    Events are now dispatched by the MediaPlayerView instance rather than from the extension service.

    So for example the following events listeners:

    MediaPlayer.service.addEventListener( MediaPlayerEvent.COMPLETE, completeHandler );
    MediaPlayer.service.addEventListener( MediaProgressEvent.PROGRESS, progressHandler );
    MediaPlayer.service.addEventListener( MediaErrorEvent.ERROR, errorHandler );

    should now be attached to your player instance:

    player.addEventListener( MediaPlayerEvent.COMPLETE, completeHandler );
    player.addEventListener( MediaProgressEvent.PROGRESS, progressHandler );
    player.addEventListener( MediaErrorEvent.ERROR, errorHandler );

    Control

    Playback control is now controlled through the player instance.

    To start playback of your video:

    MediaPlayer.service.play();

    becomes:

    player.play();

    Similarly for the other playback controls such as:

    • pause()
    • stop()

    Resize

    Player resizing is now done with the resize function on the player.

    MediaPlayer.service.resize( 0, 0, stage.stageWidth, 500 );

    Becomes:

    player.resize( 0, 0, stage.stageWidth, 500 );

    Destroying the player

    Previously calling removePlayer() would remove and destroy the player. This is now changed to the clearer destroy() function on the player instance.

    So

    MediaPlayer.service.removePlayer();

    becomes:

    player.destroy();

    After you call destroy() on a player instance the player will no longer function. You should remove all event listeners and clear any references to this object. If you need to use a player again, then you'll need to call createPlayerView() again to create a new player instance.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/migrating-to-androidx/index.html b/docs/mediaplayer/migrating-to-androidx/index.html index d971c753084..afdfd067409 100644 --- a/docs/mediaplayer/migrating-to-androidx/index.html +++ b/docs/mediaplayer/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/remote-command-center/index.html b/docs/mediaplayer/remote-command-center/index.html index 09f5c4e4242..9d6de19b6dc 100644 --- a/docs/mediaplayer/remote-command-center/index.html +++ b/docs/mediaplayer/remote-command-center/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ media info will be ignored on Android. Title, artist and artwork are all still available.

    Android Icon

    On Android the notification has an icon displayed in the status bar. By default this is a play arrow icon, which is the default icon for Android media notifications.

    This can be customised by packaging a custom resource notification icon with your application (in a custom resources ANE) and specifying the name of the resource in the media info.

    info.setIcon( "ic_custom_resource_icon_name" )

    If you don't provide a value the default icon will be used.

    For information on creating a custom resources ANE see the script available here: https://github.com/distriqt/ANE-CustomResources

    Remote Control Events

    The lock screen, control center and notification areas can contain buttons to control the media playback.

    Generally these are only appropriate for when you are background playing media. In these cases you should listen for these control events and appropriately pause / play your media.

    You listen for RemoteCommandCenterEvents on the MediaPlayer.service.remoteCommandCenter property, however they will only be dispatched after you call registerForControlEvents(). This registration process makes your application the registered receiver for these control events.

    MediaPlayer.service.remoteCommandCenter.registerForControlEvents();

    You can similarly stop the events by calling unregisterForControlEvents().

    Example

    For example if we are using an AudioPlayer to background play music:

    var options:AudioPlayerOptions = new AudioPlayerOptions()
    .enableBackgroundAudio();

    var player:AudioPlayer = MediaPlayer.service.createAudioPlayer( options );
    player.play();

    We can then listen for control events and appropriately change the state of the player:

    MediaPlayer.service.remoteCommandCenter.addEventListener( RemoteCommandCenterEvent.PAUSE, remoteCommandCenter_pauseHandler );
    MediaPlayer.service.remoteCommandCenter.addEventListener( RemoteCommandCenterEvent.PLAY, remoteCommandCenter_playHandler );

    MediaPlayer.service.remoteCommandCenter.registerForControlEvents();

    function remoteCommandCenter_pauseHandler( event:RemoteCommandCenterEvent ):void
    {
    player.pause();
    }

    function remoteCommandCenter_playHandler( event:RemoteCommandCenterEvent ):void
    {
    player.play();
    }

    Notes

    - + \ No newline at end of file diff --git a/docs/mediaplayer/sound-pool/index.html b/docs/mediaplayer/sound-pool/index.html index 6391ea4f2fe..c7c09cede62 100644 --- a/docs/mediaplayer/sound-pool/index.html +++ b/docs/mediaplayer/sound-pool/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ If you want to playback longer sounds and music look at the AudioPlayer class for a more complete audio playback solution. Sounds played through the sound pool may not complete if they are too long.

    Creating Sounds

    When dealing with the sound pool you will use the SoundPool functionality to create instances of a Sound and use this to load and play sounds.

    To create a Sound call createSound():

    var sound:Sound = MediaPlayer.service.soundPool.createSound();

    Note: This is the com.distriqt.extension.mediaplayer.sound.Sound class and not flash.media.Sound. We have used the same name to be able to quickly replace sounds in your application with the native equivalent.

    Loading

    To load a sound you call the loadFile function and pass a reference to a file on the device.

    var soundFile:File = File.applicationDirectory.resolvePath("assets/explosion.mp3");

    sound.loadFile( soundFile );

    Loading a file will dispatch one of two events:

    The loadFile call may also throw an Error if the file doesn't exist.

    var soundFile:File = File.applicationDirectory.resolvePath("assets/explosion.mp3");

    sound.addEventListener( Event.COMPLETE, sound_completeHandler );
    sound.addEventListener( IOErrorEvent.IO_ERROR, sound_errorHandler );
    sound.loadFile( soundFile );

    function sound_completeHandler( event:Event ):void
    {
    // Sound is loaded and ready for playback
    }

    function sound_errorHandler( event:IOErrorEvent ):void
    {
    // An error occurred
    }

    Controlling Playback

    Once a sound is loaded you can call play() to play the sound:

    sound.play();

    To stop a sound call stop():

    sound.stop();

    Unloading

    Once you have finished with a sound and never plan to use it again or if you wish to clear memory resources associated with a sound you can call unload().

    sound.unload();

    Once a sound has been unloaded the Sound instance is no longer valid. You will need to create a new sound and load a file again.

    Fallback

    If the device doesn't support native sound pool implementation a fallback implementation will be used which uses the flash.media.Sound implementation to playback sounds.

    You can check what implementation will be used by checking the isSupportedNatively flag on the sound pool. If this is true then the native implementation will be used and if it is false then the flash.media.Sound implementation will be used.

    Currently only Android has a native implementation

    Migrating from flash.media.Sound

    Loading

    Loading a sound using the flash.media.Sound class:

    var effect:Sound = new Sound();
    effect.addEventListener( Event.COMPLETE, sound_loadCompleteHandler );
    effect.addEventListener( IOErrorEvent.IO_ERROR, sound_errorHandler );
    effect.load( new URLRequest( "sounds/effect.mp3" ));

    function sound_loadCompleteHandler( event:Event ):void
    {
    effect.play();
    }

    Becomes the following using the com.distriqt.extension.mediaplayer.sound.Sound class:

    var effect:Sound = MediaPlayer.service.soundPool.createSound();
    effect.addEventListener( Event.COMPLETE, sound_loadCompleteHandler );
    effect.addEventListener( IOErrorEvent.IO_ERROR, sound_loadErrorHandler );
    effect.loadFile( File.applicationDirectory.resolvePath("sounds/effect.mp3"));

    function sound_loadCompleteHandler( event:Event ):void
    {
    effect.play();
    }

    Playback

    var loops:int = 1;
    var transform:SoundTransform = new SoundTransform();

    var channel:SoundChannel = effect.play( 0, loops, transform );

    becomes (still using flash.media.SoundTransform):

    var loops:int = 1;
    var transform:SoundTransform = new SoundTransform();

    effect.play( loops, transform );

    Stopping

    Stopping a sound using flash requires the sound channel:

    channel.stop();

    This is simplified to using the sound instance:

    effect.stop();

    Events

    The Event.COMPLETE and IOErrorEvent.IO_ERROR are both dispatched from the sounds.

    There is no way to detect the end of playback with the sound pool.

    - + \ No newline at end of file diff --git a/docs/mediaplayer/system-control/index.html b/docs/mediaplayer/system-control/index.html index 064f663a5ce..46f6cbe6d94 100644 --- a/docs/mediaplayer/system-control/index.html +++ b/docs/mediaplayer/system-control/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    System Control

    The system control interface allows your application to dispatch system wide events that other applications can respond to. These events are the default system control events for media and may control the active media player (most player respond to these events however it does depend on the application implementation).

    This functionality is provided through the SystemControl interface, which can be accessed via MediaPlayer.service.systemControl.

    Currently this is only supported on Android v19+.

    Support

    You can check whether the current device is supported by checking the isSupported property.

    if (MediaPlayer.service.systemControl.isSupported)
    {
    // System control actions are supported
    }

    Control

    You can perform several operations that can control the current media player:

    • play() : Dispatches the media play event;
    • pause() : Dispatches the media pause event;
    • next() : Dispatches the media next track event;
    • previous() : Dispatches the media previous track event;
    • playPause() : Dispatches the media play pause event to toggle the play state;

    For example, to pause the active media:

    if (MediaPlayer.service.systemControl.isSupported)
    {
    MediaPlayer.service.systemControl.pause();
    }
    - + \ No newline at end of file diff --git a/docs/memory/add-the-extension/index.html b/docs/memory/add-the-extension/index.html index 985308c795f..38d64c6bcca 100644 --- a/docs/memory/add-the-extension/index.html +++ b/docs/memory/add-the-extension/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Memory

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Memory.ane # Memory extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Memory.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/memory/changelog/index.html b/docs/memory/changelog/index.html index a6f2f1527a1..fe79e372fd9 100644 --- a/docs/memory/changelog/index.html +++ b/docs/memory/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.09.22 [v4.2.2]

    fix(android): correct name of value for memory warning level

    2023.09.22 [v4.2.1]

    fix(actionscript): correct event listener not being added correctly which prevented events from being dispatched (resolves #7)
    feat(android): add level associated with a MemoryEvent.LOW_MEMORY_WARNING event (resolves #8)

    2023.02.01 [v4.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2022.02.15 [v4.0.11]

    Update docs to use apm

    2021.12.06 [v4.0.10]

    Add airpackage

    2021.03.12 [v4.0.009]

    Updated to latest build process  
    Added Android-x64 support

    2020.03.24 [v4.0.006]

    Android X migration (resolves #6)

    2019.08.15 [v3.0.002]

    Android 64bit support (resolves #5)
    Updated minimum iOS version to 9.0
    - + \ No newline at end of file diff --git a/docs/memory/index.html b/docs/memory/index.html index 7d67c8a86c8..a5f29ec1a01 100644 --- a/docs/memory/index.html +++ b/docs/memory/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Memory

    Memory is an AIR Native Extension to receive the low memory notifications on iOS which indicate when your application should clear up as much memory as possible to avoid facing termination by the operating system.

    Features

    • Low Memory Warning Event
    • Memory Information
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    Acknowledgements

    This extension was made possible with support by MovieStarPlanet

    MovieStarPlanet

    - + \ No newline at end of file diff --git a/docs/memory/usage/index.html b/docs/memory/usage/index.html index bdda1296e6f..f64811fc79b 100644 --- a/docs/memory/usage/index.html +++ b/docs/memory/usage/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Usage

    Low Memory Warning

    This extension is very simple in the implementation, you simply add a listener for the MemoryEvent.LOW_MEMORY_WARNING and respond accordingly.

    if (Memory.isSupported)
    {
    Memory.service.addEventListener( MemoryEvent.LOW_MEMORY_WARNING, lowMemoryWarningHandler );
    }

    Then in your handler you can respond appropriately, clearing any unnecessary memory usage:

    function lowMemoryWarningHandler( event:MemoryEvent ):void
    {
    trace( "low memory warning" );
    }

    Level

    On Android you will receive additional information in the event, pertaining to the "level" (in the event.level property). The level of the low memory warning gives a hint as to the amount of trimming the application may like to perform. Levels and associated descriptions can be found in the MemoryWarningLevel class.

    function lowMemoryWarningHandler( event:MemoryEvent ):void
    {
    switch (event.level)
    {
    case MemoryWarningLevel.RUNNING_LOW:
    break;

    case MemoryWarningLevel.RUNNING_MODERATE:
    break;

    // Other state handlers
    }
    }

    On unsupported platforms the level will be "unknown".

    Memory Information

    You can retrieve some basic information about the current memory statistics using the MemoryInfo class. You retrieve a current version of this by using the getMemoryInfo function:

    var info:MemoryInfo = Memory.service.getMemoryInfo();

    trace( "available memory = " + info.availableMemory );
    trace( "total memory = " + info.totalMemory );

    These values are gathered from the operating system directly which should be more accurate representation than the values reported from System.

    - + \ No newline at end of file diff --git a/docs/message/add-the-extension/index.html b/docs/message/add-the-extension/index.html index 9b0687f40e3..7edbd9489b9 100644 --- a/docs/message/add-the-extension/index.html +++ b/docs/message/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Android Support

    The Android Support libraries encompass the Android Support, Android X and common Google libraries.

    These libraries are specific to Android. There are no issues including these on all platforms, they are just required for Android.

    This extension requires the following extensions:

    You can access these extensions here: https://github.com/distriqt/ANE-AndroidSupport.

    Note: if you have been using the older com.distriqt.androidsupport.* (Android Support) extensions you should remove these extensions and replace it with the androidx extensions listed above. This is the new version of the android support libraries and moving forward all our extensions will require AndroidX.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Extension IDs

    The following should be added to your extensions node in your application descriptor to identify all the required ANEs in your application:

    <extensions>
    <extensionID>com.distriqt.Message</extensionID>
    <extensionID>com.distriqt.Core</extensionID>
    <extensionID>androidx.core</extensionID>
    </extensions>

    Android

    Manifest Additions

    The Message ANE requires a few additions to the manifest to be able to start certain activities and to get permission to send and receive SMS. You will need to replace any occurrences of YOUR_APPLICATION_PACKAGE with your application package name (generally your application id prefixed by air.)

    You should add the listing below to your manifest:

    <manifest android:installLocation="auto">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application>

    <provider
    android:name="com.distriqt.extension.message.content.MessageFileProvider"
    android:authorities="YOUR_APPLICATION_PACKAGE.messagefileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_message_paths" />
    </provider>


    <!-- PERMISSIONS -->
    <activity android:name="com.distriqt.extension.message.permissions.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" />

    </application>
    </manifest>

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Message.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/message/changelog/index.html b/docs/message/changelog/index.html index 18d47f750f3..298763fb59d 100644 --- a/docs/message/changelog/index.html +++ b/docs/message/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2021.04.27 [v7.0.027]
    Updated docs and links (resolves #61)
    2020.04.05 [v7.0.024]
    iOS: Updated symbol names to avoid conflict with Share ANE (resolves #57)
    2020.03.20 [v7.0.023]
    Android X migration (resolves #56)
    2020.01.29 [v6.1.018]
    Added subscription id to received SMS (resolves #55)
    2019.12.01 [v6.1.012]
    Android: Added ability to disable automatic chooser when sending email (resolves #54)
    2019.10.11 [v6.1.010]
    Android: Added ability to select SIM card for SMS (resolves #53)
    2019.08.15 [v6.0.002]
    Android 64bit support (resolves #50)
    Updated minimum iOS version to 9.0
    Removed application keys
    2019.02.27 [v5.3.017]
    Updated minimum iOS version to 8.0 (resolves #49)
    Embedded iOS bitcode
    2018.12.01 [v5.2.012]
    Android: Added file provider functionality for sharing files through attachments (resolves #44)
    2017.08.11 [v5.2.008]
    Updated simple example
    2017.07.31 [v5.2.007]
    Added SMS NOT DELIVERED event
    2017.07.10 [v5.2.005]
    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)
    2017.06.19 [v5.2.004]
    Added authorisation checks for send SMS on Android (#28)
    2016.12.30 [v5.1.009]
    Updated examples + added checks for invalid attachments
    2016.12.30 [v5.1.008]
    Updated SDKs + new documentation
    2016.11.04 [v5.1.006]
    Corrected sendMail function on Android v6+ (resolves #25)
    2016.08.03
    Updated Core library compatibility
    2016.07.19
    Confirming build settings (#23)
    2016.07.05
    Documentation update
    iOS: Corrected small issue with sendSMSWithUI
    2016.05.29
    Android: Added basic HTML formatting and links (resolves #20)  
    Added starling example application
    Android: Corrected text on Textra app (resolves #22)
    2015.10.07
    Corrected MessageEvent typo (resolves #17)
    2015.06.22
    Android: Fix for sending SMS with Hangouts in API > 19 (resolves #16)
    2015.06.16
    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    2015.06.09
    Android: Windows: Fix for bug in AIR packager resulting in missing resources (resolves #11)
    2015.04.07
    Added an 'id' to the SMS object that gets returned with send events (resolves #13)
    Android: Added the ability to send SMS messages longer than 160 characters (resolves #14)
    Corrected the returned SMS object on send events (resolves #12)
    Android: Removed unused resources (resolves #11)
    2015.03.17
    Added share activity to allow sharing of text/url/image (resolves #10)
    Android: Fixed issue with sendMail when intent failed to be created
    2015.02.12
    Moved to new structure to support FlashBuilder 4.6 (#6)
    2015.02.03
    Android: Copied attachments to a temporary cache so external applications can access the files (resolves #3)
    2015.02.02
    Added check for .debug suffix in application id
    2014.12.22
    iOS: Included arm64 support (resolves #5) 
    Android: Corrected application id check when doesn't contain air prefix
    2014.12.22
    iOS: Included arm64 support (resolves #2) 
    Android: Corrected application id check when doesn't contain air prefix (resolves #1)
    2014.12.05
    Added CHANGELOG
    2014.12.05
    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls
    2014.12.01
    New application based key check, removing server checks
    - + \ No newline at end of file diff --git a/docs/message/email/index.html b/docs/message/email/index.html index 69a0c9dba25..3ba46b30880 100644 --- a/docs/message/email/index.html +++ b/docs/message/email/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Email

    Sending an Email

    Sending an email is a simple task of calling the sendMail function, specifying the subject, body and recipients. If you wish you can also using the sendMailWithOptions function to send more complex data, including:

    • CC and BCC recipients;
    • file attachments; and
    • HTML content;

    The following example shows the supported HTML content:

    if (Message.isMailSupported)
    {
    var email:String = "emailaddress@test.com";
    var subject:String = "Sending HTML email from AIR using the distriqt Message ANE";

    var body:String =
    "<div>"+
    "<p>This HTML email was sent using the distriqt <b>Message ANE</b></p>"+
    "A link: <a href='http://airnativeextensions.com'>airnativeextensions.com</a>"+
    "<br/>" +
    "Block: <blockquote>Some quote</blockquote>"+
    "<br/>" +
    "Bold: <b>This text should be bold</b>"+
    "<br/>" +
    "Italic: <i>This text should be italic</i>"+
    "<br/>" +
    "Colour: <font color='#ff0000'>This text should be red</font>"+
    "<div/>" ;

    Message.service.sendMailWithOptions(
    subject,
    body,
    email,
    "",
    "",
    [],
    true
    );
    }

    Attachments

    - + \ No newline at end of file diff --git a/docs/message/index.html b/docs/message/index.html index d06507ccfde..ef8b0402fc4 100644 --- a/docs/message/index.html +++ b/docs/message/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ all supported platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with messaging quickly and easily.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    if (Message.isMailSupported)
    {
    Message.service.sendMailWithOptions(
    "Subject",
    "Body of email",
    "test@distriqt.com" );
    }

    - + \ No newline at end of file diff --git a/docs/message/migrating-to-androidx/index.html b/docs/message/migrating-to-androidx/index.html index 2e7e56acf84..ce1e6ad51e8 100644 --- a/docs/message/migrating-to-androidx/index.html +++ b/docs/message/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/message/sms/index.html b/docs/message/sms/index.html index a6c37352a4a..92331690413 100644 --- a/docs/message/sms/index.html +++ b/docs/message/sms/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ You will still need to list them in your manifest and then follow the same code below as for iOS, except that on Android you will be able to ask multiple times. You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

    The following code will work across both platforms:

    Message.service.smsManager.addEventListener( AuthorisationEvent.CHANGED, authorisationStatus_changedHandler );

    switch (Message.service.smsManager.authorisationStatus())
    {
    case AuthorisationStatus.SHOULD_EXPLAIN:
    case AuthorisationStatus.NOT_DETERMINED:
    // REQUEST ACCESS: This will display the permission dialog
    Message.service.smsManager.requestAuthorisation();
    return;

    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    case AuthorisationStatus.RESTRICTED:
    // ACCESS DENIED: You should inform your user appropriately
    return;

    case AuthorisationStatus.AUTHORISED:
    // AUTHORISED: SMS will be available
    break;
    }
    private function authorisationStatus_changedHandler( event:AuthorisationEvent ):void
    {
    trace( "authorisationStatus_changedHandler: "+event.status );
    }

    Sending an SMS

    Once you have authorisation, sending an SMS is a simple matter of calling sendSMS:

    if (Message.service.smsManager.isSMSSupported)
    {
    var sms:SMS = new SMS();
    sms.address = "0444444444";
    sms.message = "Testing Message ANE";

    Message.service.smsManager.sendSMS( sms );
    }

    Subscription Info

    In some devices there are multiple SIM cards and you may wish to specify the subscription to use to send the SMS.

    Firstly you must add the additional permission to READ_PHONE_STATE to be able to access the subscription information.

    Then call getSubscriptions() to retrieve an array of SubscriptionInfo objects representing the different sims.

    var subs:Array = Message.service.smsManager.getSubscriptions();
    for each (var sub:SubscriptionInfo in subs)
    {
    trace( "SIM: ["+sub.id+"] " + sub.displayName + "/"+sub.carrierName);
    }

    When sending an SMS you can specify the subscription id to use to send the SMS:

    Message.service.smsManager.sendSMS( sms, sub.id );

    Note: This is only supported on Android API v22+. If it is not supported (or if you haven't requested the additional permission) getSubscriptions() will return an empty array and the default sim will be used to send messages.

    Events

    You can listen for several events, as defined in the MessageSMSEvent class, see the documentation in that class for more information on the events.

    Message.service.smsManager.addEventListener( MessageSMSEvent.MESSAGE_SMS_CANCELLED,     smsEventHandler );
    Message.service.smsManager.addEventListener( MessageSMSEvent.MESSAGE_SMS_DELIVERED, smsEventHandler );
    Message.service.smsManager.addEventListener( MessageSMSEvent.MESSAGE_SMS_RECEIVED, smsEventHandler );
    Message.service.smsManager.addEventListener( MessageSMSEvent.MESSAGE_SMS_SENT, smsEventHandler );
    Message.service.smsManager.addEventListener( MessageSMSEvent.MESSAGE_SMS_SENT_ERROR, smsEventHandler );


    function smsEventHandler( event:MessageSMSEvent ):void
    {
    trace( event.type +"::"+ event.details + "::"+event.sms.toString() );
    }
    - + \ No newline at end of file diff --git a/docs/nativemaps/add-the-extension/index.html b/docs/nativemaps/add-the-extension/index.html index 33a73a35fa7..fc205c46145 100644 --- a/docs/nativemaps/add-the-extension/index.html +++ b/docs/nativemaps/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ AIR application's Java package name, something like air.com.distriqt.test. Generally this is your AIR application id prefixed by air. unless you have specified no air flair in your build options.

    <manifest android:installLocation="auto">

    <!-- Include required permissions for Google Maps API to run. -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- Replace 'APPLICATION_PACKAGE' here with your application package eg: 'air.your.app.id' -->
    <uses-permission android:name="APPLICATION_PACKAGE.MAPS_RECEIVE" android:protectionLevel="signature"/>

    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

    <queries>
    <package android:name="com.google.android.apps.maps" />
    </queries>

    <application>

    <activity android:name="com.distriqt.core.auth.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:exported="false" />


    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
    <activity android:name="com.google.android.gms.common.api.GoogleApiActivity"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:exported="false"/>

    <!-- Replace "YOUR_API_KEY" with your Android Google Maps API Key -->
    <meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_API_KEY" />


    <uses-library android:name="org.apache.http.legacy" android:required="false" />


    </application>
    </manifest>

    iOS

    InfoAdditions

    Nothing specific required here.

    note

    If you are going to be sending data to a url don't forget to add the appropriate NSAppTransportSecurity definitions to your info additions.

    For example to allow all http requests:

    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    </dict>

    User Location

    If you plan to use the automatic feature to display the user location you will need to add some additional items to your configuration.

    To add these additions you need to add some additional configuration. Firstly add a custom iOS configuration file by running:

    apm generate config

    Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the usage strings:

    <plist version="1.0">
    <dict>

    <!-- iOS 6,7 -->
    <key>NSLocationUsageDescription</key>
    <string>${locationUsageDescription}</string>

    <!-- iOS 8 + -->
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>${locationWhenInUseUsageDescription}</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>${locationAlwaysUsageDescription}</string>

    <!-- iOS 11 + -->
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>${locationAlwaysAndWhenInUseUsageDescription}</string>

    </dict>
    </plist>
    note

    The values for these usage strings will be pulled from your project configuration.

    Edit the config/android/AndroidManifest.xml file that was generated to resemble the following, adding the location permissions:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <application>

    <meta-data android:name="android.max_aspect" android:value="2.5" />

    </application>

    </manifest>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    - + \ No newline at end of file diff --git a/docs/nativemaps/apple-maps/index.html b/docs/nativemaps/apple-maps/index.html index becc8caeb7f..bf28f21ef9a 100644 --- a/docs/nativemaps/apple-maps/index.html +++ b/docs/nativemaps/apple-maps/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Apple Maps

    Nothing particular is required to setup your application for Apple Maps on iOS.

    Just make sure you add the correct authorisation additions for location access if you plan to display the user's location. See Request Authorisation.

    - + \ No newline at end of file diff --git a/docs/nativemaps/changelog/index.html b/docs/nativemaps/changelog/index.html index 922c5bcc888..2fb56cb3bd2 100644 --- a/docs/nativemaps/changelog/index.html +++ b/docs/nativemaps/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.26 [v5.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
    feat(android): Move to new permissions request process

    2022.03.09 [v5.1.0]

    Android: Updated Maps SDK to v18.0.2

    Update package and docs for Android 31 and latest dependencies
    Added descriptions to air package parameters

    2022.02.08 [v5.0.18]

    Update package and docs for Android 31
    Update docs to use apm
    Fix missing dependency and config parameters in air packages

    2021.10.08 [v5.0.17]

    Add air package
    Remove ios minimum version flag
    Add security flag to auth activity on android

    2020.03.20 [v5.0.011]

    Android X migration (resolves #214)

    2019.11.21 [v4.0.008]

    iOS: Corrected custom marker drag interactions (resolves #212)

    2019.10.17 [v4.0.003]

    Updated documentation

    2019.08.15 [v4.0.003]

    Android 64bit support (resolves #207)
    Updated minimum iOS version to 9.0

    2019.04.02 [v3.5.211]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode

    2018.11.27 [v3.4.208]

    Updated documentation

    2018.11.27 [v3.4.207]

    Updated to Google Play Services v16.0.5 
    Removed application keys

    2018.11.14 [v3.3.202]

    Android: Added additional checks on map ready handler (#198)

    2018.06.01 [v3.3.201]

    Android: Updated to Google Play Services v15+

    2018.03.02 [v3.3.199]

    iOS: Changed z-index implementation on iOS 11 + to fix crashes (resolves #188)

    2018.02.27 [v3.3.166]

    iOS: Fixed crash with destroy map containing markers (resolves #188)

    2018.01.09 [v3.3.156]

    iOS: Resolved visibility issue (resolves #185)
    iOS: Resolved iOS 11 z-index issues (resolves #179)
    Android: Improved performance of Polyline additions (resolves #126)
    Android: Improved performance of Polygon additions (resolves #178)
    Added PolyUtils

    2017.10.13 [v3.2.098]

    Updated documentation (resolves #170)

    2017.09.02 [v3.2.096]

    Fixed issue with updating first added marker (resolves #163)

    2017.09.01 [v3.2.092]

    Android: Fixed issue with resetting anchor point for default icons (resolves #164)

    2017.08.31 [v3.2.090]

    Added Marker z index (resolves #121) 
    Added Custom Marker Icon offsets (resolves #54)
    iOS: Migrated to camera calls for all view actions (resolves #156, resolves #157 resolves #158)
    iOS: Corrected setCentre zoom issue (resolves #155)
    iOS: Added traffic for MapKit on iOS > 9

    2017.07.10 [v3.1.050]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.03.13 [v3.1.049]

    Android: Corrected authorisation status response (resolves #134)
    Android: Fix for prepareViewOrder hiding Stage elements (resolves #43)
    Projection implementation for screen / location conversions (resolves #115)
    Added some createMap viewport checks (resolves #97)

    2016.12.30 [v3.1.040]

    Updated documentation

    2016.12.02 [v3.1.040]

    iOS: Corrected setBearing and setAltitude animation flags (resolves #111)

    2016.11.28 [v3.1.039]

    Updated example

    2016.11.28 [v3.1.039]

    Android: Corrected showMap and hideMap functionality (resolves #85)
    Android: Added clear map styles by passing null (resolves #107)
    Android: Added check for bounds
    Removed limitation on setTilt method (resolves #109)

    2016.11.24 [v3.1.033]

    Android: Added setMapStyle for styling support (resolves #102)
    Added mapToolbarEnabled to options to disable directions and open in google maps options on a marker (resolves #101)
    Android: Fixed crash when dispose map while moving (#99)
    iOS: Added showScale to show the scale (resolves #86)

    2016.11.15 [v3.1.028]

    Updated example to new API

    2016.11.13 [v3.1.028]

    Changed createMap function to accept an initial position and zoom (resolves #95)
    Android: Corrected update marker function (resolves #93)

    2016.11.13 [v3.1.028]

    Changed  function to accept an initial position and zoom (resolves #95)
    Android: Corrected update marker function (resolves #93)

    2016.11.01 [v3.1.016]

    iOS: Corrected custom marker image scaling (resolves #92)

    2016.11.01 [v3.1.014]

    Removed debug trace statements (#91)

    2016.11.01 [v3.1.013]

    Corrected issue with marker events (resolves #91)

    2016.10.31 [v3.1.004]

    Added new drag touch events (resolves #89)

    2016.10.18 [v3.0.019]

    Android: Fixed zoom changing during call to setCentre (resolves #81)

    2016.10.07 [v3.0.018]

    Major update to latest APIs and many bug fixes (resolves #72, resolves #77, resolves #76, resolves #70, resolves #69, resolves #60, resolves #44, resolves #38)
    Android: Corrected view order (resolves #52)
    Android: Dangerous permissions for v23+ (resolves #51)
    Android: Fixed keyboard event issues (resolves #37)

    2015.11.26

    Update ANE file

    2015.11.24

    Added key press handlers and redirection from the map view to correctly pass key events to the AIR application

    2015.03.20

    Correctly added the new version of the ANE

    2015.03.19

    Updated to use our shared GooglePlayServices library, added a fix for z-ordering issued on Android

    2015.01.06

    Added 64bit support, added support for new iOS8 location permissions to allow geolocation services

    2014.12.12

    Updated example changing references to 'developer key'

    2014.12.11

    New application based key check, removing server checks
    iOS: Implemented autoreleasepools for all C function calls
    - + \ No newline at end of file diff --git a/docs/nativemaps/controlling-the-view/index.html b/docs/nativemaps/controlling-the-view/index.html index 1dbf6c33e42..4ada71cf1dc 100644 --- a/docs/nativemaps/controlling-the-view/index.html +++ b/docs/nativemaps/controlling-the-view/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ Setting the bounds will change the currently displayed map area.

    Setting the bounds is achieved by calling the setBounds function. This takes a LatLngBounds parameter which defines the south-west and north-east corners the map. The map will change to ensure this area is displayed within the map view.

    var bounds:LatLngBounds = new LatLngBounds(
    new LatLng(-27.5, 150 ),
    new LatLng(-27.0, 155 )
    );

    NativeMaps.service.setBounds( bounds );
    - + \ No newline at end of file diff --git a/docs/nativemaps/create-a-map/index.html b/docs/nativemaps/create-a-map/index.html index 13ef7e80312..96192dda454 100644 --- a/docs/nativemaps/create-a-map/index.html +++ b/docs/nativemaps/create-a-map/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ the application's view in order to allow the map layer to be rendered consistently.

    This method must be called before you create a map.

    Using this method will cause a short flash of a black screen while the view order is modified. Unfortunately there is no way to avoid this currently. However, since you can do this at any time after your application has started (once the main class is added to the stage), you can choose an appropriate time in your application's life cycle, before you create a map, where it will be least noticeable by the user.

    If you do not call this method before creating a map, it will be called automatically.

    if (NativeMaps.isSupported)
    {
    NativeMaps.service.prepareViewOrder();
    }

    Create the Map

    Creating a map is a simple process of calling the createMap function, passing the required viewport (width, height, x and y) and the map type.

    var viewport:Rectangle = new Rectangle( 0, 0, 500, 800 );
    NativeMaps.service.createMap( viewport, MapType.MAP_TYPE_HYBRID );

    There are also some events around the creation of a map that allow you to be notified when the map is created and ready to be used.

    var viewport:Rectangle = new Rectangle( 0, 0, 500, 800 );

    NativeMaps.service.addEventListener( NativeMapEvent.MAP_CREATED, mapCreatedHandler );

    var success:Boolean = NativeMaps.service.createMap( viewport, MapType.MAP_TYPE_HYBRID );
    if (success)
    {
    trace( "Map creation started successfully" );
    }
    else
    {
    trace( "Map creation failed - most likely a map has already been created" );
    }

    ...

    private function mapCreatedHandler( event:NativeMapEvent ):void
    {
    trace( "Map created" );
    }

    Set the map centre

    The createMap function also takes some additional parameters to set the initial location and zoom of the map

    var viewport:Rectangle = new Rectangle( 0, 0, 500, 800 );
    var centre:LatLng = new LatLng( -27.0, 155 );
    var zoom:Number = 3;

    NativeMaps.service.createMap( viewport, MapType.MAP_TYPE_HYBRID, centre, zoom );

    Timing

    Some crashes or problems can be caused by trying to initialise and create a map too quickly when your app starts up. For example, a lot of developers add all their code to init, create and set up a map in the addedToStage handler of the main class.

    This can be problematic, because the extension needs to perform some view reordering and modification to fix the z-indexing problem. We strongly suggest:

    - + \ No newline at end of file diff --git a/docs/nativemaps/google-maps/index.html b/docs/nativemaps/google-maps/index.html index 7d623a26591..be183dc1477 100644 --- a/docs/nativemaps/google-maps/index.html +++ b/docs/nativemaps/google-maps/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ to the application id and the SHA-1 fingerprint of your signing certificate.

    You'll need the SHA1 fingerprint of your signing certificate here. This is the certificate you use to sign your application.

    keytool -exportcert -keystore [YOUR_CERTIFICATE_PATH] -storepass [YOUR_CERT_PASSWORD]  -list -v -storetype PKCS12

    If you wish to test debug builds you must use the debug certificate used in Flash Builder and enter this fingerprint here. You should update it when beta testing to your own certificate. The following command retrieves the SHA1 signature for the debug certificate used in Flash Builder (on OSX/macOS):

    keytool -exportcert -keystore /Applications/Adobe\ Flash\ Builder\ 4.7/eclipse/plugins/com.adobe.flexide.multiplatform.android_4.7.0.349722/resources/debug-certificate-android.p12 -storepass debug  -list -v -storetype PKCS12

    Read more about restricting the API key here

    - + \ No newline at end of file diff --git a/docs/nativemaps/index.html b/docs/nativemaps/index.html index e7be8026615..21414bd35d7 100644 --- a/docs/nativemaps/index.html +++ b/docs/nativemaps/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Native Maps

    The Native Maps allows you to display native iOS Apple maps and Android Google maps with interactivity and overlays in your applications. 

    This allows you to provide high performance mapping applications well integrated with your AIR application. Select between normal, hybrid and satellite map types and control the view setting positions, bounds, zoom and tilt.

    You can add markers and draw custom overlays using polylines etc and you can draw the map to a bitmap if you require to animate the map in AIR.

    The simple API allows you to quickly integrate high performance mapping solution in your AIR application in just a few lines of code. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with dialogs quickly and easily.

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests. Identical code base can be used across all supported platforms allowing you to concentrate on your application and not device specifics.

    Features

    • Seamlessly integrate native OS maps in your app
      • Access Apple Maps on iOS;
      • Access Google Maps on Android;
    • Enable or disable normal user touch interaction
    • Controls: Control map movement, panning and zooming via code
    • Layers: Enable traffic overlays, indoor and 3D views, tilt and bearing on Android
    • Markers: Add and remove markers with info windows
    • Enable draggable markers and receive touch and drag marker events
    • Drawing: Custom Polyline and Polygon overlay drawing
    • User location updates and follow modes on iOS
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    More information here:

    com.distriqt.NativeMaps

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/nativemaps/initialise-the-extension/index.html b/docs/nativemaps/initialise-the-extension/index.html index 14ad05b2a70..c0cb99012de 100644 --- a/docs/nativemaps/initialise-the-extension/index.html +++ b/docs/nativemaps/initialise-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Initialise the Extension

    Supported

    You should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    if (NativeMaps.isSupported)
    {
    // Functionality here
    }

    Check Google Play Services Availability

    This extension requires the use of Google Play Services.

    You should use the GoogleApiAvailability helper in the com.distriqt.playservices.Base ANE. The documentation for this class is available in the Google Play Services wiki.

    For example:

    import com.distriqt.extension.playservices.base.ConnectionResult;
    import com.distriqt.extension.playservices.base.GoogleApiAvailability;
    var result:int = GoogleApiAvailability.instance.isGooglePlayServicesAvailable();
    if (result != ConnectionResult.SUCCESS)
    {
    if (GoogleApiAvailability.instance.isUserRecoverableError( result ))
    {
    GoogleApiAvailability.instance.showErrorDialog( result );
    }
    else
    {
    trace( "Google Play Services aren't available on this device" );
    }
    }
    else
    {
    trace( "Google Play Services are Available" );
    }

    If Google Play Services aren't available then you won't be able to use the functionality in this extension.

    - + \ No newline at end of file diff --git a/docs/nativemaps/migrating-to-androidx/index.html b/docs/nativemaps/migrating-to-androidx/index.html index 20c07fcda04..7307337cf01 100644 --- a/docs/nativemaps/migrating-to-androidx/index.html +++ b/docs/nativemaps/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/nativemaps/migrating-to-v5.2/index.html b/docs/nativemaps/migrating-to-v5.2/index.html index 9f2c41dc71c..f86a760bf18 100644 --- a/docs/nativemaps/migrating-to-v5.2/index.html +++ b/docs/nativemaps/migrating-to-v5.2/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v5.2

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/nativemaps/overlays---markers/index.html b/docs/nativemaps/overlays---markers/index.html index 64d273fcd13..0165542d1af 100644 --- a/docs/nativemaps/overlays---markers/index.html +++ b/docs/nativemaps/overlays---markers/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Overlays - Markers

    Markers are pins located at a single location. They can be used to identify places of interest.

    A marker is represented by the MapMarker class.

    Adding a Marker

    To add a marker, create an instance of the MapMarker class and then pass this object to the addMarker function.

    var marker:MapMarker = new MapMarker( "demo marker" )
    .setPosition( new LatLng( 50, 3 ) );

    NativeMaps.service.addMarker( marker );

    This will added the marker to the map using the specified options. The marker will appear immediately at the specified position (animating in if selected).

    Z Order

    You can set the z-index of markers to ensure certain markers remain above others. The z-index specifies the stack order of this marker, relative to other markers on the map. A marker with a high z-index is drawn on top of markers with lower z-indexes. The default z-index value is 0.

    To change the z-index simply set the zIndex property of the MapMarker:

    var marker:MapMarker = new MapMarker( "demo marker" )
    .setPosition( new LatLng( 50, 3 ) )
    .setZIndex( 300 );

    MapKit iOS 11+

    With iOS 11 Apple have introduced some major changes as to how the z ordering of markers occurs.

    We can no longer apply a z index to simple "pin" markers, i.e. markers without a custom icon. The z-index of markers without a custom icon will be managed by the internal logic of MapKit. We have however been able to override this behaviour for markers with a custom icon.

    Custom Marker Icons

    You can use your own imagery for markers, by loading or creating a BitmapData object and creating a CustomMarkerIcon with a unique id. You then pass this icon to the extension through the addCustomMarkerIcon function. Once you have added a custom marker icon to the extenion you can use the unique id to create markers using the custom icon.

    For example, firstly create a marker icon from an embedded Marker image asset:

    var markerImage:Bitmap = new Marker() as Bitmap;

    var markerIcon:CustomMarkerIcon = new CustomMarkerIcon( "UNIQUE_MARKER_ID" )
    .setImage( markerImage.bitmapData )

    NativeMaps.service.addCustomMarkerIcon( markerIcon );

    Then create a marker using this icon:

    var marker:MapMarker = new MapMarker()
    .setPosition( new LatLng( 50, 3 ) )
    .setCustomIconId( "UNIQUE_MARKER_ID" );

    NativeMaps.service.addMarker( marker );

    Offsets

    You can set the offset to correctly place your icon at the position by specifying the centerOffset point of the CustomMarkerIcon. The centerOffset point is the offset in pixels from the center of the marker image to the position that gets placed at the markers coordinate. Positive offset values move the icon down and to the right, while negative values move it up and to the left.

    By default, the center of the marker icon is placed over the coordinate of the marker. i.e. offsets of 0.

    So to demonstrate, to use the bottom middle of the image as the anchor point you would set the x offset to be 0 and the y offset to be - imageHeight / 2:

    var markerImage:Bitmap = new Marker() as Bitmap;

    var markerIcon:CustomMarkerIcon = new CustomMarkerIcon( "MARKER_ID_1" )
    .setImage( markerImage.bitmapData )
    .setCenterOffset( 0, -markerImage.height * 0.5 );

    Interaction

    Touch Events

    You can listen for a touch events on markers by listening for the NativeMapEvent.MARKER_TOUCHED event.

    NativeMaps.service.addEventListener( NativeMapEvent.MARKER_TOUCHED, marker_touchHandler );

    This event will contain the identifier of the marker that was touched, which can be retrieved using the getMarker function. For example:

    function marker_touchHandler( event:NativeMapEvent ):void
    {
    var selectedMarker:MapMarker = NativeMaps.service.getMarker( event.markerId );

    // Change marker as required

    NativeMaps.service.updateMarker( selectedMarker );
    }

    Drag Events

    If you have made a marker draggable (see MapMarker.setDraggable()) then you can listen for the NativeMapEvent.MARKER_DRAG_START and NativeMapEvent.MARKER_DRAG_END events to handle drag start and stop events.

    NativeMaps.service.addEventListener( NativeMapEvent.MARKER_DRAG_START, marker_dragStartHandler );
    NativeMaps.service.addEventListener( NativeMapEvent.MARKER_DRAG_END, marker_dragEndHandler );

    function marker_dragStartHandler( event:NativeMapEvent ):void
    {
    trace( "drag start for marker id: " + event.markerId );
    }

    function marker_dragEndHandler( event:NativeMapEvent ):void
    {
    trace( "drag end for marker id: " + event.markerId );
    }
    - + \ No newline at end of file diff --git a/docs/nativemaps/overlays---polygons/index.html b/docs/nativemaps/overlays---polygons/index.html index b8abc161386..aec790d5f7c 100644 --- a/docs/nativemaps/overlays---polygons/index.html +++ b/docs/nativemaps/overlays---polygons/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Overlays - Polygons

    Polygons are an extension of a polyline allowing you to fill the area contained within the line, so they can be used to draw shapes on the map.

    A polygon is represented by the Polygon class.

    Adding a Polygon

    To add a polygon, create an instance of the Polygon class and pass the object to the addPolygon function.

    var polygon:Polygon = new Polygon();

    polygon.setColour( 0xFFFF00FF );
    polygon.setFillColour( 0xFF00FF00 );

    polygon.addPoint( new LatLng( -27.5, 150 ) );
    polygon.addPoint( new LatLng( -27.5, 151 ) );
    polygon.addPoint( new LatLng( -27.0, 150 ) );

    NativeMaps.service.addPolygon( polygon );

    Z Order

    You can set the z-index of a polygon to ensure certain polygons remain above other overlays. The z-index specifies the stack order of this line, relative to other overlays on the map.

    A high z-index is drawn above objects with lower z-indexes. The default z-index value is 0.

    To change the z-index simply set the zIndex property of the Polygon:

    var polygon:Polygon = new Polygon();
    polygon.setZIndex( 300 );

    Encoded Path

    As a polygon can be made up of a large number of points conversion from AS3 to native objects can be time consuming process.

    In order to speed this up we suggest investigating encoding a polygon as a string and using the encoded path instead of an Array of LatLng values. This reduces the conversions needed from many LatLng objects to a single String and will speed up the conversion considerably.

    To set the encoded path of a polygon use the setEncodedPath function:

    var polygon:Polygon = new Polygon();
    polygon.setEncodedPath( encodedPath );

    Setting the encoded path of a polygon will override the points on Android.

    On iOS the encoded path is ignored.

    Encoding

    To encode a polygon you can use the encode function in the PolyUtil. This will take a series of LatLng objects and encode the path of these points as a String. You can read the details of this process in the PolyUtil class.

    var points:Vector.<LatLng> = ...;

    var encodedPath:String = PolyUtil.encode(points);

    Automatic encoding

    When adding a large polygon (> 100 points) the NativeMaps extension will automatically encode the points to improve performance. This means that you don't have to manually encode the path for large polygons but simply add points as normal and the extension will handle the encoding internally.

    Holes

    You can "cut out" areas of your polygons to remove fill areas of your polygon if you require.

    To do this you create another Polygon instance that represents the area of the hole and add it to your Polygon instance. The hole polygon will only be used as a series of points and the other options (such as fill colour) will be ignored.

    var hole:Polygon = new Polygon();
    hole.addPoint( new LatLng( 12, 10 ))
    .addPoint( new LatLng( 12, 11 ))
    .addPoint( new LatLng( 11, 10 ));

    polygon.addHole( hole );

    It is important that a hole must be enclosed completely by the parent polygon. Additionally holes must not overlay with other holes.

    - + \ No newline at end of file diff --git a/docs/nativemaps/overlays---polylines/index.html b/docs/nativemaps/overlays---polylines/index.html index 3f620b07d5f..d97620d97fa 100644 --- a/docs/nativemaps/overlays---polylines/index.html +++ b/docs/nativemaps/overlays---polylines/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Overlays - Polylines

    Polylines are a series of points that trace out a line. They can be used to outline areas or to indicate paths.

    A polyine is represented by the Polyline class.

    Adding a Polyline

    To add a polyline, create an instance of the Polyline class and pass the object to the addPolyline function.

    var polyline:Polyline = new Polyline()
    .setColour( 0xFFFF00FF )
    .addPoint( new LatLng( -27.5, 150 ) )
    .addPoint( new LatLng( -27.5, 151 ) );

    NativeMaps.service.addPolyline( polyline );

    Z Order

    You can set the z-index of a polyline to ensure certain lines remain above other overlays. The z-index specifies the stack order of this line, relative to other overlays on the map.

    A high z-index is drawn above objects with lower z-indexes. The default z-index value is 0.

    To change the z-index simply set the zIndex property of the Polyline:

    var polyline:Polyline = new Polyline()
    .setZIndex( 300 );

    Encoded Path

    As a polyline can be made up of a large number of points conversion from AS3 to native objects can be time consuming process.

    In order to speed this up we suggest investigating encoding a polyline as a string and using the encoded path instead of an Array of LatLng values. This reduces the conversions needed from many LatLng objects to a single String and will speed up the conversion considerably.

    To set the encoded path of a polyline use the setEncodedPath function:

    var polyline:Polyline = new Polyline()
    .setEncodedPath( encodedPath );

    Setting the encoded path of a polyline will override the points on Android.

    On iOS the encoded path is ignored.

    Encoding

    To encode a polyline you can use the encode function in the PolyUtil. This will take a series of LatLng objects and encode the path of these points as a String. You can read the details of this process in the PolyUtil class.

    var points:Vector.<LatLng> = ...;

    var encodedPath:String = PolyUtil.encode(points);

    Automatic encoding

    When adding a large polyline (> 100 points) the NativeMaps extension will automatically encode the points to improve performance. This means that you don't have to manually encode the path for large polylines but simply add points as normal and the extension will handle the encoding internally.

    - + \ No newline at end of file diff --git a/docs/nativemaps/overlays/index.html b/docs/nativemaps/overlays/index.html index 618733e713b..35279c83d21 100644 --- a/docs/nativemaps/overlays/index.html +++ b/docs/nativemaps/overlays/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content
    - + \ No newline at end of file diff --git a/docs/nativemaps/request-authorisation/index.html b/docs/nativemaps/request-authorisation/index.html index 8a664375691..2a8520e3c83 100644 --- a/docs/nativemaps/request-authorisation/index.html +++ b/docs/nativemaps/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ For most cases, this will be excessive for a mapping application and we suggest you only request the IN_USE permission, which allows your application access to the user's permission while your application is active.

    Implementation

    The following code will work across both platforms:

    switch (NativeMaps.service.authorisationStatus())
    {
    case AuthorisationStatus.ALWAYS:
    case AuthorisationStatus.IN_USE:
    trace( "User allowed access: " + NativeMaps.service.authorisationStatus() );
    break;

    case AuthorisationStatus.NOT_DETERMINED:
    case AuthorisationStatus.SHOULD_EXPLAIN:
    NativeMaps.service.requestAuthorisation( AuthorisationStatus.IN_USE );
    break;

    case AuthorisationStatus.RESTRICTED:
    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    trace( "User denied access" );
    break;
    }

    Usage Description

    You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

    The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

    You set these values through adding the usage description keys to your application descriptor's info additions or simply by setting up your configuration options in your apm project.

    - + \ No newline at end of file diff --git a/docs/nativemaps/touch-events/index.html b/docs/nativemaps/touch-events/index.html index bbd30fa00a9..48003815d19 100644 --- a/docs/nativemaps/touch-events/index.html +++ b/docs/nativemaps/touch-events/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ on the map that the user has touched.

    The event will contain the location as a LatLng instance.

    NativeMaps.service.addEventListener( NativeMapTouchEvent.TOUCH, nativeMaps_touchHandler );
    NativeMaps.service.addEventListener( NativeMapTouchEvent.TOUCH_LONG, nativeMaps_touchHandler );

    ...

    private function nativeMaps_touchHandler( event:NativeMapTouchEvent ):void
    {
    trace( event.type );
    trace( event.location.toString() );
    }

    Drag Events

    Drag events are dispatched whenever the map is moved by the user. This can be done by either using one or two fingers and as such doesn't have a specific location attached to it and location will be null.

    NativeMaps.service.addEventListener( NativeMapTouchEvent.DRAG_START, nativeMaps_dragHandler );
    NativeMaps.service.addEventListener( NativeMapTouchEvent.DRAG_END, nativeMaps_dragHandler );

    ...

    private function nativeMaps_dragHandler( event:NativeMapTouchEvent ):void
    {
    trace( event.type );
    }
    - + \ No newline at end of file diff --git a/docs/nativemaps/upgrade-new-version/index.html b/docs/nativemaps/upgrade-new-version/index.html index 311873818b4..a0e41ca4ca3 100644 --- a/docs/nativemaps/upgrade-new-version/index.html +++ b/docs/nativemaps/upgrade-new-version/index.html @@ -13,7 +13,7 @@ - + @@ -38,7 +38,7 @@ your app starts up. For example, a lot of developers add all their code to init, create and set up a map in the addedToStage handler of the main class.

    This can be problematic, especially in this new version because the extension needs to perform some view reordering and modification to fix the z-indexing problem. We strongly suggest:

    Documentation

    Latest documentation:

    http://airnativeextensions.com/extension/com.distriqt.NativeMaps

    - + \ No newline at end of file diff --git a/docs/nativetext/add-the-extension/index.html b/docs/nativetext/add-the-extension/index.html index 19140ef6643..4ebcbc95a31 100644 --- a/docs/nativetext/add-the-extension/index.html +++ b/docs/nativetext/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.NativeText

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.NativeText.ane # NativeText extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (NativeText.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/nativetext/changelog/index.html b/docs/nativetext/changelog/index.html index e95b5c0aabb..9a02e2a3fbb 100644 --- a/docs/nativetext/changelog/index.html +++ b/docs/nativetext/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.26 [v0.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.10.07 [v0.1.90]

    feat(docs): add documentation for usage of showKeyboardWithInput
    feat(airpackage): create airpackage

    2022.08.11 [v0.1.84]

    initial release of keyboard with input functionality
    - + \ No newline at end of file diff --git a/docs/nativetext/index.html b/docs/nativetext/index.html index 925dc4ad734..0aabc63e67e 100644 --- a/docs/nativetext/index.html +++ b/docs/nativetext/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    This extension was built by distriqt //

    NativeText

    Display native text fields in your AIR application

    Features

    • Allows display of the keyboard with a native text field displayed above the keyboard for input
    • Allows display of native text fields for better control of input and display options

    Documentation

    Latest documentation can be found on the documentation site. More information here:

    https://airnativeextensions.com/extension/com.distriqt.NativeText

    License

    You can purchase a license for using this extension:

    https://airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/nativetext/keyboard-input/index.html b/docs/nativetext/keyboard-input/index.html index 3ad87220821..d69ae245a3c 100644 --- a/docs/nativetext/keyboard-input/index.html +++ b/docs/nativetext/keyboard-input/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Keyboard Input

    This extension provides the ability to show a text field input that displays directly above the keyboard over your application content and is presented with the keyboard. This gives you a simple way for your users to input some text for your application to use.

    It also gives you the ability to use all the different keyboard types, auto correct and spell checking functionality built into the native OS.

    AndroidiOS

    Support

    Firstly you should check whether the device supports the native keyboard functionality by checking the isKeyboardSupported property:

    if (NativeText.instance.isKeyboardSupported)
    {
    // Keyboard is supported
    }

    If it isn't supported you should provide an alternative interface for input.

    Display

    To display the default keyboard input call the showKeyboardWithInput() method.

    var success:Boolean = 
    NativeText.instance.showKeyboardWithInput();

    This method will return a Boolean value indicating whether the keyboard will be shown.

    There are several events dispatched from the keyboard:

    • NativeKeyboardEvent.ACTIVATE: Dispatched when the keyboard is shown to the user;
    • NativeKeyboardEvent.DEACTIVATE: Dispatched when the user dismisses the keyboard;
    • NativeKeyboardEvent.INPUT: Dispatched when the user inputs characters into the text field;
    • NativeKeyboardEvent.ENTER: Dispatched when the enter or return key was pressed;

    Options

    There are two parameters to the showKeyboardWithInput() method, the first specifies options for the keyboard and the second specifies options for the text input. Together they control the operation of the keyboard and text input field.

    The default with no parameters is equivalent to:

    NativeText.instance.showKeyboardWithInput(
    new KeyboardOptions(),
    new InputOptions()
    );

    Keyboard Options

    The keyboard options controls things like the keyboard type (layout and type of keys displayed) and the return key type (value or symbol displayed on the enter key).

    You construct an instance of the KeyboardOptions class and then set the parameters on the instance:

    var keyboardOptions:KeyboardOptions = new KeyboardOptions()
    .setKeyboardType( KeyboardType.NUMBER_PAD )
    .setReturnKeyType( ReturnKeyType.CONTINUE );

    This should be passed as the first parameter to the showKeyboardWithInput() method. If you pass null then the default parameters will be used.

    Input Options

    The input options controls the way text is handled in the text input, including auto-correct, capitalisation and spell checking.

    Create an instance of the InputOptions class and then set the parameters on the instance:

    var inputOptions:InputOptions = new InputOptions()
    .setAutoCorrect( AutoCorrectType.YES )
    .setCapitalisation( AutoCapitalize.WORD )
    .setSpellCheckType( SpellCheckType.YES );

    This should be passed as the second parameter to the showKeyboardWithInput() method. If you pass null then the default parameters will be used.

    Setup

    There are some settings you should apply to your application to get best results from displaying the keyboard, particularly on Android.

    Set the softKeyboardBehavior in your app descriptor to be none. This allows the extension to better control the display of the keyboard over the top of your application content.

    Set fullScreen in your app descriptor to be false and use the Application extension to change the display mode. This is important, particularly for Android. Using this process allows us to correctly get the size of the keyboard and position the text field. If you don't do this you may see some display issues and misalignment with the keyboard and text field.

    To summarise, have the following in your application descriptor:

    <initialWindow>
    <fullScreen>false</fullScreen>
    <softKeyboardBehavior>none</softKeyboardBehavior>
    </initialWindow>

    Set your display mode using the Application extension, for example:

    Application.service.display.setDisplayMode( 
    DisplayMode.FULLSCREEN
    );
    - + \ No newline at end of file diff --git a/docs/nativewebview/add-the-extension/index.html b/docs/nativewebview/add-the-extension/index.html index 3496068dda6..ade0f5d44da 100644 --- a/docs/nativewebview/add-the-extension/index.html +++ b/docs/nativewebview/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -42,7 +42,7 @@ you access. For example the following adds an exception for the yourserver.com domain and subdomains.

    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSExceptionDomains</key>
    <dict>
    <key>yourserver.com</key>
    <dict>
    <!--Include to allow subdomains-->
    <key>NSIncludesSubdomains</key>
    <true/>
    <!--Include to allow HTTP requests-->
    <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
    <true/>
    </dict>
    </dict>
    </dict>

    To read more about this there is a great article here

    To add these additions you need to add some additional configuration. Firstly add a custom iOS configuration file by running:

    apm generate config ios

    Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the NSAppTransportSecurity node:

    <plist version="1.0">
    <dict>

    <key>NSAppTransportSecurity</key>
    <dict>
    <!-- Include to allow all connections -->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    </dict>

    </dict>
    </plist>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    Windows

    .Net Framework

    This extension requires v4.8 or higher of the .Net framework. This should come preinstalled on any Windows 10 or higher machine so if you are targetting those you should not have to do anything. If however you are targetting older versions of Windows you must ensure .Net v4.8 or higher is installed either manually or as part of an installer.

    C++ Redistributable

    The native code has a dependency on the Visual C++ Redistributable package. This package contains code that is required to run code developed using C++ in Visual Studio and is very common amongst Windows applications.

    There are two ways to ensure this is available to your application:

    The first is the suggested method. Installing the redistributable via an installer allows it to be put into the windows update process, allowing bug fixes and security updates to be handled automatically.

    The last method is only advised if you need a complete standalone application, where you don't (or cannot) use an installation process. This requires you to package DLLs from the redistributable with your application. It is not advised as you will miss out on critical updates and security patches from Microsoft.

    For development you can manually download and install the redistributable package from here.

    Creating an Installer

    There are many methods to create application installers and many tutorials available. We suggest you find a method suitable to your environment and application and utilise the tutorials online.

    Some methods include:

    Tutorials:

    You need to include the C++ Redistributable in the installer, there are many examples and documentation online to achieve this.

    The advantage of this method is that the libraries will be updated along with any system updates and will not require manual updating of the libraries and releasing of your application.

    Packaging DLLs

    Packaging the DLLs into your application involves copying the required DLLs into your application root and including in your application package.

    Contact us for the latest information on packaging the dll's directly, however we do not advise using this technique.

    The following DLLs are the critical ones, (XXX will need to be replaced with the current required version):

    You should ensure you are allowed to package these files as per the Microsoft Software License terms but generally these are safe to redistribute subject to the license terms. More information here: Redistributing Visual C++ Files

    You should get legal advice if you are unsure.

    MacOS

    No specific additions are required for macOS.

    - + \ No newline at end of file diff --git a/docs/nativewebview/browser-view/index.html b/docs/nativewebview/browser-view/index.html index 6536972189d..6d5b52ce54d 100644 --- a/docs/nativewebview/browser-view/index.html +++ b/docs/nativewebview/browser-view/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ documentation for details.

    Imports

    When using the Browser view you will be interacting with several classes and interfaces. The main functionality is defined in the BrowserView interface and you will be listening for the BrowserViewEvent as described.

    To use these classes you will need the following import statements:

    import com.distriqt.extension.nativewebview.browser.BrowserView;
    import com.distriqt.extension.nativewebview.events.BrowserViewEvent;

    Options

    You can specify options when opening a browser view by creating an instance of the BrowserViewOptions class and passing that as the second parameter to the openWithUrl function:

    var options:BrowserViewOptions = new BrowserViewOptions();

    NativeWebView.service.browserView.openWithUrl( "http://airnativeextensions.com", options );

    Colours

    You can change the background colour of the browser view tool bar by specifying the primary colour:

    options.primaryColour = 0xFF0000;

    The primary colour is used on iOS 10+ and Android as the background colour of the toolbar.

    You can change the text in the toolbar by specifying the secondary colour. This is currently only supported on iOS 10+.

    options.secondaryColour = 0x000000;

    Animations

    On Android you can select the in and out animations by setting the animationIn and animationOut properties.

    These animations control how the browser view is shown and hidden. For example to slide the browser view in from the bottom and back out to the bottom:

    options.animationIn = BrowserViewOptions.SLIDE_BOTTOM;
    options.animationOut = BrowserViewOptions.SLIDE_TOP;

    The out animation is easier thought of as the direction your application will animate in rather than the view out, so in the above, the browser view would slide in from the bottom and then when closing the application will slide in from the top pushing the browser view out the bottom.

    Potential values are:

    The defaults are SLIDE_LEFT and SLIDE_RIGHT for the animationIn and animationOut properties respectively, so that the view will slide in from the left and back out towards the left.

    note

    The out animation is only used when the user presses the close button. If you programmatically close the view using the close() function the animation will not be shown.

    - + \ No newline at end of file diff --git a/docs/nativewebview/changelog/index.html b/docs/nativewebview/changelog/index.html index 7143b06e30f..ac08d6b47f4 100644 --- a/docs/nativewebview/changelog/index.html +++ b/docs/nativewebview/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.10 [v7.1.0]

    feat(debugging): add enableDebugging flag to enable debugging of webviews where explicit setting is required (resolves #316)

    2023.07.23 [v7.0.0]

    feat(windows): update cef (chrome) version to v114.2.12 - requires .net 4.8 (resolves #313)

    2023.05.26 [v6.0.0]

    feature(android): add support for AIR running in background thread (resolves #307)

    2023.02.22 [v5.5.0]

    feat(macos): add support for apple silicon processors (resolves #283)

    2023.02.22 [v5.5.0]

    feat(macos): add support for apple silicon processors (resolves #283)

    2023.01.26 [v5.4.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
    feat(android): Move to new permissions request process

    2022.11.02 [v5.3.12]

    fix(android): update to fix some minor focus issues with the latest AIR SDK (resolves #289)

    2022.11.02 [v5.3.12]

    fix(android): update to fix some minor focus issues with the latest AIR SDK (resolves #289)

    2022.06.15 [v5.3.11]

    fix(android): set default text zoom on webview settings - appears to have changed the default appearance to match chrome more closely (resolves #287)

    2022.03.23 [v5.3.10]

    Correct reporting of isSupported for M1 macOS (resolves #283)

    2022.02.08 [v5.3.9]

    Update package and docs for Android 31
    Update docs to use apm

    2021.10.25 [v5.3.8]

    Update Android for API 30, include queries requirement in docs (resolves #271)
    Add new airbridge.js to add a message stack to handling multiple messages (resolves #267)

    2021.10.12 [v5.3.7]

    Add air package
    Android: Activity window security flag updates (resolves #250)
    Android: Corrected draw viewport functionality on android
    Windows: Added windows 64bit support (resolves #255)

    2021.04.21 [v5.2.383]

    iOS: Fixed issue with browser view failing to initialise correctly (resolves #252)

    2020.12.11 [v5.2.378]

    Windows: Corrected broken default CachePolicy implementation (resolves #233)
    Windows: Changed storage location of debug.log output (resolves #234)

    2020.12.04 [v5.2.362]

    Fixed browser view failing on devices with Chrome not set as default browser (resolves #232)
    Applied global user agent as default for all web views
    Windows: Implemented cache policy (resolves #231)
    Deprecated wiki

    2020.11.16 [v5.1.341]

    Android: Fix for Android WebView bug with href links on images (resolves #229)

    2020.11.11 [v5.1.338]

    Android: Implemented linkTargetAction (resolves #227)
    macOS/iOS fixed clearing of cookies with latest OS versions
    Added pageUp/pageDown/scrollTo/scrollBy functionality
    Windows: Changed the way target=_blank are handled (resolves #222)
    Windows: Added ability to set additional cef command line args (resolves #224)

    2020.10.02 [v5.0.269]

    Windows implementation
    macOS implementation

    Updates:
    - New initialisation process
    - Android: Added handling of potential null reference (resolves #213)

    2020.03.20 [v4.0.025]

    Android X migration (resolves #206)
    iOS: Removed UIWebView usage to comply with Apple deprecation (resolves #194)

    2020.02.07 [v3.0.020]

    Updated docs

    2020.02.07 [v3.0.020]

    Android: Added some additional handling of the airbridge before page load complete (#205)

    2019.10.16 [v3.0.017]

    iOS: Fixed NSInternalInconsistencyException crash due to multiple identical load requests (resolves #196)

    2019.09.10 [v3.0.015]

    Android 64bit support (resolves #188)
    iOS: Keyboard hides input area (resolves #134)
    iOS: WebView notch related issues (resolves #187, resolves #186, resolves #180)
    iOS: BrowserView corrected issue with notch and hidden status bar (resolves #176)
    iOS: Changed the default to use WKWebView if useWebKitIfAvailable not specified (#194)
    Android: Resolved scroll issue (resolves #177)
    Android: Resolved text input focus issues (resolves #154)
    Android: Fixed crash on Android 4.4 (resolves #144)

    2019.02.27 [v2.5.182]

    Updated minimum iOS version to 8.0 (resolves #183)
    Embedded iOS bitcode

    2018.12.05 [v2.4.174]

    iOS: Corrected access to cookies on iOS 12 (resolves #171)

    2018.06.20 [v2.3.157]

    iOS: Corrected timing of browser view closed event (resolves #162)

    2018.05.30 [v2.3.148]

    Android: Added ability for video to go fullscreen (resolves #145)
    Android: Implemented disableLongPressGestures to disable copy / paste menu (resolves #113)
    BrowserView: Added cause to events to distinguish close reason (resolves #158)

    2018.04.17 [v2.2.118]

    Added options for browser view including colour and animations (resolves #90)
    Added ability to get cookies from current page (resolves #146)
    Added scroll bar style settings to control colour (resolves #123)
    Android: Fixed issue with loading linked local files (resolves #148, resolves #136)
    Android: Fixed double load of initial load url page (resolves #83)
    iOS: Resolved webkit cookie header issue (resolves #109)

    2018.03.14 [v2.2.039]

    iOS: Corrected browser view close button (#139)

    2018.02.28 [v2.2.038]

    Added the ability to close a browser view (resolves #139)
    iOS: Corrected local file access for WKWebView version (resolves #141)
    iOS: Limited display of PIP (resolves #131)

    2018.01.10 [v2.1.021]

    Android: Implemented ‘allow zooming’ flag (resolves #135)

    2017.08.08 [v2.1.009]

    Updated documentation

    2017.08.08 [v2.1.006]

    Visibility flag (resolves #9)
    Added setViewPort function

    2017.07.10 [v2.0.023]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.06.23 [v2.0.022]

    Updated browser view example

    2017.06.23 [v2.0.022]

    Added browser view example (#118)

    2017.03.01 [v2.0.020]

    Improved cookie handling with WKWebView (resolves #85)

    2017.01.10 [v2.0.015]

    Updated build for iOS 7 crash (resolves #98)

    2016.12.30 [v2.0.014]

    Updated documentation

    2016.12.30 [v2.0.014]

    Updated documentation

    2016.12.30 [v2.0.014]

    New documentation

    2016.12.03 [v2.0.014]

    Corrected documentation (resolves #88)

    2016.11.30 [v2.0.014]

    Updated documentation

    2016.11.30 [v2.0.014]

    Added Browser View for simple web page viewer (resolves #80)

    2016.08.08 [v1.23.001]

    Added geolocation settings (resolves #72)
    Implemented new versioning system

    2016.08.01

    Added cookie manager and a removeAllCookies function (resolves #58)

    2016.06.15

    Added setFocus and focus events function
    Android: Corrected text field focus operation (resolves #51)
    Android: Added ability to move content for input below keyboard (resolves #35)
    iOS: Added keyboardDisplayRequiresUserAction (resolves #50)

    2016.05.10

    Android: Added mediaPlaybackRequiresUserAction allowing autoplay video (resolves #47)

    2016.05.02

    Added custom request headers (resolves #37)
    Android: Fixed disposal of videos (resolves #45)

    2016.04.26

    Added cache memory and disk size control

    2016.04.26

    Android: Corrected issue when file chooser active when app moved to background (#42)

    2016.04.12

    Android: Added check for BrowseActivity and updated documentation (#42)

    2016.04.11

    Added allowScrolling property to disable scrolling on a WebView (resolves #41)
    Android: Implemented file form input launching a browse activity (resolves #42)

    2016.03.13

    iOS: Removed setAnimationsEnabled call affecting animations (#39)

    2016.03.06

    Corrected default lib missing variable (resolves #38)

    2016.02.19

    iOS: Update for loading local files in WKWebView on iOS 9 (#34)

    2016.02.02

    Android: Fix for window.location incorrectly returning for local files (#32)

    2016.01.29

    Android: Fixed issue with comments in javascript stopping page from loading correctly

    2015.12.03

    iOS: Fixed issue with WKWebView userAgent on first view

    2015.11.27

    iOS: Implemented WKWebView as alternative for UIWebView   
    Android: Corrected keyboard event interception preventing webview inputs (resolves #15)
    Android: Added some additional clean up on web view disposal (#14)
    Android: Fixed issue with removeEventListener (resolves #13)
    Added ability to specify baseUrl for loadString to use local assets in loaded html (resolves #17)
    Android: Fixed loading of local assets from local html (resolves #27)
    iOS: Added option to disable long press gestures (resolves #20)

    2015.07.23

    Android: Corrected last historyBack operation on local files (resolves #5)

    2015.07.23

    Added additional checks around the location property (#1)
    iOS: Corrected changing event dispatch (resolves #3)

    2015.07.22

    Android: Fixed issue with url encoded html links (#2)

    2015.07.22

    Android: Fixed passing get parameters to local files (#2)

    2015.07.22

    Corrected processing of url to correctly handle url encoded strings (#2)
    Android: Added permission to load scripts in local files

    2015.07.20

    Android: Added backgound colour and transparency options

    2015.07.20

    Added example packaged html files and airbridge.js

    2015.07.20

    Release version v1.0

    - + \ No newline at end of file diff --git a/docs/nativewebview/communication/index.html b/docs/nativewebview/communication/index.html index e2681d1db52..ba14461d6c0 100644 --- a/docs/nativewebview/communication/index.html +++ b/docs/nativewebview/communication/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ Calling the AirBridge.message( 'content-for-air' ); in your Javascript will cause a NativeWebViewEvent.JAVASCRIPT_MESSAGE event to be dispatched with the data value containing the message, 'content-for-air' in this case.

    The two important events here are:

    Android

    On Android the communication channel is only completely setup after the page load is complete. I.e after NativeWebViewEvent.COMPLETE. We suggest you wait for this event before attempting to communicate between the page and the application.

    To this end, we suggest implementing a function in your page that you call from AS3 after the NativeWebViewEvent.COMPLETE event has fired, which initialises your communication channel.

    We have implemented some handlers for this scenario but they may affect loading of the page and we suggest you take the above approach wherever possible.

    Example

    The following is an example from actionscript:

    var webView:WebView = NativeWebView.service.createWebView( new Rectangle( 0, 0, 400, 600 ) ) ;

    webView.addEventListener( NativeWebViewEvent.COMPLETE, webView_completeHandler );
    webView.addEventListener( NativeWebViewEvent.JAVASCRIPT_RESPONSE, javascriptResponseHandler );
    webView.addEventListener( NativeWebViewEvent.JAVASCRIPT_MESSAGE, javascriptMessageHandler );

    var file:File = File.applicationStorageDirectory.resolvePath( "example.html" );

    webView.loadURL( "file://"+file.nativePath );


    function completeHandler( event:NativeWebViewEvent ):void
    {
    webView.evaluateJavascript( "alert('message from AS3');" );
    }

    function javascriptResponseHandler( event:NativeWebViewEvent ):void
    {
    trace( "evaluateJavascript response: " + event.data );
    }

    function javascriptMessageHandler( event:NativeWebViewEvent ):void
    {
    // This is the message sent from the javascript
    // AirBridge.message i.e. 'content-for-air'
    trace( "message from JS: " + event.data );
    }

    communicating with the following html page:

    <html>
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script type="text/javascript" src="airbridge.js" ></script>
    <script>
    "use strict";
    function sendToAIR()
    {
    AirBridge.message( "content-for-air" );
    }
    </script>
    </head>

    <body>
    <h1>NativeWebView Example</h1>
    <p>
    <button type="button" onClick="sendToAIR()" >Example Call</button>
    </p>
    </body>

    </html>

    AIR Bridge Code

    This is the contents of the airbridge.js file

    /**
    * Air Bridge interface to communicate to actionscript through the NativeWebView ANE
    */

    var AirBridge = (function () {
    var instance;

    function createInstance() {
    var object = {};
    object.useWindowLocation = true;

    object.isWKWebView = false;
    if (navigator.platform.substr(0, 2) === "iP") {
    if (window.indexedDB) {
    object.isWKWebView = window.webkit && window.webkit.messageHandlers;
    }
    }

    object.messageStack = [];
    object.messageStackInterval = 1; // milliseconds interval
    object.messageInProgress = false;

    object.message = function (message) {
    object.messageStack.push(message);
    if (!object.messageInProgress) {
    object._checkNextMessageInStackTimeout();
    }
    };

    object._sendMessage = function (message) {
    object.messageInProgress = true;

    try {
    if (object.isWKWebView) {
    window.webkit.messageHandlers.airbridge.postMessage(message);
    } else if (!object.useWindowLocation) {
    NativeWebView.airBridge(message);
    } else {
    window.location = "airBridge:" + message;
    }
    } catch (err) {
    window.location = "airBridge:" + message;
    }

    setTimeout(
    object._checkNextMessageInStackTimeout,
    object.messageStackInterval
    );
    };

    object._checkNextMessageInStackTimeout = function () {
    object.messageInProgress = false;

    if (object.messageStack.length) {
    object._sendMessage(object.messageStack.shift());
    }
    };

    return object;
    }

    return {
    setUseWindowLocation: function (shouldUseWindowLocation) {
    if (!instance) {
    instance = createInstance();
    }
    instance.useWindowLocation = shouldUseWindowLocation;
    },

    message: function (message) {
    if (!instance) {
    instance = createInstance();
    }
    instance.message(message);
    },
    };
    })();

    Sending parameters to Javascript

    You can use the evaluateJavascript() function to send any Javascript to the loaded page, however sometimes it is useful to call a function in javascript and pass an array of parameters. Below we are going to go through some techniques to communicate parameters with your page.

    This first method is the simplest, constructing a String with the function name and parameters laid out:

    var javascript:String = "functionName( '" + param1 + "' )";
    _webView.evaluateJavascript( javascript );

    Developing on this you can also construct a utility function that takes a function name and array of parameters:

    function callJavascriptFunction( functionName:String, args:Array ):void 
    {
    var params:String = "";
    for (var i:int = 0; i < args.length; i++)
    {
    // Assuming strings, but you can add switching on type
    params += "'"+args[i] + "'";
    }
    var javascript:String = functionName + "( " + params + " )" ;
    _webView.evaluateJavascript( javascript );
    }

    You could use the JSON class to encode the parameters into a JSON string:

    function callJavascriptFunction( functionName:String, args:Array ):void 
    {
    var parametersJSON:String = JSON.stringify(args);
    var javascript:String = functionName + "( " + parametersJSON + " )" ;
    _webView.evaluateJavascript( javascript );
    }

    Then in your javascript side parse the JSON back into your parameters:

    function myFunction(parametersJSON):void
    {
    let parametersArray = JSON.parse(parametersJSON);

    // Use your parameters as required
    }
    - + \ No newline at end of file diff --git a/docs/nativewebview/create-a-webview/index.html b/docs/nativewebview/create-a-webview/index.html index 333069069fc..92e3d415dd3 100644 --- a/docs/nativewebview/create-a-webview/index.html +++ b/docs/nativewebview/create-a-webview/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Create a WebView

    Once you have initialised the extension, creating a web view is simply a matter of calling the createWebView() function with your parameters.

    The following example creates a WebView of size 400x600 and loads a URL. It also demonstrates some of the events dispatched by the WebView.

    var viewPort:Rectangle = new Rectangle( 0, 0, 400, 600 );

    var webView:WebView = NativeWebView.service.createWebView( viewPort ) ;

    You can then attach listeners and load content into the view

    webView.addEventListener( NativeWebViewEvent.LOCATION_CHANGE, webView_locationChangeHandler );
    webView.addEventListener( NativeWebViewEvent.COMPLETE, webView_completeHandler );
    webView.addEventListener( NativeWebViewEvent.ERROR, webView_errorHandler );

    webView.loadURL( "https://airnativeextensions.com" );

    The events give you information about the content in the view

    function webView_locationChangeHandler( event:NativeWebViewEvent ):void
    {
    trace( "location change: " + event.data );
    }

    function webView_completeHandler( event:NativeWebViewEvent ):void
    {
    trace( "load complete: " + event.data );
    }

    function webView_errorHandler( event:NativeWebViewEvent ):void
    {
    trace( "error: " + event.data );
    }

    Web View Options

    When creating a WebView you can specify some options as to how the view will handle certain content and interactions.

    To do so, create an instance of the WebViewOptions class and set the options as required. Some of these options are platform dependent so make sure you read the documentation in the WebViewOptions class.

    var options:WebViewOptions = new WebViewOptions();

    options.mediaPlaybackRequiresUserAction = true;
    options.allowInlineMediaPlayback = true;
    options.backgroundEnabled = true;
    options.allowZooming = true;
    options.cachePolicy = CachePolicy.LOAD_NO_CACHE;
    options.scrollBarStyle = WebViewOptions.SCROLLBAR_LIGHT;

    This then gets passed as the second parameter to the createWebView() function:

    var webView:WebView = NativeWebView.service.createWebView( viewPort, options );

    The link target action option determines how links with "_blank" targets are handled. In a normal browser situation these would open a new tab/window however in our environment you have the following options:

    • LinkTargetAction.SYSTEM_BROWSER: New windows / popups from blank targets will open in the system browser;
    • LinkTargetAction.CURRENT_WEBVIEW: Blank targets will load in the current webview;
    • LinkTargetAction.BLOCK: Blank targets will be blocked, the NativeWebViewEvent.LINK_BLOCKED event will be dispatched if you wish to handle them in your code.

    For example:

    var options:WebViewOptions = new WebViewOptions();
    options.linkTargetAction = LinkTargetAction.BLOCK;

    var webView:WebView = NativeWebView.service.createWebView( viewPort, options );
    webView.addEventListener( NativeWebViewEvent.LINK_BLOCKED, linkBlockedHandler );


    function linkBlockedHandler( event:NativeWebViewEvent ):void
    {
    trace( "Link was blocked: " + event.data );
    }
    - + \ No newline at end of file diff --git a/docs/nativewebview/index.html b/docs/nativewebview/index.html index 6d4eb280ff9..e6304240e3f 100644 --- a/docs/nativewebview/index.html +++ b/docs/nativewebview/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    NativeWebView

    The NativeWebView extension is designed to be a replacement version of the StageWebView, but much more useful.

    The simple API allows you to quickly integrate web views in your AIR application. Identical code base can be used across all supported platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with asset selection quickly and easily.

    Features

    • Browser View:
      • Android: Chrome Custom Tabs
      • iOS: Safari View Controller
    • HTML5 Video;
    • Touch events;
    • Capture BitmapData screenshot;
    • Communicate both ways using Javascript AS3->JS & JS->AS3;
    • Transparent background;
    • Additional page controls: auto play, background colour;
    • iOS: Air Printing;

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    This site forms the best source of detailed documentation for the extension along with the asdocs.

    More information here:

    com.distriqt.NativeWebView

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/nativewebview/initialise-the-extension/index.html b/docs/nativewebview/initialise-the-extension/index.html index 86e18442d28..ea8db18a3a4 100644 --- a/docs/nativewebview/initialise-the-extension/index.html +++ b/docs/nativewebview/initialise-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Initialise the Extension

    Supported

    You should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    if (NativeWebView.isSupported)
    {
    // Functionality here
    }

    Initialisation

    You must initialise the platform before attempting to utilise the extension. This initialisation process will configure any libraries that are needed by the extensions. Additionally certain platforms have configuration options that will apply to all webviews that are created using the extension.

    In order to specify these options and initialise the platform you must call initialisePlatform() with an instance of NativeWebViewOptions before creating any WebViews. If you don't then the extension will fail to create any WebView instances and your application may crash.

    For example:

    var options:NativeWebViewOptions = new NativeWebViewOptions()
    .setWindowsOptions(
    new WindowsOptions()
    )
    .setUserAgent("distriqt/webview");

    The initialise process is asynchronous so you can either use a callback:

    NativeWebView.service.initialisePlatform( options, function(success:Boolean):void
    {
    // You can now create web views
    });

    Or listen for the NativeWebViewEvent.INITIALISED event:

    NativeWebView.service.addEventListener( NativeWebViewEvent.INITIALISED, function( event:NativeWebViewEvent ):void
    {
    NativeWebView.service.removeEventListener( NativeWebViewEvent.INITIALISED, arguments.callee );
    // You can now create web views
    });
    NativeWebView.service.initialisePlatform( options );

    See the notes in the NativeWebViewOptions class for details and support of the specific options

    - + \ No newline at end of file diff --git a/docs/nativewebview/loading-packaged-files/index.html b/docs/nativewebview/loading-packaged-files/index.html index 1ac0db55ff2..e159765656e 100644 --- a/docs/nativewebview/loading-packaged-files/index.html +++ b/docs/nativewebview/loading-packaged-files/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ especially on Android.

    In the example application we have a directory named www that contains several example html files. In the following we show how to copy these to an accessible location and then load them into the web view.

    var webView:WebView = NativeWebView.service.createWebView( new Rectangle( 0, 0, 400, 600 ) ) ;

    var file:File;
    var fileUrl:String;
    if (NativeWebView.service.version.indexOf("Android") > 0)
    {
    // Android: Copy the application packaged files to an accessible location
    var packagedWWWRoot:File = File.applicationDirectory.resolvePath( "www" );
    var destination:File = File.applicationStorageDirectory.resolvePath( "www" );
    packagedWWWRoot.copyTo( destination, true );
    // Grab the file url
    file = File.applicationStorageDirectory.resolvePath( "www/example.html" );
    fileUrl = "file://"+file.nativePath;
    }
    else
    {
    // iOS:
    file = File.applicationDirectory.resolvePath( "www/example.html" );
    fileUrl = "file://"+file.nativePath;
    }

    webView.loadURL( fileUrl );
    - + \ No newline at end of file diff --git a/docs/nativewebview/location-changes/index.html b/docs/nativewebview/location-changes/index.html index 94e1f988dfe..ff28aef8a15 100644 --- a/docs/nativewebview/location-changes/index.html +++ b/docs/nativewebview/location-changes/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ from the web view and handle them differently. If you call event.preventDefault() then the location change will not occur and the NativeWebViewEvent.LOCATION_CHANGE will not be dispatched. The web view will not change.

    var webView:WebView = NativeWebView.service.createWebView( new Rectangle( 0, 0, 400, 600 ) ) ;

    webView.addEventListener( NativeWebViewEvent.LOCATION_CHANGING, webView_locationChangingHandler );
    webView.addEventListener( NativeWebViewEvent.LOCATION_CHANGE, webView_locationChangeHandler );

    webView.loadURL( "https://airnativeextensions.com" );

    function webView_locationChangingHandler( event:NativeWebViewEvent ):void
    {
    trace( "location changing to: " + event.data );

    // Stop the location change by calling 'event.preventDefault()'
    event.preventDefault();
    }

    function webView_locationChangeHandler( event:NativeWebViewEvent ):void
    {
    trace( "location changed to: " + event.data );
    }

    You may wish to see the WebViewOptions.linkTargetAction setting and handle BLOCKED links as well. See the documentation in the Web View Options

    - + \ No newline at end of file diff --git a/docs/nativewebview/migrating-to-androidx/index.html b/docs/nativewebview/migrating-to-androidx/index.html index 79a3be641bf..88448b87e7f 100644 --- a/docs/nativewebview/migrating-to-androidx/index.html +++ b/docs/nativewebview/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/nativewebview/migrating-to-v5.4/index.html b/docs/nativewebview/migrating-to-v5.4/index.html index 38ab017235c..668cfa9dd34 100644 --- a/docs/nativewebview/migrating-to-v5.4/index.html +++ b/docs/nativewebview/migrating-to-v5.4/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v5.4

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/nativewebview/migrating-to-v5/index.html b/docs/nativewebview/migrating-to-v5/index.html index b3fc6fc5da3..29cd80f3351 100644 --- a/docs/nativewebview/migrating-to-v5/index.html +++ b/docs/nativewebview/migrating-to-v5/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v5

    Version 5

    Version 5 of this extension introduces the desktop (windows/macOS) implementations and along with this several changes were made to the initialisation process to correctly setup the extension.

    Existing code will throw an Error with the message:

    "You must call initialisePlatform and await completion before using any of this extensions functionality."

    In order to correctly migrate to this version you need to add the following initialisation code to some point in your application before you attempt to create a WebView:

    var options:NativeWebViewOptions = new NativeWebViewOptions();
    NativeWebView.service.initialisePlatform( options, function(success:Boolean):void
    {
    // You can now create web views
    });

    This will correctly setup any libraries required by the platform and initialise the extension.

    More information here: Initialise the Extension

    - + \ No newline at end of file diff --git a/docs/nativewebview/position-size-visibility/index.html b/docs/nativewebview/position-size-visibility/index.html index de232a1e462..20cefd102eb 100644 --- a/docs/nativewebview/position-size-visibility/index.html +++ b/docs/nativewebview/position-size-visibility/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ setting a new rectangular area to display the web view.

    For example:

    var viewPort:Rectangle = new Rectangle( 15, 15, 300, 600 );

    webview.viewPort = viewPort;

    You can also control the x, y, width and height properties individually.

    For example:

    webView.width = 300;
    webView.height = 600;
    webView.x = 15;
    webView.y = 15;

    We suggest using the viewPort to update the position and size as it results in one view port change rather than several from setting the properties individually.

    Visibility

    You can remove the web view from the view altogether by setting the visible property.

    When false this will remove the web view from the current view, while still keeping the current state and any ongoing operations continuing in the background.

    You can then later present the view again by setting this to true.

    The default is true and presents the web view to the user.

    For example to hide the web view:

    webView.visible = false;
    - + \ No newline at end of file diff --git a/docs/nativewebview/removing-the-webview/index.html b/docs/nativewebview/removing-the-webview/index.html index ee14c7fd6da..658ea66d73b 100644 --- a/docs/nativewebview/removing-the-webview/index.html +++ b/docs/nativewebview/removing-the-webview/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Removing the WebView

    In order to remove the web view from your application you call the dispose function on the WebView. It is important that you remove any event listeners before calling dispose. After calling dispose the WebView will be in an invalid state so calling any other functions will have undefined results.

    if (webView != null)
    {
    webView.removeEventListener( NativeWebViewEvent.LOCATION_CHANGING, webView_locationChangingHandler );
    webView.removeEventListener( NativeWebViewEvent.LOCATION_CHANGE, webView_locationChangeHandler );
    webView.removeEventListener( NativeWebViewEvent.COMPLETE, webView_completeHandler );
    webView.removeEventListener( NativeWebViewEvent.ERROR, webView_errorHandler );
    webView.removeEventListener( NativeWebViewEvent.JAVASCRIPT_RESPONSE, webView_javascriptResponseHandler );
    webView.removeEventListener( NativeWebViewEvent.JAVASCRIPT_MESSAGE, webView_javascriptMessageHandler );
    webView.removeEventListener( TouchEvent.TOUCH_TAP, webView_tapHandler );
    webView.dispose();
    webView = null;
    }
    - + \ No newline at end of file diff --git a/docs/nativewebview/screenshot/index.html b/docs/nativewebview/screenshot/index.html index 94f0bce334f..51f39d7f83e 100644 --- a/docs/nativewebview/screenshot/index.html +++ b/docs/nativewebview/screenshot/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Screenshot

    Capturing a Screenshot

    You can capture the web view to bitmap data by calling the drawViewPortToBitmapData() function and providing a correctly sized BitmapData object.

    var bd:BitmapData = new BitmapData( webView.width, webView.height );

    webView.drawViewPortToBitmapData( bd );

    This process is asynchronous so the bitmap data will be updated after the capture is complete. If you need to know when the process is complete you can either listen for the NativeWebViewEvent.DRAWVIEWPORT_COMPLETE event or pass a callback function.

    Using the event listener:

    var bd:BitmapData = new BitmapData( webView.width, webView.height );
    webView.addEventListener( NativeWebViewEvent.DRAWVIEWPORT_COMPLETE, function(e:NativeWebViewEvent):void
    {
    webView.removeEventListener( NativeWebViewEvent.DRAWVIEWPORT_COMPLETE, arguments.callee );

    // Use bd
    });
    webView.drawViewPortToBitmapData( bd );

    Using the callback function:

    var bd:BitmapData = new BitmapData( webView.width, webView.height );
    webView.drawViewPortToBitmapData( bd, function():void
    {
    // Use bd
    });
    - + \ No newline at end of file diff --git a/docs/nativewebview/webview-information/index.html b/docs/nativewebview/webview-information/index.html index b00373eea25..743eac01c0a 100644 --- a/docs/nativewebview/webview-information/index.html +++ b/docs/nativewebview/webview-information/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    WebView Information

    You can get information about the current state and contents of the web view through a range of methods.

    For example you can retrieve the current loaded url through the location property.

    var currentUrl:String = webView.location;

    Similarly you can retrieve the last loaded status code, user agent, and several other properties:

    trace( "UserAgent:  " + webView.userAgent );
    trace( "StatusCode: " + webView.statusCode );

    Cookies

    You can access the current cookies loaded in the page using the cookies property.

    var cookies:Object = webView.cookies;
    for (var cookieName:String in cookies)
    {
    trace( cookieName +" = " + cookies[cookieName] );
    }

    HTML Source

    You can retrieve the current page source using the htmlSource property. This may be useful if you just want to inspect the contents of the loaded page, however if you need to interact with the content you should look into using the javascript communication interface.

    trace( webView.htmlSource );
    - + \ No newline at end of file diff --git a/docs/networkinfo/add-the-extension/index.html b/docs/networkinfo/add-the-extension/index.html index 4fd463321e3..05073fa5b42 100644 --- a/docs/networkinfo/add-the-extension/index.html +++ b/docs/networkinfo/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Extension IDs

    The following should be added to your extensions node in your application descriptor to identify all the required ANEs in your application:

    <extensions>
    <extensionID>com.distriqt.NetworkInfo</extensionID>
    <extensionID>com.distriqt.Core</extensionID>
    </extensions>

    Android

    Manifest additions

    Depending on the functionality you will be using in your application you may require the following permissions added to your manifest additions in your application descriptor:

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    MultiDex Applications

    If you have a large application and are supporting Android 4.x then you will need to ensure you enable your application to correctly support MultiDex to allow the application to be broken up into smaller dex packages.

    This is enabled by default with releases of AIR v25+, except in the Android 4.x case where you need to change the manifest additions for the application tag to match the following and use the MultiDexApplication.

    Using AndroidX

    This will require the addition of the androidx.multidex extension which contains the androidx.multidex.MultiDexApplication implementation.

    <manifest android:installLocation="auto">
    <!-- PERMISSIONS -->

    <application android:name="androidx.multidex.MultiDexApplication">

    <!-- ACTIVITIES / RECEIVERS / SERVICES -->

    </application>
    </manifest>

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (NetworkInfo.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/networkinfo/changelog/index.html b/docs/networkinfo/changelog/index.html index 0efd909deb0..ba46c436613 100644 --- a/docs/networkinfo/changelog/index.html +++ b/docs/networkinfo/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.19 [v4.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2022.02.08 [v4.0.12]

    Update docs to use apm
    Fix air package to use correct manifest additions

    2021.10.11 [v4.0.11]

    Add air package 
    Remove ios minimum version flag

    2020.12.10 [v4.1.010]

    Android x64 support (resolves #34)
    Deprecated wiki

    2020.03.20 [v4.0.006]

    Android X migration (resolves #32)

    2019.08.15 [v3.0.002]

    Android 64bit support (resolves #28)
    Updated minimum iOS version to 9.0

    2019.03.11 [v2.1.025]

    Updated minimum iOS version to 8.0 (resolves #26)
    Embedded iOS bitcode
    Removed application keys (resolves #25)

    2018.12.14 [v2.0.022]

    Removed application key requirement

    2017.08.24 [v2.0.020]

    Updated documentation

    2017.08.24 [v2.0.020]

    Added telephony information (resolves #18)

    2017.07.10 [v1.8.010]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.31 [v1.8.009]

    Updated SDKs + new documentation

    2016.08.11 [v1.8.008]

    Updated implementation to dispatch network change events correctly (#12)

    2015.02.20

    Changed class structure to support FlashBuilder 4.6 (resolves #2)

    2015.02.03

    Added check for .debug suffix in application id

    2015.01.21

    Corrected key checks on default library (resolves #2)

    2014.12.22

    iOS: Included arm64 support (resolves #1)

    2014.12.08

    GitHub release for new site
    - + \ No newline at end of file diff --git a/docs/networkinfo/index.html b/docs/networkinfo/index.html index 36fc65efc0e..5e483fb9171 100644 --- a/docs/networkinfo/index.html +++ b/docs/networkinfo/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ interfaces of a device. The default Adobe AIR NetworkInfo class is not fully supported on the iOS platform, so this extension provides all functionality developers expect from the NetworkInfo utility class.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    NetworkInfo.networkInfo.addEventListener( 
    NetworkInfoEvent.CHANGE,
    networkChangeHandler
    );

    function networkChangeHandler( event:NetworkInfoEvent ):void
    {
    trace( "isReachable=" + NetworkInfo.networkInfo.isReachable() );
    trace( "isWWAN=" + NetworkInfo.networkInfo.isWWAN() );
    }

    More information here:

    com.distriqt.NetworkInfo

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/networkinfo/network-change-monitoring/index.html b/docs/networkinfo/network-change-monitoring/index.html index d8c0a417682..5810fca4397 100644 --- a/docs/networkinfo/network-change-monitoring/index.html +++ b/docs/networkinfo/network-change-monitoring/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Network Change Monitoring

    To monitor network changes you add a listener for the NetworkInfoEvent.CHANGE event and then handle the change in your event handler.

    NetworkInfo.networkInfo.addEventListener( 
    NetworkInfoEvent.CHANGE,
    networkChangeHandler
    );
    private function networkChangeHandler( event:NetworkInfoEvent ):void
    {
    trace( "isReachable=" + NetworkInfo.networkInfo.isReachable() );
    trace( "isWWAN=" + NetworkInfo.networkInfo.isWWAN() );
    }
    - + \ No newline at end of file diff --git a/docs/networkinfo/telephony/index.html b/docs/networkinfo/telephony/index.html index 7a80f45848a..85ed0d9ee06 100644 --- a/docs/networkinfo/telephony/index.html +++ b/docs/networkinfo/telephony/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Telephony

    Provides access to information about the telephony services on the user's device.

    Network Operator

    You can retrieve the name of the network operator on the user's device.

    This string is provided by the carrier and formatted for presentation to the user. The value does not change if the user is roaming; it always represents the provider with whom the user has an account.

    var networkOperator:String = NetworkInfo.service.telephony.getNetworkOperatorName();

    If you configure a device for a carrier and then remove the SIM card, this property retains the name of the carrier.

    If the device was never configured for a carrier it will return an empty string.

    - + \ No newline at end of file diff --git a/docs/nfc/add-the-extension/index.html b/docs/nfc/add-the-extension/index.html index ffa17bb5fa0..46ad22dc7fb 100644 --- a/docs/nfc/add-the-extension/index.html +++ b/docs/nfc/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ It also includes some centralised code for some common actions that can cause issues if they are implemented in each individual extension.

    You can access this extension here: https://github.com/distriqt/ANE-Core.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    note

    In order to launch your application from an NFC tag on iOS you are required to have a universal link setup to launch your application, and that the data in the tag contains this url.

    To setup universal links you can follow the Apple documentation here.

    If you are using universal links to background scan on iOS you need to add the domain for each universal link to the entitlements section.

    To add these additions you need to add some additional configuration. Firstly add a custom iOS configuration file by running:

    apm generate config ios

    Edit the config/ios/Entitlements.xml file that was generated to resemble the following, adding the com.apple.developer.associated-domains node:

    <plist version="1.0">
    <dict>

    <key>com.apple.developer.associated-domains</key>
    <array>
    <string>applinks:example.com</string>
    </array>

    </dict>
    </plist>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    Supported

    You should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    if (NFC.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/nfc/add-the-plugin/index.html b/docs/nfc/add-the-plugin/index.html index 32670fb424a..63148014332 100644 --- a/docs/nfc/add-the-plugin/index.html +++ b/docs/nfc/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Plugin

    First step is always to add the plugin to your development environment.

    Asset Store

    Open the Asset Store in your browser and add the plugin to your assets.

    Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

    Manual Installation

    In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.NFC.unitypackage.

    You can manually download the extension from our repository:

    Import the Plugin

    This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

    The plugin will be added to your project and you can now use the plugins functionality in your application.

    Proguard

    If you are using a custom proguard configuration you may need to add the following line to ensure the interface class for the plugin is accessible to unity at runtime.

    -keep class com.distriqt.extension.nfc.NFCUnityPlugin {*;}

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (NFC.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/nfc/changelog/index.html b/docs/nfc/changelog/index.html index 0906b15af54..ddc593736a2 100644 --- a/docs/nfc/changelog/index.html +++ b/docs/nfc/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.07.06 [v5.3.0]

    feat(unity,android): update core lib to new common location
    feat(docs): improve docs for ndef record payload

    2023.06.22 [v5.2.0]

    feat(ios): add new singleRead option to foreground dispatch mode to close ui after a tag read occurs - makes sure ui doesn't block
    fix(android): correct usage of pending intent on recent android versions to include mutable flag

    2023.04.26 [v5.1.1]

    fix(unity): fix manifest additions for latest android versions

    2023.01.27 [v5.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.02.08 [v5.0.94]

    Update package and docs for Android 31
    Update docs to use apm

    2021.10.11 [v5.0.92]

    Add air package

    2021.06.20 [v5.0.090]

    Unity plugin release 1.0
    Reader mode
    Added restart scanning function
    Updated build and improved iOS implementation for iOS 13+ compatibility

    2020.03.20 [v4.0.016]

    Android X migration (resolves #17)

    2020.02.26 [v3.0.014]

    Updated documentation

    2020.02.26 [v3.0.014]

    iOS background scanning and application launching from tags

    2019.08.15 [v2.0.002]

    Android 64bit support (resolves #13)

    2019.04.17 [v1.1.054]

    Embedded iOS bitcode
    Removed application keys
    Added iOS dialog message (resolves #6)

    2018.03.22 [v1.0.050]

    Release version

    2017.11.29 [v1.0.048]

    iOS implementation

    2017.11.27 [v1.0.038]

    Updated documentation

    2017.11.21 [v1.0.038]

    Updated documentation

    2017.11.21 [v1.0.038]

    First release
    - + \ No newline at end of file diff --git a/docs/nfc/dispatch-mode/index.html b/docs/nfc/dispatch-mode/index.html index 59fcbeeec0e..cb405e0dd7f 100644 --- a/docs/nfc/dispatch-mode/index.html +++ b/docs/nfc/dispatch-mode/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ iPhone XS and later support background tag reading.

    After the device scans an NFC tag while in background tag reading mode, the system inspects the tag’s NDEF message for a URI record by looking for an payload object with the following property values:

    If the NDEF message contains more than one URI record, the system uses the first one. The URI record must contain either a universal link or a supported URL scheme.

    You cannot use a custom URL to launch your application, this only works with a predefined set of url schemes mainly for web urls, email, sms etc.

    For tags that contain universal links, the system presents a notification and then launches (or brings to the foreground) the app associated with the universal link after the user taps the notification. (This will happen if the application is in the foreground as well, ie. notification will appear and you will receive an event if the user taps the notification)

    The system sends the NDEF message to the app and the extension receives it. When you call checkStartupData() the NFCEvent will be dispatched, following the same process as Android. If there are no installed apps associated with the universal link, the system opens the link in Safari.

    Associated Domains

    In order for this to work you must setup a universal link for your application and included the domain in the com.apple.developer.associated-domains entitlements section of your iphone additions.

    With AIR this is simply a matter of adding the fields to the entitlements section in your application descriptor, (see Add the Extension for more details).

    Foreground Dispatch

    To initiate reading tags on iOS you call the registerForegroundDispatch() method. There are no filtering methods on iOS so any NDEF formatted tags will be detected and events dispatched to your application, and any options provided (as in the Android case) will be ignored.

    NFC.service.registerForegroundDispatch();

    While scanning on iOS the following dialog will be presented to your user:

    You can customise the message displayed in this dialog by setting the message in the options passed to registerForegroundDispatch():

    var options:ScanOptions = new ScanOptions();
    options.message = "Hold your device near the item to learn more about it.";

    NFC.service.registerForegroundDispatch( options );

    Launch Events

    If your application is launched from a tag you need to make sure you follow a few steps to ensure you correctly receive the event.

    The extension will store the information about the tag until you call checkStartupData() which will subsequently trigger the event dispatch. This allows you to ensure you are ready to handle the event before it gets dispatched.

    So on first run of your application, setup your handlers for the events and then call checkStartupData(). If the application was launched from a background tag scan then you will immediately receive the appropriate event.

    NFC.service.addEventListener( NFCEvent.ACTION_NDEF_DISCOVERED, discoveredHandler );

    NFC.service.checkStartupData();
    danger

    If you do not call checkStartupData() then the launch tag event will not be dispatched. However any background or foreground events from then on will work as normal. This solely covers the case where your application was not running at the time the tag was scanned and your application was launched as a result of the scan.

    - + \ No newline at end of file diff --git a/docs/nfc/index.html b/docs/nfc/index.html index 4489fa9ece7..4988fce109a 100644 --- a/docs/nfc/index.html +++ b/docs/nfc/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    NFC

    The NFC extension gives you the ability to use the Near Field Communication (NFC) hardware to scan for NFC Tags and read the record data contained in the tags.

    On Android and selected iOS 12+ devices, it can be used to automatically launch your application when a device is in range of a specific formatted tag.

    Additionally it can be used to actively scan for tags in the foreground reading NDEF data when a device is brought close to a tag.

    The simple API allows you to quickly integrate NFC scanning in your application in just a few lines of code.

    Features

    • Scan for NFC tags on both iOS and Android;
    • Launch your application automatically on Android and iOS 12+;
    • Read NDEF record data;
    • Single API interface - your code works across supported platforms with no modifications;
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    AIR
    var options:ScanOptions = new ScanOptions();
    options.mimeTypes.push( "*/*" );
    options.urls.push( "https://airnativeextensions.com" );

    NFC.service.addEventListener( NFCEvent.ACTION_NDEF_DISCOVERED, actionDiscoveredHandler );
    NFC.service.registerForegroundDispatch( options );

    function actionDiscoveredHandler( event:NFCEvent ):void
    {
    for each (var message:NdefMessage in event.tag.messages)
    {
    for each (var record:NdefRecord in message.records)
    {
    trace( "\t"+record.toString() + "::"+record.payload.toString() );
    }
    }
    }

    More information here:

    com.distriqt.NFC

    License

    You can purchase a license for using this extension:

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/nfc/reader-mode/index.html b/docs/nfc/reader-mode/index.html index 4ed016ae528..5cf64456fda 100644 --- a/docs/nfc/reader-mode/index.html +++ b/docs/nfc/reader-mode/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Reader Mode

    Reader mode can be used to active scan for tags and read them multiple times. This is useful in the cases where the data changes on the tag so you may need to re-read it at a later point.

    info

    It is important to note that using reader mode may interfere with the other NFC operations of the device, disabling any peer-to-peer (Android Beam) and card-emulation modes of the NFC adapter on this device.

    Start scanning

    To initiate reader mode call enableReaderMode():

    NFC.service.enableReaderMode();

    While active any detected tags will dispatch a NFCEvent.ACTION_NDEF_DISCOVERED event:

    NFC.service.addEventListener( NFCEvent.ACTION_NDEF_DISCOVERED, discoveredHandler );

    function discoveredHandler( event:NFCEvent ):void
    {
    // ndef tag detected
    }

    Stop scanning

    You should make sure to disable reader mode once you have completed scanning by calling disableReaderMode():

    NFC.service.disableReaderMode();

    Restart scanning

    If you have scanned a tag and wish to re-read it, you will need to call restart() to invalidate any scanned tags and rescan them:

    NFC.service.restart();

    If a tag scanned previously is still within range then another NFCEvent.ACTION_NDEF_DISCOVERED event will be dispatched with the latest payload data.

    - + \ No newline at end of file diff --git a/docs/nfc/scanning/index.html b/docs/nfc/scanning/index.html index a695f5300d9..fc1d0fad06a 100644 --- a/docs/nfc/scanning/index.html +++ b/docs/nfc/scanning/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Scanning

    Tags

    NFC tags come in a wide array of technologies and can also have data written to them in many different ways. Android and iOS has the most support for the NDEF standard, which is defined by the NFC Forum.

    NDEF data is encapsulated inside a message (NdefMessage) that contains one or more records (NdefRecord). Each NDEF record must be well-formed according to the specification of the type of record that you want to create.

    Events

    Your application will get notified about NFC tag detection events via the NFCEvent. This is independent of the mode. The most relevant event is the NFCEvent.ACTION_NDEF_DISCOVERED which is dispatched whenever an applicable NDEF NFC tag is detected.

    The NFCEvent will contain a Tag object in the tag variable. This contains all the information available about the detected tag, including NdefMessages and NdefRecords contained in the tag.

    NFC.service.addEventListener( NFCEvent.ACTION_NDEF_DISCOVERED, discoveredHandler );

    function discoveredHandler( event:NFCEvent ):void
    {
    trace( "discoveredHandler" );
    for each (var message:NdefMessage in event.tag.messages)
    {
    for each (var record:NdefRecord in message.records)
    {
    trace( "\t"+record.toString() + "::"+record.payload.toString() +" url:"+record.url );
    }
    }
    }

    NdefRecord Payload

    The payload of the records contains data in a specific format.

    The payload in an NdefRecord is encoded as a ByteArray.

    If you are expecting ascii string data you can just read the data using toString(), eg:

    var record:NdefRecord = ...;
    var payloadAsString:String = record.payload.toString();

    Modes

    There are two modes of scanning for tags, which we reference as:

    Both are very similar, and will communicate via the same events as above. The main differences being that:

    1. reader mode active reads tags and can read a tag multiple times if required, however;
    2. reader mode mode interferes with other NFC functionality disabling any peer-to-peer (Android Beam) and card-emulation modes of the NFC adapter on this device;
    3. reader mode is only available while your application is active, i.e only dispatch mode supports background scanning and launching your application from a tag.

    As a general rule, you should use dispatch mode, unless you really need to read a tag multiple times.

    There is also no reason that you can't combine the two, using dispatch mode to register your application for launches from tags and using reader mode to actively scan while your application is in use.

    - + \ No newline at end of file diff --git a/docs/nfc/unity/index.html b/docs/nfc/unity/index.html index cd5284c5b94..3ebdbe766a6 100644 --- a/docs/nfc/unity/index.html +++ b/docs/nfc/unity/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ iPhone XS and later support background tag reading.

    After the device scans an NFC tag while in background tag reading mode, the system inspects the tag’s NDEF message for a URI record by looking for an payload object with the following property values:

    If the NDEF message contains more than one URI record, the system uses the first one. The URI record must contain either a universal link or a supported URL scheme.

    You cannot use a custom URL to launch your application, this only works with a predefined set of url schemes mainly for web urls, email, sms etc.

    For tags that contain universal links, the system presents a notification and then launches (or brings to the foreground) the app associated with the universal link after the user taps the notification. (This will happen if the application is in the foreground as well, ie. notification will appear and you will receive an event if the user taps the notification)

    The system sends the NDEF message to the app and the extension receives it. When you call checkStartupData() the NFCEvent will be dispatched, following the same process as Android. If there are no installed apps associated with the universal link, the system opens the link in Safari.

    Associated Domains

    In order for this to work you must setup a universal link for your application and included the domain in the com.apple.developer.associated-domains entitlements section of your iphone additions.

    With Unity you will need to add your domain to the NFCConfig.cs class in the Assets/distriqt/NFCUnity/NFC/Editor folder. Set your domains into the associatedAppDomains array, for example:

    public static string[] associatedAppDomains = new string[] 
    {
    // Add your associated App Domains here
    "applinks:example.com"
    };

    These domains will be applied to the entitlements for your application by our post build scripts.

    Foreground Dispatch

    To initiate reading tags on iOS you call the RegisterForegroundDispatch() method. There are no filtering methods on iOS so any NDEF formatted tags will be detected and events dispatched to your application, and any options provided (as in the Android case) will be ignored.

    NFC.Instance.RegisterForegroundDispatch();

    While scanning on iOS the following dialog will be presented to your user:

    You can customise the message displayed in this dialog by setting the message in the options passed to RegisterForegroundDispatch():

    ScanOptions options = new ScanOptions();
    options.message = "Hold your device near the item to learn more about it.";

    NFC.Instance.RegisterForegroundDispatch(options);

    Launch Events

    If your application is launched from a tag you need to make sure you follow a few steps to ensure you correctly receive the event.

    The extension will store the information about the tag until you call CheckStartupData() which will subsequently trigger the event dispatch. This allows you to ensure you are ready to handle the event before it gets dispatched.

    So on first run of your application, setup your handlers for the events and then call CheckStartupData(). If the application was launched from a background tag scan then you will immediately receive the appropriate event.

    NFC.Instance.OnNdefDiscovered += Instance_OnNdefDiscovered;

    NFC.Instance.CheckStartupData();

    If you do not call CheckStartupData() then the launch tag event will not be dispatched. However any background or foreground events from then on will work as normal. This solely covers the case where your application was not running at the time the tag was scanned and your application was launched as a result of the scan.

    Reader Mode

    Reader mode can be used to active scan for tags and read them multiple times. This is useful in the cases where the data changes on the tag so you may need to re-read it at a later point.

    info

    It is important to note that using reader mode may interfere with the other NFC operations of the device, disabling any peer-to-peer (Android Beam) and card-emulation modes of the NFC adapter on this device.

    Start scanning

    To initiate reader mode call EnableReaderMode():

    NFC.Instance.EnableReaderMode();

    While active any detected tags will dispatch a OnNdefDiscovered event:

    NFC.Instance.OnNdefDiscovered += Instance_OnNdefDiscovered;

    void Instance_OnNdefDiscovered(NFCEvent e)
    {
    // ndef tag detected
    }

    Stop scanning

    You should make sure to disable reader mode once you have completed scanning by calling DisableReaderMode():

    NFC.Instance.DisableReaderMode();

    Restart scanning

    If you have scanned a tag and wish to re-read it, you will need to call Restart() to invalidate any scanned tags and rescan them:

    NFC.Instance.Restart();

    If a tag scanned previously is still within range then another OnNdefDiscovered event will be dispatched with the latest payload data.

    Support

    If you need further support integrating or using this extension please feel free to contact us.

    We have been supporting developers for over 10 years and always happy to help.





    - + \ No newline at end of file diff --git a/docs/notifications/add-the-extension---windows/index.html b/docs/notifications/add-the-extension---windows/index.html index 360a4a72e96..46e31866167 100644 --- a/docs/notifications/add-the-extension---windows/index.html +++ b/docs/notifications/add-the-extension---windows/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Extension - Windows

    There are several additional things to consider on Windows:

    Dependencies

    .Net Framework

    This extension requires v4.6 or higher of the .Net framework. This should come preinstalled on any Windows 10 or higher machine so if you are targetting those you should not have to do anything. If however you are targetting older versions of Windows you must ensure .Net v4.6 or higher is installed either manually or as part of an installer.

    C++ Redistributable

    The native code has a dependency on the Visual C++ 2017 Redistributable package. This package contains code that is required to run code developed using C++ in Visual Studio and is very common amongst Windows applications.

    There are two ways to ensure this is available to your application:

    • Create an installer that includes the redistributable installer;
    • Package the required DLL files from the redistributable with your application;

    The first is the suggested method. Installing the redistributable via an installer allows it to be put into the windows update process, allowing bug fixes and security updates to be handled automatically.

    The second method is only advised if you need a complete standalone application, where you don't (or cannot) use an installation process. This requires you to package DLLs from the redistributable with your application.

    Creating an Installer

    There are many methods to create application installers and many tutorials available. We suggest you find a method suitable to your environment and application and utilise the tutorials online.

    Some methods include:

    Tutorials:

    You need to include the x86 c++ 2017 redistributable in the installer, there are many examples and documentation online to achieve this.

    Packaging DLLs

    Packaging the DLLs into your application involves copying the DLLs specified below into your application root and including in your application package.

    The best option is to install Visual Studio 2017 and locate the Program Files[ (x86)]\Microsoft Visual Studio\2017\edition\VC\Redist\MSVC\lib-version folder, eg: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Redist\MSVC\14.16.27012\x86\Microsoft.VC141.CRT

    Alternatively, download and install the x86 redistributable from the Microsoft website. This should install the DLLs into C:\Windows\System32 folder.

    Open the folder and copy the following DLLs to your application:

    • msvcp140.dll
    • vcruntime140.dll

    If you are having issues locating these files, feel free to contact us for help.

    You should ensure you are allowed to package these files as per the Microsoft Software License terms but generally these are safe to redistribute subject to the license terms. More information here: Redistributing Visual C++ Files

    You should get legal advice if you are unsure.

    AppxManifest

    The windows notifications UWP support requires a couple of additions to your AppxManifest in order to receive notification events when the user interacts with the notification.

    You will need to use the "Sign Separately" method to package your appx as described here.

    If you don't make these changes then your application will not receive all the notification events.

    During the "Update Content" step you will need to edit the AppxManifest.xml file contained in the pacakged files directory and add the following:

    • Declaration for xmlns:com
    • Declaration for xmlns:desktop
    • In the IgnorableNamespaces attribute, com and desktop
    • com:Extension for the COM activator
    • desktop:Extension for windows.toastNotificationActivation to declare your toast activator
    <Package
    ...
    xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
    xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
    IgnorableNamespaces="... com desktop">
    ...
    <Applications>
    <Application>
    ...
    <Extensions>

    <!--Register COM CLSID LocalServer32 registry key-->
    <com:Extension Category="windows.comServer">
    <com:ComServer>
    <com:ExeServer Executable="YOURAPPLICATION.exe" Arguments="-ToastActivated" DisplayName="Toast activator">
    <com:Class Id="4db090a5-b5c9-4cbf-97a6-dd6a431f8749" DisplayName="Toast activator"/>
    </com:ExeServer>
    </com:ComServer>
    </com:Extension>

    <!--Specify which CLSID to activate when toast clicked-->
    <desktop:Extension Category="windows.toastNotificationActivation">
    <desktop:ToastNotificationActivation ToastActivatorCLSID="4db090a5-b5c9-4cbf-97a6-dd6a431f8749" />
    </desktop:Extension>

    </Extensions>
    </Application>
    </Applications>
    </Package>

    You also need to replace YOURAPPLICATION with the name of the Executable attribute in the Application node.

    For example, this is the entire AppxManifest.xml for the distriqt test application:

    <?xml version="1.0" encoding="utf-8"?>
    <Package
    xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
    xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
    xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
    xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
    xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
    xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    xmlns:rescap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/3"
    xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
    xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"
    xmlns:desktop3="http://schemas.microsoft.com/appx/manifest/desktop/windows10/3"
    xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
    xmlns:wincap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/windowscapabilities/3"
    IgnorableNamespaces="uap4 wincap3 rescap3 desktop desktop2 desktop3 com">
    <Identity Name="distriqt.airnativeextensions" ProcessorArchitecture="x86" Publisher="CN=38CAD93E-B1A7-480F-B65D-3545798BA205" Version="1.0.0.0" />
    <Properties>
    <DisplayName>distriqt.airnativeextensions</DisplayName>
    <PublisherDisplayName>distriqt</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
    </Properties>
    <Resources>
    <Resource Language="en-us" />
    <Resource uap:Scale="100" />
    <Resource uap:Scale="125" />
    <Resource uap:Scale="150" />
    <Resource uap:Scale="200" />
    <Resource uap:Scale="400" />
    </Resources>
    <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.16299.15" />
    </Dependencies>
    <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <Capability Name="internetClient" />
    </Capabilities>
    <Applications>
    <Application Id="distriqt.airnativeextensions" Executable="testnotifications.exe" EntryPoint="Windows.FullTrustApplication">
    <uap:VisualElements DisplayName="distriqt.airnativeextensions" Description="distriqt.airnativeextensions" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
    <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\Square310x310Logo.png" Square71x71Logo="Assets\Square71x71Logo.png">
    <uap:ShowNameOnTiles>
    <uap:ShowOn Tile="square150x150Logo" />
    <uap:ShowOn Tile="wide310x150Logo" />
    <uap:ShowOn Tile="square310x310Logo" />
    </uap:ShowNameOnTiles>
    </uap:DefaultTile>
    </uap:VisualElements>

    <Extensions>
    <!--Register COM CLSID LocalServer32 registry key-->
    <com:Extension Category="windows.comServer">
    <com:ComServer>
    <com:ExeServer Executable="testnotifications.exe" Arguments="-ToastActivated" DisplayName="Toast activator">
    <com:Class Id="aa28441a-fba8-45dc-887e-149495769502" DisplayName="Toast activator"/>
    </com:ExeServer>
    </com:ComServer>
    </com:Extension>

    <!--Specify which CLSID to activate when toast clicked-->
    <desktop:Extension Category="windows.toastNotificationActivation">
    <desktop:ToastNotificationActivation ToastActivatorCLSID="aa28441a-fba8-45dc-887e-149495769502" />
    </desktop:Extension>

    </Extensions>
    </Application>
    </Applications>
    </Package>
    - + \ No newline at end of file diff --git a/docs/notifications/add-the-extension/index.html b/docs/notifications/add-the-extension/index.html index 8a2da772a11..d7c8a7b3107 100644 --- a/docs/notifications/add-the-extension/index.html +++ b/docs/notifications/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    AIR SDK

    This ANE currently requires at least AIR 33+. This is required in order to support versions of Android > 9.0 (API 28). We always recommend using the most recent build with AIR especially for mobile development where the OS changes rapidly.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Notifications

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Notifications.ane # Notifications extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Windows

    See the detailed Windows section

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    Core.init();
    if (Notifications.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/notifications/cancel-notifications/index.html b/docs/notifications/cancel-notifications/index.html index 6dbb62f5883..6e5850999f2 100644 --- a/docs/notifications/cancel-notifications/index.html +++ b/docs/notifications/cancel-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ are yet to be delivered. Any notifications that have already been displayed in the notification area are not removed.

    With iOS < 10 they can only be removed from the notification area either by the user or by calling cancelAll.

    - + \ No newline at end of file diff --git a/docs/notifications/changelog/index.html b/docs/notifications/changelog/index.html index d8f50215c97..b0a2fbe8926 100644 --- a/docs/notifications/changelog/index.html +++ b/docs/notifications/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.09.22 [v6.6.1]

    fix(android): correct handling of authorisation denied state, incorrectly returned not_determined resulting in ANRs

    2023.08.18 [v6.6.0]

    feat(api): update as3 api to include addChannel method similar to push notifications (resolves #202)

    2023.01.27 [v6.5.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #199)
    feat(android): Move to new permissions request process

    2022.12.15 [v6.4.0]

    feat(android): add android 13 notification permission request

    2022.02.18 [v6.3.1]

    Android: Fix for issue with Android 12 trampoline incorrectly resolved (resolves #193)

    2022.02.10 [v6.3.0]

    Update for Android 31 (resolve notification trampoline issue)
    Update docs for Android 31
    Update docs to use apm

    2021.10.12 [v6.2.0]

    Add air package
    Add windows 64 bit support

    2021.03.16 [v6.1.124]

    Removed ios_version_min

    2020.08.17 [v6.1.121]

    Corrected windows cancel operations for scheduled notifications

    2020.04.29 [v6.0.116]

    Fixed several issues around displaying and removing group notifications (resolves #186)

    2020.03.25 [v6.0.103]

    Android X migration (resolves #184)

    2019.08.15 [v5.0.009]

    Android 64bit update (resolves #175)
    Updated minimum iOS version to 9.0
    Corrected issue with large icon and delayed notifications (resolves #177)

    2019.03.12 [v4.8.125]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode

    2018.10.29 [v4.7.122]

    Android: Created specific file provider to avoid conflicts
    Android: Added missing Channel sound property for latest Android OS

    2018.10.19 [v4.7.120]

    iOS: Added limited ability to specify the time for repeat intervals  
    Android: Corrected action cancel not closing notification panel

    2018.08.02 [v4.7.114]

    Android: Corrected setBadgeNumber for Android 8 (resolves #162)

    2018.07.26 [v4.7.111]

    Corrected clearing of badge with notifications without count (resolves #160)

    2018.07.04 [v4.7.108]

    Updated Android min sdk documentation (resolves #159)

    2018.02.14 [v4.7.106]

    Android 8.0 support - Added channels

    2017.12.18 [v4.6.099]

    Added additional checks to notification builders
    Updated notification icon documentation
    Updated badge number documentation

    2017.11.27 [v4.5.092]

    Better Emoji integration (#148)
    Additional context checks (resolves #152)
    Removed legacy alert/title requirement (resolves #153)

    2017.09.29 [v4.4.054]

    Removed Android 8 support while Adobe fix AIR SDK issue

    2017.09.19 [v4.4.052]

    Android 8.0: Notification Channels + Badges (resolves #145)
    Android: Added background image

    2017.07.10 [v4.3.028]

    Updated Android file paths

    2017.07.10 [v4.3.026]

    Updated Android file paths

    2017.07.10 [v4.3.025]

    Android: Added setBadgeNumber for supported Android devices (resolves #110)
    iOS 10: Centralisation of new notifications delegate (#132)

    2017.07.05 [v4.2.019]

    Android: Corrected immediate event with delayed notification (resolves #138)

    2017.07.05 [v4.2.017]

    iOS: Corrected authorisation status on iOS 10 (resolves #136)

    2017.04.13 [v4.2.011]

    Fixed Android conflict with Push Notifications service definitions

    2017.04.06 [v4.2.007]

    Android: Corrected sound access permissions (resolves #128)

    2017.03.26 [v4.2.004]

    Android: Added setShouldCancelOnAction to make actions close a notification (resolves #112)
    Android: Added enableNotificationsWhenActive false (resolves #123)
    Added timestamp to notification events (resolves #118)

    2016.12.30 [v4.1.004]

    Updated documentation

    2016.12.30 [v4.1.004]

    New documentation

    2016.12.21 [v4.1.004]

    Updated image

    2016.12.21 [v4.1.004]

    Changed usage of alert/title/body to be more consistent across platforms and versions
    Android: Corrected action dismissing notification (resolves #109)

    2016.12.20 [v4.0.031]

    Fix for crash on iOS 7

    2016.11.28 [v4.0.030]

    Added fallback if no body is supplied (resolves #107)

    2016.11.23 [v4.0.029]

    Updated docs

    2016.11.23 [v4.0.029]

    iOS 10 updates including: (resolves #97)
    - expanded image style
    - cancel a single notification from displayed and scheduled (resolves #98)
    - display notifications when app is in foreground
    Android: Corrected cancel single notification from a group (resolves #103)
    Android: Heads-up notifications (resolves #104)
    Added openDeviceSettings

    2016.11.15 [v3.7.010]

    Updated examples

    2016.11.15 [v3.7.010]

    Updated group example

    2016.11.15 [v3.7.010]

    Added group summary to collapsed notification state (#100)

    2016.09.18 [v3.7.006]

    Updated simple example to new API (#89)

    2016.09.07 [v3.7.006]

    iOS: Added some checks for notifications with unexpected values (resolves #85, #74)

    2016.09.05 [v3.7.004]

    Updated documentation and version numbering

    2016.08.12 [v3.7.003]

    Android: Corrected usage of http large icons (resolves #136)

    2016.07.02

    Android: Corrected double notification issue on startup when register before activation (resolves #58, #71)
    Android: Added 'willLaunchApplication' option to actions to allow app to start (resolves #63)

    2016.06.19

    Android: Increased speed of notify function with large number of delayed notifications (#69)

    2016.05.19

    Added REPEAT_WEEK and REPEAT_FORTNIGHT intervals (resolves #64)
    Android: Corrected operation of on-going notifications (resolves #62)

    2016.05.12

    Android: Implemented OnGoing Notifications (resolves #60)

    2016.04.27

    Android: Set delayed notifications to use exact timings on v19+ where possible (resolves #59)

    2016.04.12

    Removed debug code from example app

    2016.04.12

    Android: Removed debug code which was slowing down custom sounds (#50)

    2016.04.12

    iOS: Corrected authorisation status value (resolves #49)

    2016.04.08

    iOS: Corrected setAlertTitle crash on iOS < 8.2 (resolves #48)

    2016.04.06

    Corrected references to PushNotifications (#47)

    2016.04.04

    Updated documentation

    2016.04.04

    Version 3.0 Release
    Notification Actions
    Builders for all notification types
    Android: Group / Stacking notifications
    Android: Expanded view notifications (resolves #45)
    Android: Custom icons (resolves #35)
    Android: Correctly restore notifications on restart (resolves #44)
    Android: Repeat interval implementation (resolves #41)

    2015.10.20

    Android: Fixed issue with notification being dispatched twice (resolves #17)

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.06.02

    Repackaged to test distriqt/ANE-Calendar#10

    2015.03.05

    Separated common app delegates into Core ANE to resolve conflicting ANEs issues

    2015.02.10

    iOS: Added some additional checks to input variables to isolate crash (#5)

    2015.02.03

    Added check for .debug suffix in application id

    2014.12.22

    iOS: Included arm64 support (resolves #1) 
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.08

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    New application based key check, removing server checks

    2014.10.18

    iOS Update for iOS 8
    - iOS: Fixed iOS 8 registering for notification permission (resolves #219)
    - iOS: Added function to check if user has allowed notifications
    - iOS: Fixed vibrate on notification selection (resolves #209, closes #177)
    - Android: cancelAll was previously implemented (closes #71)
    - + \ No newline at end of file diff --git a/docs/notifications/delay-and-repeat-interval/index.html b/docs/notifications/delay-and-repeat-interval/index.html index 63a565751f4..934a027cf0c 100644 --- a/docs/notifications/delay-and-repeat-interval/index.html +++ b/docs/notifications/delay-and-repeat-interval/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ Available intervals are in the NotificationRepeatInterval class, and include, minute, hour, day, week etc. Check the individual intervals for their availability on each of the platforms.

    Notifications.service.notify(
    new NotificationBuilder()
    .setRepeatInterval( NotificationRepeatInterval.REPEAT_HOUR ) // Repeat the notification every hour
    .setAlert( "Repeat Notification" )
    .setTitle( "Repeat Notification" )
    .setBody( "The body of the notification" )
    .build()
    );

    These notifications continue until you cancel them.

    Combining Delay and Repeat Intervals

    You can use both the delay and repeat interval to create notifications that start repeating at some time in the future.

    For example, say we wanted to schedule a reminder every day at 7am, then we would use a REPEAT_DAY interval and set the fireDate to be at 7:00am.

    var now:Date = new Date();
    var fireDate:Date = new Date( now.year, now.month, now.date, 7, 0, 0 );
    fireDate.date += 1; // tomorrow

    Notifications.service.notify(
    new NotificationBuilder()
    .setFireDate( fireDate )
    .setRepeatInterval( NotificationRepeatInterval.REPEAT_DAY )
    .setAlert( "Repeat Notification" )
    .setTitle( "Repeat Notification" )
    .setBody( "The body of the notification" )
    .build()
    );

    iOS

    With iOS 10 and higher, Apple have severely limited the ability to schedule and repeat notifications.

    Instead of being able to specify the first notification date and then a repeat interval we can only use the fire date to specify the details of the repeat interval.

    So we cannot specify an initial delay to the first notification occurrence. If the above example was called before 7am then the first notification would occur today and not tomorrow on iOS 10+ device. The day specified in the fire date for the daily repeat interval will be ignored.

    The issue becomes more prevalent if you were attempting to set reminders for important events eg, remind your user to take their medication at 7am by setting a reminder every minute after 7am:

    var now:Date = new Date();
    var fireDate:Date = new Date( now.year, now.month, now.date, 7, 0, 0 );
    fireDate.date += 1; // tomorrow

    Notifications.service.notify(
    new NotificationBuilder()
    .setFireDate( fireDate )
    .setRepeatInterval( NotificationRepeatInterval.REPEAT_MINUTE )
    .setAlert( "Repeat Notification" )
    .setTitle( "Repeat Notification" )
    .setBody( "The body of the notification" )
    .build()
    );

    Instead of waiting until 7am tomorrow this alarm would immediately start occurring every minute.

    Please be aware of this limitation if you are combining delays and repeat intervals.

    caution

    If you are wanting to have consistent repeating notifications across platforms we suggest considering the repeat interval as the priority and the fire date and specifying the time components of the interval smaller than the repeat interval.

    For example, create:

    • a daily notification at a particular time (hour / minute eg 07:00)
    • an hourly notification at a particular minute (eg quarter past the hour, :15)

    If you have any concerns or need some help on creating a specific repeating notification feel free to ask our support team.

    - + \ No newline at end of file diff --git a/docs/notifications/displaying-notifications/index.html b/docs/notifications/displaying-notifications/index.html index dba3855271f..36810c8c970 100644 --- a/docs/notifications/displaying-notifications/index.html +++ b/docs/notifications/displaying-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ text fields and the icon:

    Notifications.service.notify(
    new NotificationBuilder()
    .setAlert( "The alert text" )
    .setTitle( "The title text" )
    .setBody( "The body text" )
    .setIcon( "ic_stat_distriqt" )
    .build()
    );
    OSPositionExample
    Android 4Notification Center
    Android 4Ticker Text
    Android 7Lock screen
    Android 7Notification Center
    Android 7Ticker (no text shown just icon)
    iOS 7Notification Center
    iOS 7Top overlay
    iOS 9Notification Center
    iOS 9Top overlay
    iOS 10Full view
    iOS 10Notification Center
    iOS 10Top overlay

    Payload

    You should set a payload on your notification that will get returned in any of the notification events. This will help you identify the notification and correctly handle the notification. The payload can be any string, but we suggest using a JSON encoded object as shown in the example below.

    var id:int = 1;
    var payload:Object = { id: id, type: "payload" }; // An example payload

    Notifications.service.notify(
    new NotificationBuilder()
    .setId( id )
    .setAlert( "A simple alert" )
    .setTitle( "A simple notification" )
    .setBody( "The body of the notification" )
    .setPayload( JSON.stringify(payload) )
    .build()
    );

    The payload is return in the notification events, more on this in the Receiving Notifications section.

    - + \ No newline at end of file diff --git a/docs/notifications/emojis/index.html b/docs/notifications/emojis/index.html index 5824c14132c..223adfca392 100644 --- a/docs/notifications/emojis/index.html +++ b/docs/notifications/emojis/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Emojis

    You can use emojis that are part of Unicode in your notifications wherever the extended unicode character sets are supported, which includes modern Android and iOS releases.

    To include them in your text there are several methods.

    HTML Entities

    The most reliable is using HTML entities:

    Notifications.service.notify(
    new NotificationBuilder()
    .setAlert( "&#x1F601; The alert text" )
    .build()
    );

    In the above case the "Smiley face" emoji has been specified by it's hex code as a HTML entity &#x1F601;.

    As there are no issues with the encoding of the file or string at any point this method is the most reliable method to display emojis. Other method may fail under different circumstances, such as loading data from a file encoded differently.

    Direct encoding / escaping

    You can directly paste a unicode character (or escape sequence) into your code and you should expect it to work

    Notifications.service.notify(
    new NotificationBuilder()
    .setAlert( "\u2702 it out!" )
    .build()
    );

    However there are issues with this method whenever any of the files (or filesystems) used are saved in a format (encoding) not supporting the unicode characters. This means this method requires careful management of the encodings in use.

    - + \ No newline at end of file diff --git a/docs/notifications/index.html b/docs/notifications/index.html index 6dc75e3d4c1..22e35020de0 100644 --- a/docs/notifications/index.html +++ b/docs/notifications/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Notifications

    The Notifications extension enables the use of Local Notifications on your device giving you the ability to easily engage your users on their device without having to setup remote notification servers.

    Create useful notifications for your users increasing user engagement and bringing them back to your application.

    You can give users the ability to quickly interact with your application through actions, allowing them to do common tasks quickly.

    The simple API will have you up and running with notifications in just a few lines of code. Identical code base can be used across all platforms without any platfrom specific code, allowing you to develop once and deploy everywhere!

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Getting started with local notifications is quick and easy!

    Features

    • Custom icons;
    • Stacking (group) notifications;

    • Expanded view notifications: image, text and inbox;

    • Actions;

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    Notifications.service.notify(
    new NotificationBuilder()
    .setAlert( "A simple alert" )
    .setTitle( "A simple notification" )
    .setBody( "The body of the notification" )
    .build()
    );

    More information here:

    com.distriqt.Notifications

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/notifications/migrating-to-6.3/index.html b/docs/notifications/migrating-to-6.3/index.html index 3df49b64f22..47e449cb9e8 100644 --- a/docs/notifications/migrating-to-6.3/index.html +++ b/docs/notifications/migrating-to-6.3/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v6.3

    Android 31

    When users interact with notifications, our extension responds to notification taps by launching an app component that eventually starts the AIR activity that the user finally sees and interacts with. This app component is known as a notification trampoline.

    With Android 12 (API 31) the system prevents the activity from starting, and the following message appears in Logcat:

    Indirect notification activity start (trampoline) from PACKAGE_NAME, \
    this should be avoided for performance reasons.

    More information here

    To resolve this we have needed to completely redesign the notification system on Android 12. While this is a major refactor internally to the extension there are only a few things you need to manage. The API has not changed and you won't see any change to the events or order of the events.

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/notifications/migrating-to-6.4/index.html b/docs/notifications/migrating-to-6.4/index.html index 4329685aa97..bd0cda34077 100644 --- a/docs/notifications/migrating-to-6.4/index.html +++ b/docs/notifications/migrating-to-6.4/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v6.4

    Android 13 (API 33) Permissions

    With Android 13 comes a new runtime user permission required to present a user with notifications.

    If you do not update your users will be presented with the permission notification on launch of your application.

    Authorisation process follows exactly the same code you have used for iOS and from a developer perspective no changes are needed, except that you need to handle a SHOULD_EXPLAIN case for Android, similar to other permissions.

    See the documentation on requesting authorisation for more information.

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/notifications/migrating-to-6.5/index.html b/docs/notifications/migrating-to-6.5/index.html index 6d6f0d0613f..f8952d6f661 100644 --- a/docs/notifications/migrating-to-6.5/index.html +++ b/docs/notifications/migrating-to-6.5/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v6.5

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/notifications/migrating-to-androidx/index.html b/docs/notifications/migrating-to-androidx/index.html index e9d61ba6142..73ef985b57c 100644 --- a/docs/notifications/migrating-to-androidx/index.html +++ b/docs/notifications/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/notifications/notification-icons/index.html b/docs/notifications/notification-icons/index.html index 861cb344c55..68b496344e4 100644 --- a/docs/notifications/notification-icons/index.html +++ b/docs/notifications/notification-icons/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Notification Icons

    Notification icons refer to the image displayed in the notification center alongside the title, message and any other content associated with the notification.

    At a minimum all notifications consist of an icon and body text.

    iOS

    On iOS the icon is always your application icon. You do not need to do anything additional, just ensure your application has all the required application icon sizes.

    Android

    On Android the icon is provided through Android resources and you cannot use your AIR application icon (except on much older versions of Android). This icon must be white and transparent to fit with the Android design guidelines, and will be used in various positions within the Android UI.

    By default our extension will use a "bell" icon if you don't provide an icon resources yourself. In some circumstances you may see a white square. This is the Android attempt at using your application icon as the notification icon and is converting your icon based on whether a pixel is transparent or white.

    To add your own icon you will need to create your custom resources and then package them into an ANE in your AIR application. To generate these resources goto the Android Asset Studio Notification Icon Generator and upload your source image.

    Take note of the name of the icon. You will be using this name to reference this icon in notifications. Create as many different icons as you will require. These icons can be used for notification actions as well as for the main notification icon. You can use different icons for different notifications if you wish.

    Notification Bar with custom resource

    Custom resource icon in simple notification

    To create your own custom resources ANE have a look at the opensource script we have created:

    If you have troubles running this script simply send us your resources and we will create the extension for you.

    Special Resources

    We suggest you supply a default icon resource named ic_stat_distriqt_default. This icon will be used in situations where you don't supply an icon name for a notification. This will ensure all your notifications are correctly displayed.

    If you don't supply a default icon, then you must ensure all your notifications have an icon property or you will get the default "bell" icon.

    Order of Display

    Our extension uses the following order of preference when displaying an icon. If any aren't available or the version of Android doesn't match then the next in the list is attempted.

    • custom icon property
    • default icon (ic_stat_distriqt_default)
    • bell icon on newer Android versions (Lollipop or newer)
    • application icon on older Android versions

    Large Icons

    If you wish to use colour or a more detailed image for your notification you can use the "large icon" to display any image in place of the notification icon in the notification center. Your notification icon will still be displayed in the bar and overlayed on top of the large icon.

    For example, in the image below we have used a red cloud in a circle as the large icon and you will see the distriqt logo as our notification icon.

    This icon is not a resource but an image either packaged with your application or downloaded from a url. We don't suggest using a url unless absolutely neccessary, as a user may not get notifications if the image fails to download correctly or the device is offline for any reason.

    - + \ No newline at end of file diff --git a/docs/notifications/notification-scenarios/index.html b/docs/notifications/notification-scenarios/index.html index ec6d06d0135..5a6ad0d9da5 100644 --- a/docs/notifications/notification-scenarios/index.html +++ b/docs/notifications/notification-scenarios/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Notification Scenarios

    Foreground, background - Notification Scenarios

    While we have made all possible efforts to make the platforms the same there are very different methodologies taken by the different operating systems which will affect the details of when and if notifications will arrive.

    - + \ No newline at end of file diff --git a/docs/notifications/notification-types/index.html b/docs/notifications/notification-types/index.html index b1fa0d7e656..50a351fedc8 100644 --- a/docs/notifications/notification-types/index.html +++ b/docs/notifications/notification-types/index.html @@ -13,7 +13,7 @@ - + @@ -35,7 +35,7 @@ by using a %d in your string, eg to match the title shown above:

            .setGroupTitle( "A group of %d notifications" )

    Support:

    iOS 10

    iOS 10 introduced some ability to group notifications. This is handled automatically by the operating system grouping them by a "thread identifier" which we will set to the group key provided in your notification.

    Background Image

    You can add a background or hero image to your notification by calling setBackgroundImage() and specifying an image path or url.

    AndroidWindows

    On Android in order to cover all notification sizes this image should be sized 2600x256 (91.4:9) and this will be aligned top left.

    On Windows the image is used as the "hero" image for the notification. This hero image was new in the Windows Anniversary Update. The image dimensions are 364x180 pixels at 100% scaling.

    To specify the image to use for the background of the image pass the path or url to the setBackgroundImage method of your NotificationBuilder:

    Notifications.service.notify(
    new NotificationBuilder()
    .setId(id)
    .setIcon( "ic_stat_distriqt_default" )
    .setAlert( "Notification with actions" )
    .setTitle( "Notification with actions" )
    .setBody( "The body of the notification" )

    .setBackgroundImage( "assets/notifications/background.png" )

    .build()
    );

    The parameter for the setBackgroundImage method should be a path to the packaged image asset relative to your application root or a URL to a public image. URL's are discouraged due to the network access and download required.

    note

    On Android setting the background image of a notification will remove the notification icon and large icon. If you need to display these you should add them to your image.

    Text Colour

    On Android, you can control the text colour of the title and body text by using the setBackgroundImageTextColour function. This allows you to match the colour of the text to your image:

            .setBackgroundImage( "assets/notifications/background.png" )
    .setBackgroundImageTextColour( "#FF0000" )

    Colour supported formats are:

    The following names are also accepted: red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray, darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy, olive, purple, silver, and teal.

    Support:

    - + \ No newline at end of file diff --git a/docs/notifications/receiving-notifications/index.html b/docs/notifications/receiving-notifications/index.html index 4528adcc4e1..5ed7385a7c5 100644 --- a/docs/notifications/receiving-notifications/index.html +++ b/docs/notifications/receiving-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ each of the individual events contained in the group.

    The NotificationEvent.ACTION is dispatched when a user clicks an action on a notification. This event currently is missed on iOS when the application is not running (background, suspended and foreground states operate correctly). This is due to an issue with AIR not allowing AIR application to launch into the background.

    // Previously called init, setup and checked authorisation

    Notifications.service.addEventListener( NotificationEvent.NOTIFICATION, notificationHandler );
    Notifications.service.addEventListener( NotificationEvent.NOTIFICATION_SELECTED, notificationHandler );
    Notifications.service.addEventListener( NotificationEvent.ACTION, actionHandler );
    Notifications.service.addEventListener( NotificationGroupEvent.GROUP_SELECTED, groupSelectedHandler );

    Notifications.service.register();


    function notificationHandler( event:PushNotificationEvent ):void
    {
    trace( "Notification: ["+event.type+"] state="+event.applicationState+" startup="+event.startup );
    trace( event.payload );
    }

    function actionHandler( event:PushNotificationEvent ):void
    {
    trace( "Action: ["+event.type+"] identifier="+event.identifier+" state="+event.applicationState+" startup="+event.startup );
    trace( event.payload );
    }

    function groupSelectedHandler( event:PushNotificationGroupEvent ):void
    {
    trace( "Group Selected: ["+event.type+"] groupKey="+event.groupKey+" state="+event.applicationState+" startup="+event.startup );
    for each (var payload:String in event.payloads)
    {
    trace( "PAYLOAD: "+ payload );
    }
    }
    - + \ No newline at end of file diff --git a/docs/notifications/register-for-notifications/index.html b/docs/notifications/register-for-notifications/index.html index 009efccf6bd..68d842f6cee 100644 --- a/docs/notifications/register-for-notifications/index.html +++ b/docs/notifications/register-for-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ NotificationEvent.ACTION events.

    However there will only ever be one selected event, either NotificationEvent.NOTIFICATION_SELECTED or NotificationGroupEvent.GROUP_SELECTED. The selected event should be treated as a user interaction and you should load the appropriate view in your application.

    - + \ No newline at end of file diff --git a/docs/notifications/request-authorisation/index.html b/docs/notifications/request-authorisation/index.html index 7e72c826c43..a881dc4a6cb 100644 --- a/docs/notifications/request-authorisation/index.html +++ b/docs/notifications/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ You can check the value of hasAuthorisation() which will return true if the device is authorised and false otherwise. However the better method is to use the authorisationStatus() to determine the status, this will allow you to determine if your application has authorisation, has been denied or is not yet determined (i.e. the user has not yet been asked to grant authorisation).

    On iOS you will only be able to display the authorisation request dialog once! Hence it is very important that you inform your users why they should grant authorisation before requesting authorisation.

    To request authorisation you call requestAuthorisation(). This function will trigger the native dialog asking the user for authorisation.

    Notifications.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );

    switch (Notifications.service.authorisationStatus())
    {
    case AuthorisationStatus.AUTHORISED:
    // This device has been authorised.
    // You can register this device and expect:
    // - registration success/failed event, and;
    // - notifications to be displayed
    Notifications.service.register();
    break;

    case AuthorisationStatus.SHOULD_EXPLAIN:
    case AuthorisationStatus.NOT_DETERMINED:
    // You are yet to ask for authorisation or need to further explain
    // At this point you should consider your strategy to get your user to authorise
    // notifications by explaining what the application will provide
    Notifications.service.requestAuthorisation();
    break;

    case AuthorisationStatus.DENIED:
    // The user has disabled notifications
    // Advise your user of the lack of notifications as you see fit

    // For example: You can redirect to the settings page on iOS
    if (Notifications.service.canOpenDeviceSettings)
    {
    Notifications.service.openDeviceSettings();
    }
    break;
    }

    function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    // Check the authorisation state again (as above)
    }

    You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

    Device settings

    You can redirect the user to the device settings in order to get them to change the permission to access notifications.

    This can only be performed on some platforms and you should firstly check if it is supported before calling.

    if (Notifications.service.canOpenDeviceSettings)
    {
    Notifications.service.openDeviceSettings();
    }

    - + \ No newline at end of file diff --git a/docs/notifications/set-badge-number/index.html b/docs/notifications/set-badge-number/index.html index b4812ac2a7e..18006aa44ec 100644 --- a/docs/notifications/set-badge-number/index.html +++ b/docs/notifications/set-badge-number/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Set Badge Number

    You can set the badge number using this extension. The badge number is the small number that appears over the application icon.

    This was originally part of iOS and is built into the operating system there, but has been extended to Android and Windows.

    To set the badge number use the setBadgeNumber() method:

    Notifcations.service.setBadgeNumber( 4 );

    iOS

    On iOS it is part of the operating system and nothing additional is required. You can use the setBadgeNumber() method without any additional configuration.

    Android

    On Android some manufacturers have implemented a replica of the iOS functionality in the custom Android launchers distributed with their devices.

    Each manufacturer has a slightly different implementation which we have wrapped here.

    If you aren't using apm then you will need to ensure you have added all the additional permissions for each of the manufacturers to enable this functionality. Check the Add the Extension for more information.

    Android 8

    Android 8.0 (API level 26) introduces functionality for displaying notification badges on app icons in supported launchers. Notification badges show notifications associated with one or more notification channels in an app, which the user has not yet dismissed or acted on. Users can turn off badges for notification channels or apps from the Settings app. Notification badges are also known as notification dots).

    Users can also long-press on an app icon to glance at the notifications associated with a notification badge in supported launchers. Users can then dismiss or act on notifications from the long-press menu in a similar way to the notification drawer.

    By default, each new notification in a channel increments the number displayed on the associated launcher long-press menu by one. After a user dismisses a notification or triggers a related action, that number decrements to reflect the change.

    Adjusting Badges

    By default, each notification channel reflects its active notifications in your app's launcher icon badge. You can use the setShowBadge() method to stop the presence of notifications from a channel being reflected by a badge. You can't programmatically modify this setting for a notification channel after it's created and submitted to the notification manager.

    note

    Users can turn off badges for notification channels or apps from the Settings app at any time.

    The following sample code illustrates how to hide badges in association with notifications from a notification channel:

    service.channels.push(
    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .setShowBadge( false )
    .build()
    );

    Windows

    On Windows it is part of the operating system and nothing additional is required. You can use the setBadgeNumber() method without any additional configuration.

    The badge will appear on the application tile pinned to the start menu:

    And on the application tile in the task bar (when application is closed):

    - + \ No newline at end of file diff --git a/docs/notifications/setup-your-service/index.html b/docs/notifications/setup-your-service/index.html index c5457a6c1eb..9eeb9d8ccda 100644 --- a/docs/notifications/setup-your-service/index.html +++ b/docs/notifications/setup-your-service/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ you can use setShouldCancelOnAction and pass true.

    ...
    new ActionBuilder()
    .setTitle( "Accept" )
    .setIdentifier( "ACCEPT_IDENTIFIER" )
    .setShouldCancelOnAction( true )
    .build()
    ...

    When a user clicks this action, the notification will be cancelled and removed from the notification area.

    Notifications When Active

    On Android and on iOS v10+ you can enable notifications while your application is active. This will show a notification to the user, even if they are currently using the application.

    The default is false, i.e. not show a notification and your application would only receive the notification event.

    service.enableNotificationsWhenActive = true;

    Channels

    New to Android 8.0 (API level 26) is the concept of a notification channel.

    info

    Notification channels provide a unified system to help users manage notifications. When you target Android 8.0 (API level 26), you must implement one or more notification channels to display notifications to your users. If you don't target Android 8.0 (API level 26) but your app is used on devices running Android 8.0 (API level 26), your app behaves the same as it would on devices running Android 7.1 (API level 25) or lower.

    note

    The user interface refers to notification channels as notification categories.

    You can create an instance of a Channel for each distinct type of notification you need to send. You can also create notification channels to reflect choices made by users of your app. For example, you may set up separate notification channels for each conversation group created by a user in a messaging app.

    Users can manage most of the settings associated with notifications using a consistent system UI. All notifications posted to the same notification channel have the same behaviour. When a user modifies the behaviour for any of the following characteristics, it applies to the notification channel:

    Users can visit Settings, or long-press a notification to change these behaviors, or even block a notification channel at any time. You can't programmatically modify the behaviour of a notification channel after it's created and submitted to the notification manager; the user is in charge of those settings after creation. You can however rename a notification channel or update its description after creation.

    Creating Channels

    To create channels you add them to your Service definition. A Service.channels is an array of Channel objects that you should create when passing your service to the setup function.

    You should use the ChannelBuilder to create a Channel object.

    var service:Service = new Service();

    // Setup other service related properties

    service.channels.push(
    new ChannelBuilder()
    .setId( "example_channel" )
    .setName( "Example Channel" )
    .build()
    );
    caution

    You must add at least one channel.

    - + \ No newline at end of file diff --git a/docs/notifications/sounds/index.html b/docs/notifications/sounds/index.html index dd5dbc58577..8b14ab848f4 100644 --- a/docs/notifications/sounds/index.html +++ b/docs/notifications/sounds/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Sounds

    The following documentation describes how to get custom sounds to play when your notification arrives.

    Importantly these sounds are always affected by the user's sound settings and generally they can override what you provide (eg by muting the phone), so it's always worth checking your device before deciding sounds are failing.

    Sounds need to be treated slightly differently on the different platforms however if you follow the guide you should be able to have a single code base running correctly across all platforms.

    Setting the Sound

    On iOS and Android (prior to version 8.0) you can attach a sound to a notification directly using the setSound() function on your NotificationBuilder.

    new NotificationBuilder()

    // Other notification options

    .setSound( sound )

    .build();

    The sound string passed to the setSound() function can be a few different things:

    • A relative path of an asset file packaged with your application, eg "assets/notifications/sounds/notification.mp3"
    • A relative path of an asset file packaged with your application without the extension, eg "assets/notifications/sounds/notification"
      • In this case the extension will look for an mp3 file on Android and a caf file on iOS.
    • Android: The name of a raw sound resource you have packaged with your application (in a custom ANE).

    The second method is the suggested method as this is the easiest way to simulataneously support iOS and Android. The extension will select the correct file and you will need to package the caf file on iOS and mp3 file on Android.

    For example:

    .setSound( "assets/notifications/sounds/notification" )

    Will use the following files:

    • iOS: assets/notifications/sounds/notification.caf
    • Android: assets/notifications/sounds/notification.mp3

    You can either package both of these files or selectively package them for the appropriate platform.

    Using Channels

    From Android 8.0 (API level 26), they have introduced the concept of a notification channel. When you create a notification you must specify a channel for the notification to use through the setChannel() function on the NotificationBuilder.

    new NotificationBuilder()

    // Other notification options

    .setChannel( "channel_id" )

    ;

    The channel you specify controls the sound that will be played for notifications on Android 8 and higher.

    You create the channels along with your service (see Channels for more information).

    If you don't specify a channel when creating a notification it will default to the first channel in your service.

    To set the sound played for a notification channel you use the setSound() function on the ChannelBuilder:

    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .setGroup( "test_channel_group" )
    .setSound( "assets/notifications/sounds/notification" )
    .build();

    This function operates the same way as the setSound() function for the NotificationBuilder so you can specify exactly the same path / resource name that you would have used there.

    Note: Channels are ignored on iOS so the setting on the NotificationBuilder will always be used on iOS and on older Android versions. Android version 8.0 and higher will use the channel sound.

    - + \ No newline at end of file diff --git a/docs/ocr/add-the-extension/index.html b/docs/ocr/add-the-extension/index.html index aac21e0de7f..d574862d015 100644 --- a/docs/ocr/add-the-extension/index.html +++ b/docs/ocr/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.OCR

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ assets
    | |____ ios
    | | |____ Frameworks
    | | | |____ TesseractOCR.framework
    |____ ane
    | |____ com.distriqt.OCR.ane # OCR extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.

    • You will have an assets directory that contains required assets for the installed extensions. You must add the files in the assets/ios folder to the root of your iOS application package. (It contains the Frameworks folder with the required iOS dynamic frameworks). You do not need to add this to your Android application package.

    info

    We suggest you use these locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Training Data

    This extension does not include any training data.

    You will need to make sure you download and include at least one traineddata file.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (OCR.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/ocr/changelog/index.html b/docs/ocr/changelog/index.html index 06190868b6e..1cd38cf44cc 100644 --- a/docs/ocr/changelog/index.html +++ b/docs/ocr/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.29 [v4.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2022.02.10 [v4.0.1]

    Documentation update

    2022.01.14 [v4.0.0]

    Update to latest tesseract and support v4 of tessdata (resolves #5)
    Add documentation and example for using apm

    2021.10.12 [v3.0.24]

    Add air package 
    Remove ios minimum version flag

    2020.03.20 [v3.0.020]

    Android X migration (resolves #4)

    2019.07.03 [v2.0.014]

    Android 64bit support (resolves #2)
    Updated minimum iOS version to 8.0
    Embedded iOS bitcode
    Removed application keys

    2019.07.03 [v2.0.014]

    Android 64bit support (resolves #2)
    Updated minimum iOS version to 8.0
    Embedded iOS bitcode
    Removed application keys

    2019.07.03 [v2.0.011]

    Android 64bit support (resolves #2)
    Updated minimum iOS version to 8.0
    Embedded iOS bitcode
    Removed application keys

    2017.07.10 [v1.0.007]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.21 [v1.0.006]

    Updated documentation

    2016.12.21 [v1.0.006]

    Updated documentation

    2016.12.21 [v1.0.006]

    Updating docs

    2016.12.21 [v1.0.006]

    Initial Release v1.0
    - + \ No newline at end of file diff --git a/docs/ocr/index.html b/docs/ocr/index.html index e0871fee66b..552de1c216c 100644 --- a/docs/ocr/index.html +++ b/docs/ocr/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    OCR

    The OCR extension gives you the ability to perform optical character recognition (https://en.wikipedia.org/wiki/Optical_character_recognition) on an image.

    It is built upon the powerful Tesseract Open Source OCR Engine.

    The simple API allows you to quickly scan an image for textural content, using the powerful Tesseract framework, in just a few lines of code.

    Features:

    • OCR using the Tesseract framework;
    • Recognise text from image BitmapData;
    • Set languages;
    • Set whitelist characters;
    • Single API interface - your code works across supported platforms with no modifications;
    • Sample project code and ASDocs reference;

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    OCR.service.recognise( image );

    More information here:

    https://airnativeextensions.com/extension/com.distriqt.OCR

    License

    You can purchase a license for using this extension:

    https://airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/ocr/migrating-to-androidx/index.html b/docs/ocr/migrating-to-androidx/index.html index c12775f380a..4fc806c38c6 100644 --- a/docs/ocr/migrating-to-androidx/index.html +++ b/docs/ocr/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/ocr/recognising-text/index.html b/docs/ocr/recognising-text/index.html index edb22f71d0e..1a973a828aa 100644 --- a/docs/ocr/recognising-text/index.html +++ b/docs/ocr/recognising-text/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ you are scanning.

    For example if we were to use an embedded image:

    [Embed(source="image_sample.jpg")]
    public var Image:Class;

    var image:Bitmap = new Image() as Bitmap;

    OCR.service.recognise( image.bitmapData );

    Or to load from a URL using a Loader:

    var imageLoader:Loader = new Loader();
    imageLoader.load( new URLRequest( "http://example.com/image.jpg" ));
    imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);

    function loaded(e:Event):void
    {
    var image:Bitmap = e.target.content;

    OCR.service.recognise( image.bitmapData );
    }

    Specifying Options

    You can control some aspects of the scanning process by supplying an OCROptions instance to the recognise function. The options allow you to specify some parameters that will be used in the algorithm, such as the language and whitelist characters.

    For example:

    var options:OCROptions = new OCROptions();
    options.language = "eng";
    options.whitelist = "0123456789.,€$";

    OCR.service.recognise( bitmapData, options );
    - + \ No newline at end of file diff --git a/docs/ocr/tips-for-improving-ocr-results/index.html b/docs/ocr/tips-for-improving-ocr-results/index.html index 9f87240dbc1..d7fc476b13a 100644 --- a/docs/ocr/tips-for-improving-ocr-results/index.html +++ b/docs/ocr/tips-for-improving-ocr-results/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ that Tesseract performs OCR best when it is given a preprocessed image that is ideally crystal clear black text on a pure white background.

    The Tesseract library has a Wiki page on some processes that will improve the recognition results here: https://github.com/tesseract-ocr/tesseract/wiki/ImproveQuality

    The key points for optimal recognition are:

    - + \ No newline at end of file diff --git a/docs/ocr/training-data/index.html b/docs/ocr/training-data/index.html index df666b12f76..3f8d318b861 100644 --- a/docs/ocr/training-data/index.html +++ b/docs/ocr/training-data/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Training Data

    You will need to provide a trained data file for a language. Trained data files can be found in the Tesseract Tessdata Repository.

    Currently this extension supports v4 of the language data which can be found in github in the below release:

    https://github.com/tesseract-ocr/tessdata/releases/tag/4.1.0

    You need to provide the files for the languages you intend on scanning for. The extension will search for the LANG.traineddata language file in the tessdata directory.

    You should make sure that this tessdata directory is contained at the root (top level) of your AIR application.

    For example, specifying eng+ita will search for eng.traineddata and ita.traineddata.

    .
    |___ tessdata
    |____ eng.traineddata
    |____ ita.traineddata

    You specify the languages to use in the OCROptions instance:

    var options:OCROptions = new OCROptions();
    options.language = "eng+ita";

    OCR.service.recognise( bitmapData, options );

    By default, language is set to eng.

    Android

    On Android you can specify a different location for the tessdata directory by changing the OCROptions.dataPath property to point to an alternative location. However we suggest using the same location as iOS to keep your builds inline.

    - + \ No newline at end of file diff --git a/docs/packagemanager/add-the-extension/index.html b/docs/packagemanager/add-the-extension/index.html index 54dbb4817c3..6a109aaff46 100644 --- a/docs/packagemanager/add-the-extension/index.html +++ b/docs/packagemanager/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ AIR application's Java package name, something like air.com.distriqt.test. Generally this is your AIR application id prefixed by air. unless you have specified no air flair in your build options.

    <android>
    <manifestAdditions><![CDATA[
    <manifest android:installLocation="auto" >
    <uses-permission android:name="android.permission.INTERNET"/>

    <application>

    <receiver android:name="com.distriqt.extension.packagemanager.receivers.PackageManagerReceiver" android:enabled="true" android:exported="true" >
    <intent-filter>
    <action android:name="android.intent.action.PACKAGE_REMOVED" />
    <data android:scheme="package" />
    </intent-filter>
    </receiver>

    <provider
    android:name="com.distriqt.extension.packagemanager.content.PackageManagerFileProvider"
    android:authorities="APPLICATION_PACKAGE.packagemanagerfileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_packagemanager_paths" />
    </provider>

    </application>
    </manifest>
    ]]></manifestAdditions>
    </android>

    Supported

    You should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    if (PackageManager.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/packagemanager/changelog/index.html b/docs/packagemanager/changelog/index.html index 6b0abf29df0..d3a76bb4246 100644 --- a/docs/packagemanager/changelog/index.html +++ b/docs/packagemanager/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.07.20 [v3.4.0]

    feat(android): add ability to query a single package name for PackageInfo

    2023.01.29 [v3.3.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2021.10.12 [v3.2.2]

    Add kill process functionality (resolves #6)

    2020.04.06 [v3.1.025]

    Added ability to retrieve a list of installed application packages (resolves #4)

    2020.03.20 [v3.0.018]

    Android X migration (resolves #3)

    2019.10.18 [v2.0.015]

    Resolved install apk permissions issue with older Android versions (resolves #2)

    2019.08.15 [v2.0.003]

    Android 64bit update (resolves #1)
    Updated minimum iOS version to 9.0

    2019.04.08 [v1.1.025]

    Updated documentation

    2019.04.08 [v1.1.025]

    Initial release
    - + \ No newline at end of file diff --git a/docs/packagemanager/index.html b/docs/packagemanager/index.html index a3f0e5540f5..66d2846280e 100644 --- a/docs/packagemanager/index.html +++ b/docs/packagemanager/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    PackageManager

    The PackageManager extension gives access to certain features of the Android package manager.

    Features:

    • Receive package added and removed events when other applications are installed or removed from the device
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    PackageManager.service.addEventListener( PackageManagerEvent.PACKAGE_REMOVED, packageRemovedHandler );

    function packageRemovedHandler( event:PackageManagerEvent ):void
    {
    trace( "Package Removed::"+ event.packageName );
    }

    More information here:

    com.distriqt.PackageManager

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/packagemanager/installed-application-info/index.html b/docs/packagemanager/installed-application-info/index.html index 07cc45ac2f2..d804585d325 100644 --- a/docs/packagemanager/installed-application-info/index.html +++ b/docs/packagemanager/installed-application-info/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Installed Application Info

    Permissions

    In order to retrieve information about other applications you must add the package name for the application to the queries node in your manifest additions.

    <queries>
    <package android:name="com.application.example" />
    </queries>

    You'll need to identify the package name of the application you wish to query.

    All packages permission

    Google generally restricts the visibility of installed packages, however there is a broad permission QUERY_ALL_PACKAGES that Google grants to applications in certain circumstances. If you have access to this permission then you don't need to include the queries.

    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

    More information here: https://support.google.com/googleplay/android-developer/answer/10158779?hl=en#zippy=%2Cpermitted-uses-of-the-query-all-packages-permission

    Query single application

    You can query information about a single application by using the getPackageInfo() method. This method returns a PackageInfo object representing the queried package. If this returns null the application isn't installed (or you didn't add the correct permissions).

    var packageInfo:PackageInfo = PackageManager.service.getPackageInfo( "com.application.example" );
    if (packageInfo == null)
    {
    // Application not installed or permission denied
    }

    Querying all applications

    There are two methods to retrieve the installed application information, asynchronous and synchronous. We suggest the async method as it shouldn't affect the ui as much as the synchronous method may do, depending on the device and the number of applications installed.

    Which ever method you use, the end result is an Array of PackageInfo objects. These objects contain:

    • packageName: The java package name of the application
    • label: The name of the application
    • versionName: The version name of this package, as specified by the manifest tag's versionName attribute
    • versionCode: The version code for the application

    along with other information detailed in the asdocs.

    Asynchronous retrieval

    In order to retrieve a list of applications that are installed on the device call the getInstalledApplicationsAsync() function.

    You can use either a callback passed to the function or listen for the PackageManagerEvent.GET_INSTALLED_APPLICATIONS event (or both)

    Listening for the event involves adding a listener for PackageManagerEvent.GET_INSTALLED_APPLICATIONS and then processing the result in the handler:

    PackageManager.service.addEventListener( 
    PackageManagerEvent.GET_INSTALLED_APPLICATIONS,
    getInstalledApplicationsHandler
    );

    PackageManager.service.getInstalledApplicationsAsync();


    function getInstalledApplicationsHandler( event:PackageManagerEvent ):void
    {
    var installedPackages:Array = event.data;
    if (installedPackages != null)
    {
    for each (var packageInfo:PackageInfo in installedPackages)
    {
    trace( packageInfo.packageName );
    }
    }
    }

    Alternatively you can do the similar thing with a callback:

    PackageManager.service.getInstalledApplicationsAsync(
    function( installedPackages:Array ):void
    {
    if (installedPackages != null)
    {
    for each (var packageInfo:PackageInfo in installedPackages)
    {
    trace( packageInfo.packageName );
    }
    }
    }
    );

    Synchronous retrieval

    You can also call getInstalledApplications() to directly retrieve an array of the application package information however be aware that this call may take some time.

    var installedPackages:Array = PackageManager.service.getInstalledApplications();
    if (installedPackages != null)
    {
    for each (var packageInfo:PackageInfo in installedPackages)
    {
    trace( packageInfo.packageName );
    }
    }
    - + \ No newline at end of file diff --git a/docs/packagemanager/installing-apps/index.html b/docs/packagemanager/installing-apps/index.html index efe7d9fccb3..829c0cccb4e 100644 --- a/docs/packagemanager/installing-apps/index.html +++ b/docs/packagemanager/installing-apps/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Installing Apps

    Android only

    Remember that Play policies still apply to apps distributed on Google Play if those apps can install and update other apps. In the majority of cases, such behavior is inappropriate; you should instead provide a deep link to the app's listing on the Play Store.

    Manifest Additions

    If an app uses a targetSdkLevel of 26 or above and prompts the user to install other apps, the manifest file needs to include the REQUEST_INSTALL_PACKAGES permission.

    Apps that haven't declared this permission cannot install other apps, a handy security protection for apps that have no intention of doing so.

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

    In order to correctly access the APK file you will also need to add the following file provider to the manifest inside the application tag.

    You will need to replace APPLICATION_PACKAGE with your applications package name, generally your AIR application id prepended with air. eg air.com.distriqt.test

    <provider
    android:name="com.distriqt.extension.packagemanager.content.PackageManagerFileProvider"
    android:authorities="APPLICATION_PACKAGE.packagemanagerfileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_packagemanager_paths" />
    </provider>

    Availability

    You can check whether the current device can install applications by checking the canRequestApplicationInstalls flag:

    if (PackageManager.service.canRequestApplicationInstalls)
    {
    // Can install applications
    }

    Settings

    You can redirect the user to the appropriate settings by calling showManageUnknownAppSourcesSettings():

    PackageManager.service.showManageUnknownAppSourcesSettings();

    This will redirect the user to the application settings screen similar to the following:

    On older versions of Android it will redirect to the generic unknown sources settings screen.

    Install

    To install an application use the installApplication() method and pass the native path to an APK file:

    var apkFile:File = File.applicationStorageDirectory.resolvePath( "Main.apk" );

    PackageManager.service.installApplication( apkFile.nativePath );
    - + \ No newline at end of file diff --git a/docs/packagemanager/migrating-to-androidx/index.html b/docs/packagemanager/migrating-to-androidx/index.html index e3bf4007ac9..0e2b3c1e729 100644 --- a/docs/packagemanager/migrating-to-androidx/index.html +++ b/docs/packagemanager/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/packagemanager/package-events/index.html b/docs/packagemanager/package-events/index.html index cc794c2c3c1..b013b7d9fb2 100644 --- a/docs/packagemanager/package-events/index.html +++ b/docs/packagemanager/package-events/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Package Events

    Package Removed

    The package removed event is dispatched every time another application package is removed from the device. The event will contain the package name (i.e. application id) of the application that was removed.

    Using this functionality is as simple as adding a listener for the PackageManagerEvent.PACKAGE_REMOVED event and processing the event in a handler function, for example:

    PackageManager.service.addEventListener( PackageManagerEvent.PACKAGE_REMOVED, packageRemovedHandler );

    function packageRemovedHandler( event:PackageManagerEvent ):void
    {
    trace( "Package Removed::"+ event.packageName );
    }

    The extension can also dispatch events for any package that was removed while your application was not running. These events will get dispatched straight after you add a listener for the package removed event.

    In order for your application to receive events while your application is not running, you must add the following to your Android applications manifest additions. You should have done this as part of the Add the Extension section but we will list the important receiver again here.

    <receiver android:name="com.distriqt.extension.packagemanager.receivers.PackageManagerReceiver" android:enabled="true" android:exported="true" >
    <intent-filter>
    <action android:name="android.intent.action.PACKAGE_REMOVED" />
    <data android:scheme="package" />
    </intent-filter>
    </receiver>
    caution

    This event is not dispatched when your application is removed. You cannot detect your own application removal using this process only other applications.

    - + \ No newline at end of file diff --git a/docs/pdfreader/add-the-extension/index.html b/docs/pdfreader/add-the-extension/index.html index 40be897afba..b44cc0a36be 100644 --- a/docs/pdfreader/add-the-extension/index.html +++ b/docs/pdfreader/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ access will satisfy the Apple App Transport security (i.e. access content via https) or else you will need to override the setting in the info additions.

    The following shows how to override all loads, however it is suggested you only override the particular servers you will use, so take care when using this setting.

    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    </dict>

    Supported

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (PDFReader.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/pdfreader/changelog/index.html b/docs/pdfreader/changelog/index.html index ed217d88eb8..b145dd741c4 100644 --- a/docs/pdfreader/changelog/index.html +++ b/docs/pdfreader/changelog/index.html @@ -13,7 +13,7 @@ - + @@ -32,7 +32,7 @@ Added 'Share' option to display share actions

    2015.02.19

    Changed class structure to support FlashBuilder 4.6 (resolves #2)

    2015.02.03

    Added check for .debug suffix in application id

    2014.12.22

    iOS: Included arm64 support (resolves #1) Android: Corrected application id check when doesn't contain air prefix

    2014.12.08

    Corrected missing EventDispatcher functions from base class iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    New application based key check, removing server checks

    2014.10.20

    iOS Update for iOS 8

    - + \ No newline at end of file diff --git a/docs/pdfreader/create-a-pdf-view/index.html b/docs/pdfreader/create-a-pdf-view/index.html index b97f1589faa..75081ccada0 100644 --- a/docs/pdfreader/create-a-pdf-view/index.html +++ b/docs/pdfreader/create-a-pdf-view/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ create the PDFView.

    Once you create a view you can set the viewport and listen for view events (such as SHOWN and HIDDEN) and finally call show to present the view to the user, as shown in the example below:

    var view:PDFView = PDFReader.service.createView( 
    new PDFViewBuilder()
    .setPath( "native/path/to/file.pdf" )
    .showDoneButton( true )
    .showTitle( true )
    .build()
    );

    view.setViewport( 50, 100, 400, 500 );
    view.addEventListener( PDFViewEvent.SHOWN, pdfView_shownHandler );
    view.addEventListener( PDFViewEvent.HIDDEN, pdfView_hiddenHandler );

    view.show();
    private function pdfView_shownHandler( event:PDFViewEvent ):void
    {
    trace( "view shown" );
    }

    private function pdfView_hiddenHandler( event:PDFViewEvent ):void
    {
    trace( "view hidden" );
    }
    - + \ No newline at end of file diff --git a/docs/pdfreader/index.html b/docs/pdfreader/index.html index 003f8eb6afa..2da13bbaac4 100644 --- a/docs/pdfreader/index.html +++ b/docs/pdfreader/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ Identical code base can be used across supported platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with asset selection quickly and easily.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    PDFReader.service.showPDF( File.applicationDirectory.nativePath + File.separator + "TestDocument.pdf" );

    More information here:

    com.distriqt.PDFReader

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/pdfreader/migrating-to-androidx/index.html b/docs/pdfreader/migrating-to-androidx/index.html index 6c4888fca87..7c4b469a766 100644 --- a/docs/pdfreader/migrating-to-androidx/index.html +++ b/docs/pdfreader/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/pdfreader/pages/index.html b/docs/pdfreader/pages/index.html index f47088771b0..4e5b108fda9 100644 --- a/docs/pdfreader/pages/index.html +++ b/docs/pdfreader/pages/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Pages

    You can get information about the pages in the current document:

    • currentPage returns the current page displayed
    • totalPages returns the number of pages in the loaded document

    For example the following will trace out something like, Page 1 / 8:

    trace( "Page " + view.currentPage + " / " + view.totalPages );

    Set Current Page

    To change the current page displayed you can use the setPage function, eg to change to page 4:

    view.setPage( 4 );
    - + \ No newline at end of file diff --git a/docs/permissions/add-the-extension/index.html b/docs/permissions/add-the-extension/index.html index f9fa7046d7d..572b4b4b2e1 100644 --- a/docs/permissions/add-the-extension/index.html +++ b/docs/permissions/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ particular you need to add the activity in the listing below.

    <manifest android:installLocation="auto">

    <!-- PERMISSIONS -->
    <!-- You should add your permissions here normally eg: -->
    <uses-permission android:name="android.permission.CAMERA" />

    <application>

    <activity android:name="com.distriqt.core.auth.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:exported="false" />

    </application>

    </manifest>

    Additionally you will need to add your application permissions as normal. Using this ANE does not eliminate the need to define your permissions in the manifest! See the documentation on "set permissions" for more details.

    Supported

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Permissions.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/permissions/changelog/index.html b/docs/permissions/changelog/index.html index c71a89920dc..11df77db417 100644 --- a/docs/permissions/changelog/index.html +++ b/docs/permissions/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v3.4.1]

    fix(airpackage): correct android manifest additions for changes to permissions process

    2023.01.31 [v3.4.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 
    feat(android): Move to new permissions request process

    2022.11.14 [v3.3.1]

    feat: add openDirectory result event (PermissionsEvent.OPEN_DOCUMENT) with path
    feat(docs): add documentation on openDirectory functionality

    2022.09.01 [v3.3.0]

    feat(android): add permissions for managing all files on a storage device (resolves #22)

    2022.09.01 [v3.3.0]

    feat(android): add permissions for managing all files on a storage device (resolves #22)

    2022.02.11 [v3.2.2]

    Update for Android 31
    Update docs to use apm

    2021.12.15 [v3.2.1]

    Resolve conflict with package manager ane (resolves #21)

    2021.10.27 [v3.2.0]

    Add handling of WRITE_SETTINGS permission (resolves #20)
    Add openDirectory function for access to a file (resolves #19)
    Add air package
    Update permissions activity security settings

    2020.03.20 [v3.0.011]

    Android X migration (resolves #17)

    2019.08.15 [v2.0.003]

    Android 64bit support (resolves #14)
    Corrected function names (resolves #10)
    Updated minimum iOS version to 9.0

    2019.06.13 [v1.1.014]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode

    2018.12.18 [v1.0.010]

    Removed application key requirement

    2017.07.10 [v1.0.007]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.30 [v1.0.006]

    Updated documentation

    2016.12.30 [v1.0.006]

    Updated SDKs + new documentation

    2016.05.28

    Added individual permission check and request functions

    2016.05.28

    Updated documentation

    2016.05.27

    Release v1.0
    - + \ No newline at end of file diff --git a/docs/permissions/file-folder-access/index.html b/docs/permissions/file-folder-access/index.html index 977e0f11884..d9e11e5174a 100644 --- a/docs/permissions/file-folder-access/index.html +++ b/docs/permissions/file-folder-access/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    File and Folder Access

    Android has placed additional permissions on files outside of your application sandbox and now requires you to request user access to these directories (eg the camera storage on the sdcard: /sdcard/DCIM ).

    To gain access to these folders call the openDirectory() method with the required path:

    var f:File = new File( "/sdcard/DCIM" );
    Permissions.instance.openDirectory( f.nativePath );

    This process uses the ACTION_OPEN_DOCUMENT_TREE intent to allow the user to pick a directory subtree. Once complete your application will be able to fully manage documents within the returned directory. There are some exceptions starting in Android 11 (API 30)

    This will display a "browse" dialog for the user to select a directory and grant your application access to this location:

    Once complete this will dispatch a PermissionsEvent.OPEN_DIRECTORY event with the selected path.

    Permissions.instance.addEventListener( 
    PermissionsEvent.OPEN_DOCUMENT,
    function ( event:PermissionsEvent ):void
    {
    trace( event.path );
    }
    );
    Path

    Please note the path will likely be an Android content uri and not a file path, for example:

    content://com.android.externalstorage.documents/tree/primary%3ADCIM
    - + \ No newline at end of file diff --git a/docs/permissions/index.html b/docs/permissions/index.html index a8a270e37b0..ff2d3429e25 100644 --- a/docs/permissions/index.html +++ b/docs/permissions/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with asset selection quickly and easily.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    - + \ No newline at end of file diff --git a/docs/permissions/migrating-to-androidx/index.html b/docs/permissions/migrating-to-androidx/index.html index b5f4fa15b65..51f5a7b558f 100644 --- a/docs/permissions/migrating-to-androidx/index.html +++ b/docs/permissions/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/permissions/migrating-to-v3.4/index.html b/docs/permissions/migrating-to-v3.4/index.html index 55184b88a18..62f83c39c92 100644 --- a/docs/permissions/migrating-to-v3.4/index.html +++ b/docs/permissions/migrating-to-v3.4/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v3.4

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/permissions/requesting-access/index.html b/docs/permissions/requesting-access/index.html index af949b194a5..1f33670cce3 100644 --- a/docs/permissions/requesting-access/index.html +++ b/docs/permissions/requesting-access/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ the permissions similar to iOS. You will still need to list them in your manifest and then follow the same code below.

    Check Authorisation

    You can check the current authorisation status by calling the authorisationStatus() method:

    switch (Permissions.service.authorisationStatus())
    {
    case AuthorisationStatus.AUTHORISED:
    // This device has been authorised.
    break;

    case AuthorisationStatus.NOT_DETERMINED:
    case AuthorisationStatus.SHOULD_EXPLAIN:
    // You are yet to ask for authorisation or need to further explain
    // At this point you should consider your strategy to get your
    // user to authorise by explaining your need for the permissions
    break;

    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    case AuthorisationStatus.RESTRICTED:
    // The user has disabled the permissions
    // Advise your user of the lack of permissions as you see fit
    break;
    }

    You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

    Request Authorisation

    To request authorisation call the requestAuthorisation() function:

    Permissions.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
    Permissions.service.requestAuthorisation();

    You will then receive a change event if the user accepted your permission request:

    function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    // Check the authorisation state again (as above)
    }

    Example

    function checkAndRequestAuthorisation():void 
    {
    switch (Permissions.service.authorisationStatus())
    {
    case AuthorisationStatus.AUTHORISED:
    // This device has been authorised.
    break;

    case AuthorisationStatus.NOT_DETERMINED:
    // You are yet to ask for authorisation
    Permissions.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
    Permissions.service.requestAuthorisation();
    break;

    case AuthorisationStatus.SHOULD_EXPLAIN:
    // At this point you should consider your strategy to get your
    // user to authorise by explaining your need for the permissions

    // You can attempt a request again or show a dialog as to the requirement for the permission

    break;

    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    case AuthorisationStatus.RESTRICTED:
    // The user has disabled the permissions
    // Advise your user of the lack of permissions as you see fit
    break;
    }
    }

    function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    // Check the authorisation state again (as above)
    checkAndRequestAuthorisation();
    }
    - + \ No newline at end of file diff --git a/docs/permissions/set-permissions/index.html b/docs/permissions/set-permissions/index.html index bdaeb5aed62..67cf3654401 100644 --- a/docs/permissions/set-permissions/index.html +++ b/docs/permissions/set-permissions/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ This is done by passing an array of Strings each being the permission required.

    For example to set the camera permission:

    Permissions.service.setPermissions( 
    [
    "android.permission.CAMERA"
    ]
    );

    A complete list of the possible permissions is found here.

    Adding Permissions

    In addition to informing the extension of the permissions you must add these permissions to your application's manifest.

    Permissions are represented with a tag like the following:

    <uses-permission android:name="android.permission.CAMERA" />

    To add these permissions you need to add some additional configuration to apm. Firstly add a custom Android configuration file by running:

    apm generate config android

    Edit the config/android/AndroidManifest.xml file that was generated to resemble the following, adding the required permissions, eg:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.CAMERA" />

    </manifest>

    You can add any other additions you require in your application here and these will be merged by apm when you generate your application descriptor.

    info

    Make sure you regenerate your application descriptor after modifying this file. See the section in add the extension for details.

    - + \ No newline at end of file diff --git a/docs/permissions/system-settings/index.html b/docs/permissions/system-settings/index.html index 9c2d5a91409..e745c9ca0a4 100644 --- a/docs/permissions/system-settings/index.html +++ b/docs/permissions/system-settings/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    System Settings

    Some permissions are controlled through the system settings dialogs and cannot be requested through the normal permission request process.

    Write Settings

    The permission to read and write to the system settings (android.permission.WRITE_SETTINGS) from Android API 23 now requires a user to explicitly grant this permission to an application through a permission management screen.

    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    You cannot request this permission but you can check the current state and show the screen for the user to change the setting.

    info

    This permission is required for when you need to change system settings, such as the screen brightness as performed in the Application extension.

    To check the state of the permission use the canWrite property on the settings:

    if (Permissions.instance.settings.canWrite)
    {
    // App can write to system settings
    }

    To display the permission management screen for the user to change this state, call the showManageSettingsScreen() method:

    Permissions.instance.settings.showManageSettingsScreen();

    There is also an event dispatched (SettingsEvent.MANAGE_SETTINGS_CLOSED) when this screen is closed:

    Permissions.instance.settings.addEventListener( 
    SettingsEvent.MANAGE_SETTINGS_CLOSED,
    manageSettingsClosedHandler
    );

    Permissions.instance.settings.showManageSettingsScreen();

    function manageSettingsClosedHandler( event:SettingsEvent ):void
    {
    // screen closed
    }

    All Files Permission

    The majority of apps that require shared storage access can follow the best practices for sharing media files and sharing non-media files. However, some apps have a core use case that requires broad access of files on a device, but cannot do so efficiently using the privacy-friendly storage best practices. Android provides a special app access called All files access for these situations.

    For more information on this permission see the Android documentation section on managing all files.

    note

    For API versions < 30 don't require this additional permission and the following will always fail and isExternalStorageManager() will always return true indicating the application already has access.

    Request All files access

    An app can request All files access from the user by doing the following:

    • Declare the android.permission.MANAGE_EXTERNAL_STORAGE permission in the manifest.
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    • Use the ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent action to direct users to a system settings page where they can enable the following option for your app: Allow access to manage all files.

    With this extension you can trigger the ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION by calling:

    Permissions.instance.settings
    .showManageAllFileAccessPermission();

    This will return true if the intent was found and launched.

    Additionally you can listen for the SettingsEvent.MANAGE_ALL_FILES_ACCESS_PERMISSION_CLOSED event to be notified of when the dialog is closed and focus returned to your application.

    Permissions.instance.settings.addEventListener( 
    SettingsEvent.MANAGE_ALL_FILES_ACCESS_PERMISSION_CLOSED,
    closedHandler
    );

    function closedHandler( event:SettingsEvent ):void
    {
    trace( "closed" );
    }

    Request App All files access

    You can also trigger the ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION intent which will direct the user straight to your application setting if available.

    Permissions.instance.settings
    .showManageAppAllFileAccessPermission();

    This will return true if the intent was found and launched.

    Additionally you can listen for the SettingsEvent.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION_CLOSED event to be notified of when the dialog is closed and focus returned to your application.

    Permissions.instance.settings.addEventListener( 
    SettingsEvent.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION_CLOSED,
    closedHandler
    );

    function closedHandler( event:SettingsEvent ):void
    {
    trace( "closed" );
    }

    Check Granted

    To determine whether your app has been granted the MANAGE_EXTERNAL_STORAGE permission, call Environment.isExternalStorageManager().

    var granted:Boolean = 
    Permissions.instance.environment.isExternalStorageManager();
    - + \ No newline at end of file diff --git a/docs/pushnotifications/add-the-extension/index.html b/docs/pushnotifications/add-the-extension/index.html index 502f4c0a3fe..a64e09f348b 100644 --- a/docs/pushnotifications/add-the-extension/index.html +++ b/docs/pushnotifications/add-the-extension/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Extension

    Here we will show you how to add the extension to your development environment and make the necessary changes to your application descriptor to correctly support the extension.

    The extension supports different services and most likely you will not want to use them all in your applications. As such we have produced different "variants" of the extension which include support for different services while providing exactly the same Actionscript API.

    However while the API is identical there are varying dependencies and application descriptor additions required. As such we have broken the guide for adding the extension into the various services, each showing the variant(s) that support the service and the required additions to your application.

    Services:

    AIR SDK

    This ANE currently requires at least AIR 33+. This is required in order to support versions of Android > 9.0 (API 28). We always recommend using the most recent build with AIR especially for mobile development where the OS changes rapidly.

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    Core.init();
    if (PushNotifications.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/pushnotifications/apple/add-the-extension/index.html b/docs/pushnotifications/apple/add-the-extension/index.html index cf80e101017..3e3fbd912a3 100644 --- a/docs/pushnotifications/apple/add-the-extension/index.html +++ b/docs/pushnotifications/apple/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -36,7 +36,7 @@ If you do not include it, then you will only receive the notification events in the background when the user clicks a notification.

    However it is not required if you do not wish to include it.

    Firstly add a custom iOS configuration file by running:

    apm generate config ios

    Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the UIBackgroundModes node:

    <plist version="1.0">
    <dict>

    <key>UIDeviceFamily</key>
    <array>
    <string>1</string>
    <string>2</string>
    </array>

    <key>UIBackgroundModes</key>
    <array>
    <string>remote-notification</string>
    </array>

    </dict>
    </plist>

    You can add any other information you need in your info additions in this file as well, such as MinimumOSVersion or your UILaunchStoryboardName.

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    Critical Alerts

    Optional

    Critical alerts are important notifications that will ignore Do Not Disturb mode, and ringer settings, so they cannot be muted.

    This is an opt-in service and developers must request approval from Apple in order to add this feature to an application. Generally only applications that send notifications related to health, public safety and home security are approved.

    If you are approved by Apple then to enable critical alerts you will need to add some additions to your Entitlements section.

    Firstly add a custom iOS configuration file by running:

    apm generate config ios

    Edit the config/ios/Entitlements.xml file that was generated to resemble the following:

    <plist version="1.0">
    <dict>

    <key>com.apple.developer.usernotifications.critical-alerts</key>
    <true/>

    </dict>
    </plist>

    You can add any other information you need in your info additions in this file as well, such as MinimumOSVersion or your UILaunchStoryboardName.

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    Additionally you will need to request authorisation from the user. This is handled as part of the normal authorisation process however you need to inform the extension that you require critical alerts by calling setShouldRequestCriticalAlerts() on your Service configuration:

    var service:Service = new Service() 
    .setShouldRequestCriticalAlerts();

    // Other service options

    - + \ No newline at end of file diff --git a/docs/pushnotifications/apple/apple-push-notification-service/index.html b/docs/pushnotifications/apple/apple-push-notification-service/index.html index 624313c08f9..023e747218d 100644 --- a/docs/pushnotifications/apple/apple-push-notification-service/index.html +++ b/docs/pushnotifications/apple/apple-push-notification-service/index.html @@ -13,7 +13,7 @@ - + @@ -90,7 +90,7 @@ certificate through this process) at this point if you wish with the following command:

    openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert YOUR_CERTIFICATE.pem -key YOUR_PRIVATE_KEY.pem

    This should connect to the server and dump out a whole heap of information about the process. Eventually after the successful connection you should be able to type a few characters and the server should disconnect.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/apple/ios-apns-message/index.html b/docs/pushnotifications/apple/ios-apns-message/index.html index 17671bf9d71..0549f4331f5 100644 --- a/docs/pushnotifications/apple/ios-apns-message/index.html +++ b/docs/pushnotifications/apple/ios-apns-message/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    iOS APNS Message

    There are many ways to send notifications to your devices.

    The basic procedure is once your application has sent the device token (registration id) to your server, your server will send a message to the appropriate service (APNS/GCM) which will deliver the notification to the registered device.

    PHP Example

    The following is a very basic PHP example, sending a message to a single device.

    <?php
    // Put your device token here (without spaces):
    $deviceToken = 'DEVICE_TOKEN';

    // Put your private key's passphrase here:
    $passphrase = 'passphrase';
    $pemfilename = 'ck.pem';

    // SIMPLE PUSH
    $body['aps'] = array(
    'alert' => array(
    'title' => "You have a notification",
    'body' => "Body of the message",
    ),
    'badge' => 1,
    'sound' => 'default',
    ); // Create the payload body

    ////////////////////////////////////////////////////////////////////////////////

    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', $pemfilename);
    stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

    $fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); // Open a connection to the APNS server
    if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);
    echo 'Connected to APNS' . PHP_EOL;
    $payload = json_encode($body); // Encode the payload as JSON
    $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; // Build the binary notification
    $result = fwrite($fp, $msg, strlen($msg)); // Send it to the server
    if (!$result)
    echo 'Message not delivered' . PHP_EOL;
    else
    echo 'Message successfully delivered' . PHP_EOL;
    fclose($fp); // Close the connection to the server

    You run these scripts using php:

    php script.php
    - + \ No newline at end of file diff --git a/docs/pushnotifications/apple/ios-apns-payload/index.html b/docs/pushnotifications/apple/ios-apns-payload/index.html index 1a81c774d2a..614904f1ea3 100644 --- a/docs/pushnotifications/apple/ios-apns-payload/index.html +++ b/docs/pushnotifications/apple/ios-apns-payload/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ on your Service

    {
    "aps" :
    {
    "alert" : {
    "title" : "Game Request",
    "body" : "Bob wants to play poker",
    },
    "badge" : 1,
    "sound" : "default",
    "category" : "INVITE_CATEGORY"
    }
    }

    To send a silent (background) notification you add the content-available field. You should not send an alert as part of a background notification. If you do you may receive additional notification events.

    {
    "aps" : {
    "content-available" : 1,
    "sound" : ""
    },
    "custom-key" : "custom-value"
    }

    More details here: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html

    - + \ No newline at end of file diff --git a/docs/pushnotifications/azure/azure-notifications/index.html b/docs/pushnotifications/azure/azure-notifications/index.html index 099643c52d4..5e89b48749e 100644 --- a/docs/pushnotifications/azure/azure-notifications/index.html +++ b/docs/pushnotifications/azure/azure-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -49,7 +49,7 @@ when you were setting up your application in the iOS developer center. The seed id should be a unique ten character string and the identifier should be similar to your AIR application id.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/azure/setup-your-service/index.html b/docs/pushnotifications/azure/setup-your-service/index.html index 6292678cb81..26976669cf7 100644 --- a/docs/pushnotifications/azure/setup-your-service/index.html +++ b/docs/pushnotifications/azure/setup-your-service/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Setup your Service - Azure

    The following shows how to configure the Service for usage with your Azure Notification Hub.

    var service:Service;
    if (PushNotifications.service.isServiceSupported( Service.AZURE ))
    {
    service = new Service( Service.AZURE );
    service.serviceId = AZURE_HUB_NAME;
    service.serviceKey = AZURE_HUB_LISTENACCESS;
    }

    PushNotifications.service.setup( service );

    The serviceId will be the name of your notification hub, eg distriqt.

    The serviceKey will be the connection string value for the DefaultListenSharedAccessSignature policy defined in the Access Policies section of your hub.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/changelog/index.html b/docs/pushnotifications/changelog/index.html index 0f3316f6cea..f3fc625cff9 100644 --- a/docs/pushnotifications/changelog/index.html +++ b/docs/pushnotifications/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.24 [v14.0.0]

    feat(onesignal): update onesignal sdk to android v5.0.3, ios v5.0.2
    fix(ios,fcm): correct inclusion of frameworks on iOS < 13 causing crash at launch (resolves #580)

    2023.09.22 [v13.0.1]

    feat(docs): update docs for using amazon with onesignal (resolves #340)
    fix(android): correct handling of authorisation denied state, incorrectly returned not_determined resulting in ANRs (#576)

    2023.08.11 [v13.0.0]

    feat(onesignal): add huawei push services functionality to OneSignal which required separation of the firebase messaging dependency

    2023.08.11 [v13.0.0]

    feat(onesignal): add huawei push services functionality to OneSignal which required separation of the firebase messaging dependency

    2023.08.10 [v12.0.1]

    feat(fcm): add retrieval of the installation id as the service token (#573)

    2023.07.05 [v12.0.0]

    Firebase BOM update to v32.1.1

    feat(fcm): update to latest Firebase version android v23.1.2, ios v10.11.0
    feat(firebase-iam): update to latest Firebase InApp Messaging, android v20.3.2, ios v10.11.0

    2023.02.10 [v11.3.1]

    feat(onesignal): forced removal of bitcode from dynamic frameworks (resolves #558)

    2023.01.10 [v11.3.0]

    feat(ios): remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #551, resolves #552)
    feat(android): update to new cleaner authorisation process in latest AIR SDK
    fix(docs): correct issue with android manifest docs (#555)
    feat(pushy): update Android SDK v1.0.89
    feat(pushy): correct operation of Android startup events (resolves #553)

    2022.12.15 [v11.2.0]

    feat(onesignal): sdk update android v4.8.3, ios v3.12.3 (resolves #549)
    feat(android): add android 13 notification permission request
    fix(swc): update build scripts and air version used to build swcs (resolves #545)
    fix(ios): add null checks for device / service tokens (resolves #542)

    2022.07.01 [v11.1.1]

    fix(onesignal): airpackage fix for onesignal manifest missing tools namespace

    2022.06.23 [v11.1.0]

    feat(onesignal,android): onesignal android sdk update v4.7.3
    feat(fcm,ios): update firebase messaging sdk to v8.1.5

    2022.03.15 [v11.0.0]

    Firebase SDK update:
    - Android BoM v29.0.4

    OneSignal SDK update:
    - Android v4.7.0 (resolves #530, potential #525, #518)

    Updated package dependencies for new SDKs (resolves #532)
    Android 12 (31) update (resolves #528)
    Android: FCM remove dialog displayed during isSupported call (resolves #527)

    2021.12.17 [v10.4.5]

    Fix missing dependencies from base air package (resolves #522)

    2021.12.15 [v10.4.4]

    Add air package parameter descriptions
    Correct issue with legacy FcmInstanceIDService inclusion in manifest (resolves #520)

    2021.10.18 [v10.4.3]

    Fix issue with authorisation event not being dispatched with OneSignal (resolves #507)

    2021.09.13 [v10.4.1]

    Added AIR Package currently the base version with 2 variants, (FCM and OneSignal)

    OneSignal SDK update:
    - iOS v3.7.0
    - Android v4.6.0

    Fixed error event that was incorrectly dispatched (resolves #496)

    2021.04.15 [v10.3.048]

    Corrected iOS deployment target which caused issues on iOS 9 (resolves #489)

    2021.04.06 [v10.3.046]

    Added setUserId and removeUserId to associate custom user identifiers (resolves #485)

    2021.02.08 [v10.2.043]

    Corrected missing OneSignal data fields (resolves #480)

    2021.02.03 [v10.2.039]

    OneSignal SDK update:
    - iOS v3.1.1
    - Android v4.1.0

    2021.01.20 [v10.1.025]

    Firebase SDK update:
    - iOS v7.4.0
    - Android v21.0.1

    Firebase In-App Messaging update:
    - iOS v7.4.0
    - Android v19.1.3

    Added in-app messaging dismissed event (resolves #475)

    2020.12.23 [v10.0.016]

    OneSignal: Added handling of group notifications (resolves #474)

    2020.12.02 [v10.0.013]

    Corrected documentation links and FirebaseInitProvider authority (resolves #470)

    2020.09.01 [v10.0.012]

    In-App Messaging implementations:
    - One Signal In-App Messaging (resolves #449)
    - Firebase In-App Messaging (resolves #408)

    OneSignal SDK update:
    - iOS v2.15.3
    - Android v3.15.3 (#375, #450)

    Firebase SDK update:
    - iOS v6.30.0 (resolves #386)
    - Android v20.2.4

    2020.08.14 [v9.3.231]

    OneSignal SDK update:
    - iOS v2.14.3
    - Android v3.15.1

    2020.05.25 [v9.2.222]

    FCM SDK update:
    - iOS v6.11.0
    - Android v20.1.6

    Azure SDK update:
    - iOS v2.0.4
    - Android v0.6

    2020.05.04 [v9.0.158]

    FCM
    - Android SDK update v20.1.6

    Fixed several issues around displaying and removing group notifications

    2020.04.20 [v9.0.155]

    OneSignal
    - Android SDK update v3.13.0 (resolves #430)
    - iOS SDK update v2.13.1

    Windows: Removed EventLog usage
    Windows: Added error checking on setBadgeNumber call

    2020.03.25 [v9.0.142]

    Android X migration (resolves #423)
    Firebase Cloud Messaging:
    - Android SDK: v20.1.2
    - iOS SDK: v6.2.0

    Windows implementation supporting Windows Notification Service

    Split Firebase ANE requirement for FCM into common dependency extension (resolves #421)
    iOS: Updated method of deviceToken retrieval for iOS 13 (resolves #398)

    2020.01.30 [v8.3.049]

    Improved Android sound handling now resources can be used with AIR 33 (resolves #387)

    2020.01.30 [v8.3.044]

    Added ability to request critical alerts (resolves #419)
    OneSignal
    - Android SDK update v3.12.5
    - iOS SDK update v2.12.5

    2019.12.11 [v8.2.023]

    Firebase Cloud Messaging:
    - iOS SDK update v6.2.0

    2019.11.02 [v8.1.020]

    OneSignal
    - Android SDK update v3.12.2 (resolves #401)
    - iOS SDK update v2.11.2

    2019.08.12 [v8.0.011]

    Android 64bit support (resolves #389)
    Updated minimum iOS version to 9.0
    OneSignal
    - Android SDK update v3.11.2
    - iOS SDK update v2.10.1
    Updated OneSignal Android Icon documentation (resolves #393)
    FCM: Respected default colour manifest setting for foreground notifications (resolves #374)
    OneSignal: corrected iOS init order fixing missing auth events (resolves #397)

    2019.04.16 [v7.9.301]

    OneSignal 
    - Android SDK update v3.10.7 (#375)
    - iOS SDK update v2.9.5

    2019.02.27 [v7.8.295]

    Updated minimum iOS version to 8.0 
    Embedded iOS bitcode

    2019.02.19 [v7.7.295]

    iOS: Corrected categories incorrectly being added (resolves #360)

    2019.02.01 [v7.7.286]

    OneSignal SDK Update: Android v3.10.6 iOS v2.9.5 (resolves #352)

    2018.11.27 [v7.7.284]

    Firebase Cloud Messaging:
    - Android SDK update v17.3.4
    - iOS SDK update v5.13.0

    Updated to Google Play Services v16.0.5
    Removed application keys

    2018.10.29 [v7.6.275]

    Android: Created specific file provider to avoid conflicts
    Removed application key requirement

    2018.10.19 [v7.6.272]

    Android: Corrected action cancel not closing notification panel (resolves #335)

    2018.09.14 [v7.6.270]

    OneSignal: Android: Added ability to use a packaged asset for sounds

    2018.09.06 [v7.6.263]

    Updated iOS FCM SDK to v5.6.0 (resolves #321)

    2018.08.11 [v7.6.262]

    OneSignal 
    - Android SDK update v3.10.1 (#317)
    - iOS SDK update v2.8.6

    2018.08.02 [v7.5.254]

    Android: Corrected setBadgeNumber for Android 8

    2018.07.04 [v7.5.253]

    OneSignal: Added setLocationShared to service for additional privacy controls (resolves #305) 
    OneSignal: iOS: Corrected enableNotificationsWhenActive (resolves #306)

    2018.06.10 [v7.5.248]

    Docs: Corrected FCM manifest additions (#151)
    Docs: Added information about colour in FCM payload (#300)
    Android: Added ability to set sound on a channel (resolves #298)

    2018.06.01 [v7.5.245]

    Updates:
    - Android: Implemented checks for enabled notifications and ability to open device settings (resolves #288)
    - One Signal User consent (resolves #294)

    Firebase Cloud Messaging:
    - Android SDK update v17.0.0
    - iOS SDK update v5.1.0

    OneSignal
    - User consent
    - Android SDK update v3.9.1
    - iOS SDK update v2.8.5
    - [migration guide](https://github.com/distriqt/ANE-PushNotifications/wiki/s.OneSignal---Migrating-to-v7.5)

    2018.04.17 [v7.4.227]

    Corrected manifest addition documentation for OneSignal (#284)

    2018.04.07 [v7.4.227]

    Implemented cancelAll for iOS (resolves #281)
    Added Tags for OneSignal (resolves #256)

    2018.03.15 [v7.4.219]

    Latest SDK updates and fixes:
    - Removed debug trace (resolves #270)

    Firebase Cloud Messaging:
    - Android SDK update v11.8.0
    - iOS SDK update v4.10.1 (#198)

    OneSignal:
    - Android SDK update v3.7.1
    - iOS SDK update v2.7.2
    - iOS removed dynamic framework requirement, now statically linked (#273)

    2018.02.14 [v7.3.193]

    Android 8.0 support - Added channels

    2017.12.18 [v7.2.187]

    Updated notification icon documentation
    Updated badge number documentation (resolves #249)
    Android: Added better handling of FCM display messages (resolves #257)

    2017.11.27 [v7.1.178]

    Better Emoji integration
    Additional context checks

    2017.10.31 [v7.0.176]

    Updated documentation

    2017.10.31 [v7.0.176]

    OneSignal Integration (resolves #159)

    2017.10.03 [v6.8.091]

    Corrected background image implementation for GCM (#239)

    2017.09.29 [v6.8.090]

    Removed Android 8 support while Adobe fix AIR SDK issue

    2017.09.19 [v6.8.083]

    Updated documentation for background image

    2017.09.19 [v6.8.082]

    Android 8.0: Notification Channels + Badges 
    Android: Added background image (resolves #239)

    2017.09.01 [v6.7.074]

    Updated documentation

    2017.09.01 [v6.7.074]

    Microsoft Azure Notification Hub implementation (resolves #227)
    Separated variants into directories
    Android: Implemented badge count from notification data (resolves #221)

    2017.08.04 [v6.6.031]

    Updated FCM SDK (Android v11.0.4, iOS v4.0.4)

    2017.07.10 [v6.5.028]

    Updated Android file paths

    2017.07.10 [v6.5.027]

    Updated FCM SDK (Android v11.0.2, iOS v4.0.3)
    FCM ability to subscribe to a topic (resolves #111)
    Android: Added setBadgeNumber for supported Android devices (resolves #141)
    iOS: Better handling of registration events (#213, #188)

    iOS 10: Centralisation of new notifications delegate (resolves #177, resolves #201, resolves #219)

    2017.06.16 [v6.4.006]

    Updated FCM iOS v4.0.2

    2017.06.10 [v6.4.005]

    Updated FCM to Android v11.0.0, iOS v4.0.1

    2017.06.10 [v6.4.005]

    Updated FCM to Android v11.0.0, iOS v4.0.1

    2017.05.31 [v6.3.047]

    Update to Firebase (FCM) SDK (Android v10.2.6, iOS v4.0.0)

    2017.05.02 [v6.2.044]

    Corrected accidental inclusion of debug config files (#208)

    2017.04.13 [v6.2.043]

    Correction for should cancel on action (resolves #203)

    2017.04.12 [v6.2.038]

    Android: Small fix for startup notifications

    2017.04.11 [v6.2.036]

    Corrected priority with GCM (#196)

    2017.04.06 [v6.2.033]

    Updated documentation

    2017.04.06 [v6.2.033]

    Android: Added ability to set the number of notifications in groupSummary (resolves #197)
    Android: Added ability to set priority for headsup notifications (resolves #196)
    Android: Corrected sound access permissions

    2017.03.23 [v6.2.028]

    iOS: Corrected inclusion of frameworks that would break app store submission

    2017.03.15 [v6.1.024]

    Android: Corrected FCM registration process (resolves #184)
    iOS: Added additional checks on authorisation status (resolves #185)

    2017.03.01 [v6.1.019]

    Android Update for Google Play Services v10.2.0

    2017.02.23 [v6.1.018]

    Updated Firebase iOS SDK to v3.13 (resolves #180)

    2017.02.08 [v6.1.014]

    Corrected issue displaying notifications from particular data (resolves #176)
    Android: Update to Google Play Services v10.0.1

    2017.01.30 [v6.1.012]

    Updated to Google Play Services v10.0.1

    2017.01.18 [v6.1.004]

    Updated documentation

    2017.01.18 [v6.1.004]

    Updated documentation

    2017.01.12 [v6.1.004]

    Updated documentation image links

    2017.01.12 [v6.1.004]

    Updated documentation to include service setup tutorials

    2016.12.30 [v6.1.004]

    New documentation

    2016.11.25 [v6.1.004]

    Added topic subscriptions
    Android: Updated to Play Services v9.8.0

    2016.11.23 [v6.0.034]

    iOS: Fixed issue with startup auth status being denied on iOS 10

    2016.10.28 [v6.0.031]

    iOS 10 update (resolves #145, resolves #142)
    Firebase Cloud Messaging (#130, resolves #70)

    2016.09.01 [v5.3.005]

    Added ability to open the application device settings (resolves #138)

    2016.08.02

    Updated far latest Google Play Services libraries

    2016.07.22

    iOS: Fixed issue with hideAneLibSymbols (resolves #133)

    2016.07.16

    Updated to be compatible with latest support ANEs (#123)

    2016.07.02

    Android: Corrected double notification issue on startup when register before activation
    Android: Added 'willLaunchApplication' option to actions to allow app to start

    2016.05.03

    iOS: Resolved conflicts with GameServices (resolves #104)

    2016.04.12

    iOS: Corrected authorisation status value

    2016.04.12

    iOS: Corrected authorisation status value

    2016.03.28

    Updated readme

    2016.03.28

    Complete refactor of the API to allow for future development
    Update registration method (resolves #69)
    Implemented Actions
    Implemented Expanded notifications
    Implemented Group notifications
    Custom icons (resolves #10, resolves #88)
    Background/silent notifications (resolves #76)

    2015.10.20

    Fix for error when no notification specified and application not running (resolves #67)

    2015.09.24

    iOS 9 updates (#57)

    2015.09.17

    Android: Added custom large notification icons (resolves #5)
    Android: Added custom notification sound (#5)
    Android: Added lights setting
    Android: Added a cancelAll function to remove notifications (resolves #40)
    Android: Added customisation of variable names to help integration with other platforms (eg OneSignal)

    2015.06.16

    Android: Windows: Fix for bug in AIR packager resulting in missing resources

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.03.16

    Android: Fix for incorrectly detecting manifest reciever (#28)

    2015.03.13

    Android: Corrected issue when no id supplied in payload

    2015.03.13

    Updated documentation

    2015.03.13

    Android: Corrected issue with wrong notification data being passed when multiple notifications have been displayed (resolves #24)

    2015.03.05

    Separated common app delegates into Core ANE to resolve conflicting ANEs issues

    2015.02.10

    Images for second tutorial

    2015.02.10

    Images for first tutorial

    2015.02.10

    Fixed issue with classes not importing correctly in FlashBuilder 4.6 (resolves #16)
    iOS: Permissions implementation to allow developer to display permission dialog at appropriate time (resolves #12)

    2015.02.03

    Added check for .debug suffix in application id

    2014.12.22

    iOS: Included arm64 support (resolves #3) 
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.17

    Added SELECTED notification event dispatched when the user selects a notification
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.08

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.01

    New application based key check, removing server checks

    01-11-14

    Added header image

    01-11-14

    Android: Addition to correctly handle an invalid id value
    - + \ No newline at end of file diff --git a/docs/pushnotifications/firebase/add-the-extension/index.html b/docs/pushnotifications/firebase/add-the-extension/index.html index ce6d0b551f2..8acf0645ca1 100644 --- a/docs/pushnotifications/firebase/add-the-extension/index.html +++ b/docs/pushnotifications/firebase/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -41,7 +41,7 @@ when you were setting up your application in the iOS developer center. The seed id should be a unique ten character string and the identifier should be similar to your AIR application id.

    note

    Note the difference between a development and production / adhoc entitlements. The get-task-allow and aps-environment must be set correctly for your build.

    These values must match the values in your provisioning profile, ie you must have setup push notifications for the matching environment.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/firebase/fcm-gcm-payload/index.html b/docs/pushnotifications/firebase/fcm-gcm-payload/index.html index 84d4a85576c..f41020eb9d7 100644 --- a/docs/pushnotifications/firebase/fcm-gcm-payload/index.html +++ b/docs/pushnotifications/firebase/fcm-gcm-payload/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ notifications implementation.

    This notification can only be processed when the application is in the foreground.

    This notification is the notification sent from the FCM console.

    Our notifications implementation uses the data field, within which you can either use a flat object or place our custom notification object within it. All our payloads in the documentation where meant to be placed in this part of the payload

    Similar to APNS, the simplest notification is an alert.

    {
    "data": {
    "notification" : {
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "The body of the notification",
    "sound" : "default"
    }
    }
    }

    Additional fields include:

    The following shows a complete json payload utilising all the features:

    {
    "data" : {
    "notification" : {
    "icon" : "ic_stat_distriqt_default",
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "The body of the notification",
    "sound" : "default",
    "vibrate": "true",
    "largeIcon": "assets/notifications/icons/largeIcon.png",
    "priority": "0",
    "badge": 2,
    "colour": "#FF0000",

    "channel" : "channel_id",

    "backgroundImage" : "assets/notifications/background.png",
    "backgroundImageTextColour" : "#FFFFFF",

    "style": {
    "type": "text",
    "text": "Some longer and larger content that will be used for a text style big view.\n\nThe body content will be shown in the normal view, but this content will be shown in the expanded view. ",
    "lines": [
    "Inbox message line 1",
    "Inbox message line 2"
    ],
    "image":"http://example.com/path/to/image.png"
    },

    "groupIcon": "ic_stat_distriqt_default",
    "groupKey" : "groupKey",
    "groupTitle": "You have %d notifications",
    "groupSummary": "Message displayed at bottom of notifications",

    "category": "INVITE_CATEGORY"
    },

    "user_custom": "some-custom-value"
    }
    }

    Background Image

    On Android v5.0 + you can use an image as the background of the notification.

    As part of your payload add the backgroundImage field which is either a path to a local asset packaged with your application or a url to a public image. URL's are discouraged due to the network access and download required.

    In order to cover all notification sizes this image should be sized 2600x256 (91.4:9) and this will be aligned top left.

    You can also add the backgroundImageTextColour field which you can use to specify the text colour. This allows you to match the colour of the text to your image.

    Colour supported formats are:

    Note: Setting the background image of a notification will remove the notification icon and large icon. If you need to display these you should add them to your image.

    The following names are also accepted: red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray, darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy, olive, purple, silver, and teal.

    Example

    The following example uses an asset as the background packaged with the application located at 'assets/notifications/background.png':

    {
    "data": {
    "notification" : {
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "The body of the notification",
    "sound" : "default",
    "backgroundImage" : "assets/notifications/background.png",
    "backgroundImageTextColour" : "#FFFFFF"
    }
    }
    }
    - + \ No newline at end of file diff --git a/docs/pushnotifications/firebase/firebase-cloud-message/index.html b/docs/pushnotifications/firebase/firebase-cloud-message/index.html index 4db6ee7c0dd..8126c089a15 100644 --- a/docs/pushnotifications/firebase/firebase-cloud-message/index.html +++ b/docs/pushnotifications/firebase/firebase-cloud-message/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Firebase Cloud Message

    Sending a message with Firebase is very similar (if not exactly the same) as GCM apart from the endpoint.

    Firebase Cloud Messaging has a server-side APIs that you can call to send messages. See https://firebase.google.com/docs/cloud-messaging/server.

    Sending a message can be as simple as using curl to call a HTTP end-point. See https://firebase.google.com/docs/cloud-messaging/server#implementing-http-connection-server-protocol

    curl -X POST --header "Authorization: key=<API_ACCESS_KEY>" --Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"<YOUR_DEVICE_ID_TOKEN>\",\"notification\":{\"body\":\"Yellow\"},\"priority":10}"

    PHP Example

    Simple PHP script demonstrating the same:

    $registrationId = "YOUR_DEVICE_ID_TOKEN";
    $apiKey = "API_ACCESS_KEY";

    $dataPayload = array(
    'notification' => array(
    'icon' => 'ic_utrofi_notification',
    'alert' => "ticker text 2",
    'title' => "content title 2",
    'body' => "body copy 2",
    'sound' => 'default'
    ));

    $response = sendNotification(
    $apiKey,
    array($registrationId),
    $dataPayload,
    null
    );
    echo $response;


    ////////////////////////////////////////////////////////////////////////////////
    //
    //

    /**
    * The following function will send a FCM notification using curl.
    *
    * @param $apiKey [string] The Browser API key string for your GCM account
    * @param $registrationIdsArray [array] An array of registration ids to send this notification to
    * @param $messageData [array] An named array of data to send as the notification payload
    */
    function sendNotification( $apiKey, $registrationIdsArray, $customData, $notification )
    {
    $headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey);
    $data = array(
    'registration_ids' => $registrationIdsArray,
    );
    if ($customData != null) $data['data'] = $customData;
    if ($notification != null) $data['notification'] = $notification;

    $post = json_encode($data);

    print( $post );

    $ch = curl_init();

    curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    curl_setopt( $ch, CURLOPT_URL, "https://fcm.googleapis.com/fcm/send" );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $post );

    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
    }


    - + \ No newline at end of file diff --git a/docs/pushnotifications/firebase/firebase-cloud-messaging/index.html b/docs/pushnotifications/firebase/firebase-cloud-messaging/index.html index 088b042d658..f77d489fdfc 100644 --- a/docs/pushnotifications/firebase/firebase-cloud-messaging/index.html +++ b/docs/pushnotifications/firebase/firebase-cloud-messaging/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Setup

    You should firstly setup a Firebase project for your application. See the documentation to Create a Firebase Project.

    Once complete you need to grab the configuration files for your application and add these to your application.

    This should include:

    • iOS: GoogleService-Info.plist
    • Android: values.xml

    See more on adding these configuration files here

    iOS

    Firebase on iOS uses APNS certificates and APNS notifications to deliver messages. So you'll need to go through the process of setting up your APNS certificates and enabling APNS for your application.

    Once you have setup your APNS certificates you must add them to your Firebase application. Navigate to your application and click on settings, then the "Cloud Messaging" tab and upload your certificates.

    You can find more information on setting up the certificates in the Firebase documentation.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/firebase/firebase-inapp-messaging/index.html b/docs/pushnotifications/firebase/firebase-inapp-messaging/index.html index 97cc840444a..b0dbe9ff6aa 100644 --- a/docs/pushnotifications/firebase/firebase-inapp-messaging/index.html +++ b/docs/pushnotifications/firebase/firebase-inapp-messaging/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Firebase InApp Messaging

    Firebase In-App Messaging helps you engage your app's active users by sending them targeted, contextual messages that encourage them to use key app features. For example, you could send an in-app message to get users to subscribe, watch a video, complete a level, or buy an item. You can customize messages as cards, banners, modals, or images, and set up triggers so that they appear exactly when they'd benefit your users most.

    Use Firebase In-App Messaging to encourage exploration and discovery: highlight a sale or coupon in your ecommerce app, give clues or tips in your game, or prompt a like or share in your social media app.

    This is now included in the main Firebase Cloud Messaging guide.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/gcm/google-cloud-message/index.html b/docs/pushnotifications/gcm/google-cloud-message/index.html index baab64cc3c0..bc6b796b33b 100644 --- a/docs/pushnotifications/gcm/google-cloud-message/index.html +++ b/docs/pushnotifications/gcm/google-cloud-message/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Google Cloud Message

    There are many ways to send notifications to your devices.

    The basic procedure is once your application has sent the device token (registration id) to your server, your server will send a message to the appropriate service (APNS/GCM) which will deliver the notification to the registered device.

    PHP Example

    The following is a very basic PHP example, sending a message to a single device.

    <?php
    /**
    * This is a test script to send a message to an GCM Android device, i.e. an Android device using Google Cloud Messaging.
    *
    * To use this script you need to set the following pieces of information
    * - device registration id
    * - api key (this is the browser API key)
    *
    * Then run it using php:
    * <code> php gcm_simplepush.php </code>
    *
    */
    // Put your device token here (without spaces):
    $registrationId = 'DEVICE_ID';
    // GCM API Key
    $apiKey = "GCM_API_KEY";

    $dataPayload = array(
    'notification' => array(
    'icon' => 'ic_stat_distriqt_default',
    'alert' => 'You have a notification',
    'title' => 'You have a notification',
    'body' => "The body of the notification",
    'sound' => 'default',
    'vibrate' => 'true',
    ),
    'user_custom' => 'some-custom-value'
    );

    $response = sendNotification(
    $apiKey,
    array($registrationId),
    $dataPayload,
    null
    );

    echo $response;
    echo "\ncomplete...\n";
    ////////////////////////////////////////////////////////////////////////////////
    //
    //
    /**
    * The following function will send a GCM notification using curl.
    *
    * @param $apiKey [string] The Browser API key string for your GCM account
    * @param $registrationIdsArray [array] An array of registration ids to send this notification to
    * @param $messageData [array] A named array of data to send as the notification data payload
    * @param $notification [array] A named array of data to send as the notification information
    */
    function sendNotification( $apiKey, $registrationIdsArray, $customData, $notification )
    {
    print_r($messageData);
    print_r($registrationIdsArray);
    $headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey);
    $data = array(
    'registration_ids' => $registrationIdsArray,
    );
    if ($customData != null) $data['data'] = $customData;
    if ($notification != null) $data['notification'] = $notification;
    $post = json_encode($data);

    print( $post );
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    curl_setopt( $ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send" );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $post );
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
    }

    Source gist

    You run these scripts using php:

    php script.php
    - + \ No newline at end of file diff --git a/docs/pushnotifications/gcm/google-cloud-messaging/index.html b/docs/pushnotifications/gcm/google-cloud-messaging/index.html index 7582c38e952..6a6156cd9e3 100644 --- a/docs/pushnotifications/gcm/google-cloud-messaging/index.html +++ b/docs/pushnotifications/gcm/google-cloud-messaging/index.html @@ -13,7 +13,7 @@ - + @@ -67,7 +67,7 @@ It is important here that you use the full application ID with the air. prefix (unless you are removing this during your packaging) as this will be your actual application package name in the Android system.

    It will be of the form air.com.distriqt.test

    If any other of our ANEs require the FileProvider only add one of the references. The file provider will be shared amongst our extensions.

    <manifest android:installLocation="auto">
    <uses-sdk android:minSdkVersion="19" />

    <uses-permission android:name="android.permission.INTERNET"/>

    <!-- OPTIONAL -->
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <!-- GCM PERMISSIONS -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <!-- Only this application can receive the messages and registration result -->
    <permission android:name="APPLICATION_PACKAGE.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="APPLICATION_PACKAGE.permission.C2D_MESSAGE" />

    <application>
    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

    <receiver
    android:name="com.google.android.gms.gcm.GcmReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <category android:name="APPLICATION_PACKAGE" />
    </intent-filter>
    </receiver>
    <service
    android:name="com.distriqt.extension.pushnotifications.gcm.GcmListenerService"
    android:exported="false" >
    <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
    </service>
    <service
    android:name="com.distriqt.extension.pushnotifications.gcm.InstanceIDListenerService"
    android:exported="false">
    <intent-filter>
    <action android:name="com.google.android.gms.iid.InstanceID" />
    </intent-filter>
    </service>
    <service android:name="com.distriqt.extension.pushnotifications.gcm.RegistrationIntentService" android:exported="false" />

    <activity android:name="com.distriqt.extension.pushnotifications.PushNotificationsActivity">
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_DEFAULT" />
    <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    </activity>



    <!-- NOTIFICATIONS -->
    <receiver android:name="com.distriqt.extension.pushnotifications.notifications.receivers.NotificationReceiver">
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_SELECTED" />
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_DELETED" />
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION" />
    <data android:scheme="dtpn" />
    </intent-filter>
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
    </receiver>
    <provider
    android:name="com.distriqt.extension.pushnotifications.content.FileProvider"
    android:authorities="APPLICATION_PACKAGE.pushnotificationsfileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_pushnotifications_paths" />
    </provider>



    </application>

    </manifest>

    MultiDex Applications

    If you have a large application and are supporting Android 4.x then you will need to ensure you enable your application to correctly support MultiDex to allow the application to be broken up into smaller dex packages.

    This is enabled by default with releases of AIR v25+, except in the Android 4.x case where you need to change the manifest additions for the application tag to match the following and use the MultiDexApplication.

    Using AndroidX

    This will require the addition of the androidx.multidex extension which contains the androidx.multidex.MultiDexApplication implementation.

    <manifest android:installLocation="auto">
    <!-- PERMISSIONS -->

    <application android:name="androidx.multidex.MultiDexApplication">

    <!-- ACTIVITIES / RECEIVERS / SERVICES -->

    </application>
    </manifest>
    - + \ No newline at end of file diff --git a/docs/pushnotifications/handling-startup-notifications/index.html b/docs/pushnotifications/handling-startup-notifications/index.html index c05b21fd51f..245f20f56b4 100644 --- a/docs/pushnotifications/handling-startup-notifications/index.html +++ b/docs/pushnotifications/handling-startup-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ This may occur if your application was not running, or a notification triggered the startup of your application.

    To make sure you handle them correctly, have all your event listeners registered before calling register. There may be multiple PushNotificationEvent.NOTIFICATION events, and PushNotificationEvent.ACTION events.

    However there will only ever be one selected event, either PushNotificationEvent.NOTIFICATION_SELECTED or PushNotificationGroupEvent.GROUP_SELECTED. The selected event should be treated as a user interaction and you should load the appropriate view in your application.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/icons/index.html b/docs/pushnotifications/icons/index.html index 02c012c5ab5..a858df0d354 100644 --- a/docs/pushnotifications/icons/index.html +++ b/docs/pushnotifications/icons/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Icons

    Notification icons refer to the image displayed in the notification center alongside the title, message and any other content associated with the notification.

    At a minimum all notifications consist of an icon and body text.

    iOS

    On iOS the icon is always your application icon. You do not need to do anything additional, just ensure your application has all the required application icon sizes.

    Android

    On Android the icon is provided through Android resources and you cannot use your AIR application icon (except on much older versions of Android). This icon must be white and transparent to fit with the Android design guidelines, and will be used in various positions within the Android UI.

    By default our extension will use a "bell" icon if you don't provide an icon resources yourself. In some circumstances you may see a white square. This is the Android attempt at using your application icon as the notification icon and is converting your icon based on whether a pixel is transparent or white.

    To add your own icon you will need to create your custom resources and then package them into an ANE in your AIR application. To generate these resources goto the Android Asset Studio Notification Icon Generator and upload your source image.

    Take note of the name of the icon. You will be using this name to reference this icon in notifications. Create as many different icons as you will require. These icons can be used for notification actions as well as for the main notification icon. You can use different icons for different notifications if you wish.

    Notification Bar with custom resource

    Custom resource icon in simple notification

    To create your own custom resources ANE have a look at the opensource script we have created:

    If you have troubles running this script simply send us your resources and we will create the extension for you.

    Special Resources

    We suggest you supply a default icon resource named ic_stat_distriqt_default. This icon will be used in situations where you don't supply an icon name for a notification. This will ensure all your notifications are correctly displayed.

    Note: With the OneSignal service it does not use our notification system and hence will not utilise the ic_stat_distriqt_default default icon resource. Instead you should supply a default icon resource named ic_stat_onesignal_default. This icon will be used in the same situations as the ic_stat_distriqt_default for the OneSignal service.

    If you don't supply a default icon, then you must ensure all your notifications have an icon property or you will get the default "bell" icon.

    Order of Display

    Our extension uses the following order of preference when displaying an icon. If any aren't available or the version of Android doesn't match then the next in the list is attempted.

    • custom icon resource (property in payload)
    • default icon resource
      • OneSignal: ic_stat_onesignal_default
      • All other services: ic_stat_distriqt_default
    • bell icon on newer Android versions (Lollipop or newer)
    • application icon on older Android versions

    Large Icons

    If you wish to use colour or a more detailed image for your notification you can use the "large icon" to display any image in place of the notification icon in the notification center. Your notification icon will still be displayed in the bar and overlayed on top of the large icon.

    For example, in the image below we have used a red cloud in a circle as the large icon and you will see the distriqt logo as our notification icon.

    This icon is not a resource but an image either packaged with your application or downloaded from a url. We don't suggest using a url unless absolutely neccessary, as a user may not get notifications if the image fails to download correctly or the device is offline for any reason. It can also delay the notification while the image is downloaded.

    Firebase Notes

    With Firebase Cloud Messaging you may use the console to send messages as opposed to the API. The notifications created from these messages aren't displayed using our notification creation logic but internal to Firebase.

    In order for you to specify the icon correctly in these situations you need to add the following to your manifest inside your application tag.

    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_distriqt_default" />
    <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/black" />
    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="default_channel_id" />

    This will direct Firebase to use the same default icon as other notifications, however you can change the resource in the default_notification_icon to any that you require.

    Note: If you receive a missing resource error when packaging, make sure you have correctly specified the name of your resource for the default_notification_icon.

    Some other values for the notification colour include (with their coresponding ARGB hex codes):

    • @color/white: #FFFFFFFF
    • @color/black: #FF000000
    • @color/blue: #FF33B5E5
    • @color/purple: #FFAA66CC
    • @color/green: #FF99CC00
    • @color/orange: #FFFFBB33
    • @color/red: #FFFF4444
    • @color/darkblue: #FF0099CC
    • @color/darkpurple: #FF9933CC
    • @color/darkgreen: #FF669900
    • @color/darkorange: #FFFF8800
    • @color/darkred: #FFCC0000

    You can also add a colour to a resource and add it as part of your custom resources. Contact us if you need help with this.

    OneSignal Notes

    With OneSignal it is important that you provide a resource named ic_stat_onesignal_default as a default icon for your notifications.

    You can read more on OneSignal Android Notification Icons here: https://documentation.onesignal.com/docs/customize-notification-icons

    - + \ No newline at end of file diff --git a/docs/pushnotifications/inapp-messaging/index.html b/docs/pushnotifications/inapp-messaging/index.html index c1540613fdd..5d94086e2ef 100644 --- a/docs/pushnotifications/inapp-messaging/index.html +++ b/docs/pushnotifications/inapp-messaging/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    InApp Messaging

    In-App Messaging helps you engage your app's active users by sending them targeted, contextual messages that encourage them to use key app features.

    This messaging approach doesn't push notifications to the device, instead they are displayed at certain contextual moments in your application.

    They generally are highly customisable and importantly they don't rely on push notification authorisation so you can send these messages to devices that have denied push notifications.

    The In-App Messaging functionality is provided through the InAppMessaging singleton accessed via PushNotifications.service.inAppMessaging.

    Setup

    You must setup your service before attempting to access In-App Messaging. Any attempts to access it before calling setup will fail.

    Support

    Note: Only some services support In-App Messaging and generally require additional setup to the main push notification service. Check the documentation for the services to confirm that this is supported and that you have performed any additional integration steps.

    You can check whether the current service supports InApp Messaging by checking the isSupported flag:

    if (PushNotifications.service.inAppMessaging.isSupported)
    {
    // Current service supports In-App Messaging
    }

    Handle User Interaction

    The most important step is listening to the InAppMessagingEvent.SELECTED event that is dispatched whenever a user interacts with an In-App Message.

    PushNotifications.service.inAppMessaging.addEventListener( 
    InAppMessagingEvent.SELECTED,
    selectedHandler
    );

    This event will contain details about the In-App Message that the user interacted with. We suggest you add this event listener early in your application, immediately after setting up your application.

    There are two main pieces of data attached to this event:

    • action: A InAppMessageAction instance containing common In-App Message information representing the user's action (eg the button they clicked). In-App Message services generally include a name for the action (this can be the text on the button or a name associated with the action) and a url as a payload for the action.
    • data: An Object instance containing service specific data associated with the message. The content here depends on the service but will contain any additional information that the service provides. For example, with Firebase In-App Messaging this will contain the campaign name, campaign information and message type.
    function inappmessaging_selectedHandler( event:InAppMessagingEvent ):void
    {
    trace( "inappmessage selected" );
    trace( " action: " + event.action.name + ":" + event.action.url );
    trace( " data: " + event.data == null ? "null" : JSON.stringify(event.data) );
    }

    Trigger in-app messages programmatically

    Some services will allow you to trigger events programmatically when certain events occur in your application.

    You trigger these events in your application by calling the addTrigger() method and passing the appropriate event name for your service defined trigger and a value string (if applicable).

    PushNotifications.service.inAppMessaging
    .addTrigger( "exampleTrigger", "optional value" );

    Note: Services that don't support this process with return false

    var success:Boolean = PushNotifications.service.inAppMessaging.addTrigger( "exampleTrigger" );
    if (!success)
    {
    // manual event triggering not supported
    }

    Temporarily disable in-app messages

    By default, In-App Messaging renders messages whenever a triggering condition is satisfied, regardless of an app's current state. If you'd like to suppress message displays for any reason, for example to avoid interrupting a sequence of payment processing screens, you can do that with the SDK's messageDisplaySuppressed() method:

    PushNotifications.service.inAppMessaging.messageDisplaySuppressed( true );

    Passing true to the method prevents In-App Messaging from displaying messages, while false reenables message display.

    Note: Services that don't support this process with return false

    Enable opt-out message delivery

    - + \ No newline at end of file diff --git a/docs/pushnotifications/index.html b/docs/pushnotifications/index.html index f279dd78976..729f8a0a622 100644 --- a/docs/pushnotifications/index.html +++ b/docs/pushnotifications/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ that get processed into a notification on Android, allowing deep integration with other messaging platforms, such as OneSignal.

    The simple extension API will have you quickly up and running with remote notifications.

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Features

    Supported services

    This Wiki forms the best source of detailed documentation for the extension along with the asdocs.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/migrating-to-androidx/index.html b/docs/pushnotifications/migrating-to-androidx/index.html index 7fcb140cfa5..4d842d96d63 100644 --- a/docs/pushnotifications/migrating-to-androidx/index.html +++ b/docs/pushnotifications/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/migrating-to-v10.1/index.html b/docs/pushnotifications/migrating-to-v10.1/index.html index 3da3e6ee5c1..6d37f95545b 100644 --- a/docs/pushnotifications/migrating-to-v10.1/index.html +++ b/docs/pushnotifications/migrating-to-v10.1/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v10.1

    v10.1 brings the latest Firebase SDK which requires some changes to your application. Other services remain unchanged at this point.

    Firebase Cloud Messaging

    Firebase cloud messaging has been updated to v21.0.1 (android) and v7.4.0 (iOS). Firebase in-app messaging to version v19.1.3 (Android) and v7.4.0 (iOS).

    This requires the following updates for Android:

    • Addition of com.distriqt.playservices.CloudMessaging dependency;
    • Changes to the manifest additions for the ComponentDiscoveryService, mainly the inclusion of the DynamicLoadingRegistrar. We recommend carefully going through the manifest additions again to ensure your additions are correct:

    No changes are necessary for iOS.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/migrating-to-v10.2/index.html b/docs/pushnotifications/migrating-to-v10.2/index.html index 84762a4e979..dbff30d01e0 100644 --- a/docs/pushnotifications/migrating-to-v10.2/index.html +++ b/docs/pushnotifications/migrating-to-v10.2/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v10.2

    v10.2 brings the latest release of OneSignal:

    • Android v4.1.0
    • iOS v3.1.1

    If you are updating from a version < 10 make sure you check out the changes for Firebase Cloud Messaging as well in the Migrating to v10.1

    We have managed to hide any major implementation changes within the native code however there are some changes to the dependencies, to the manifest additions and to the payload data structure.

    Payload

    Payload

    The payload structure has changed due to a change in the data returned by OneSignal for a notification. Rather than reformatting to matching a legacy structure we have taken the approach to return the data as per OneSignal's design.

    Importantly you will need to update any code you have that relies on the structure of the OneSignal notification payload.

    For example on Android the previous payload structure was:

    {
    "isAppInFocus":true,
    "shown":false,
    "androidNotificationId":0,
    "displayType":0,
    "payload": {
    "notificationId":"bb5fd966-4ac2-4070-bcec-d66fb0fbab1f",
    "title":"asdf",
    "body":"asdfasdf",
    "additionalData":{

    },
    "lockScreenVisibility":1,
    "actionButtons":[

    ],
    "fromProjectNumber":"616489336300",
    "priority":5,
    "rawPayload":"{\"google.delivered_priority\":\"normal\",\"google.sent_time\":1612744363074,\"google.ttl\":259200,\"google.original_priority\":\"normal\",\"custom\":\"{\\\"i\\\":\\\"bb5fd966-4ac2-4070-bcec-d66fb0fbab1f\\\",\\\"a\\\":{\\\"actionButtons\\\":[],\\\"actionId\\\":\\\"__DEFAULT__\\\"}}\",\"pri\":\"5\",\"vis\":\"1\",\"from\":\"616489336300\",\"alert\":\"asdfasdf\",\"title\":\"asdf\",\"google.message_id\":\"0:1612744363095757%32d7332ff9fd7ecd\",\"google.c.sender.id\":\"616489336300\"}"
    }
    }

    The new payload structure is:

    {
    "androidNotificationId":0,
    "groupedNotifications":[

    ],
    "notificationId":"bb5fd966-4ac2-4070-bcec-d66fb0fbab1f",
    "templateName":"",
    "templateId":"",
    "title":"asdf",
    "body":"asdfasdf",
    "lockScreenVisibility":1,
    "fromProjectNumber":"616489336300",
    "priority":5,
    "additionalData":{

    },
    "actionButtons":[

    ],
    "rawPayload":"{\"google.delivered_priority\":\"normal\",\"google.sent_time\":1612744363074,\"google.ttl\":259200,\"google.original_priority\":\"normal\",\"custom\":\"{\\\"i\\\":\\\"bb5fd966-4ac2-4070-bcec-d66fb0fbab1f\\\",\\\"a\\\":{\\\"actionButtons\\\":[],\\\"actionId\\\":\\\"__DEFAULT__\\\"}}\",\"pri\":\"5\",\"vis\":\"1\",\"from\":\"616489336300\",\"alert\":\"asdfasdf\",\"title\":\"asdf\",\"google.message_id\":\"0:1612744363095757%32d7332ff9fd7ecd\",\"google.c.sender.id\":\"616489336300\"}"
    }

    Update Dependencies

    You need to ensure you have the following extensions in your application. There are several new extensions included here, and please ensure you have updated all the dependencies to the same releases:

    • com.distriqt.Core
    • com.distriqt.playservices.Base
    • com.distriqt.playservices.AdsIdentifier
    • com.distriqt.playservices.CloudMessaging
    • com.google.firebase.core
    • com.google.android.datatransport
    • com.google.dagger
    • com.google.guava
    • androidx.appcompat
    • androidx.browser
    • androidx.cardview
    • androidx.core
    • androidx.recyclerview
    • androidx.room
    • androidx.vectordrawable
    • androidx.work
    • com.jetbrains.kotlin

    See Add Required ANEs for more information.

    Update Manifest Additions

    We suggest removing any OneSignal references in your manifest and adding the following. The changes have been significant!

    You must replace APPLICATION_PACKAGE with your AIR application's Java package name, something like air.com.distriqt.test.

            <!-- ONE SIGNAL -->
    <meta-data android:name="com.onesignal.NotificationServiceExtension" android:value="com.distriqt.extension.pushnotifications.onesignal.NotificationServiceExtension" />

    <receiver
    android:name="com.onesignal.FCMBroadcastReceiver"
    android:permission="com.google.android.c2dm.permission.SEND" >

    <!-- High priority so OneSignal payloads can be filtered from other FCM receivers -->
    <intent-filter android:priority="999" >
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <category android:name="APPLICATION_PACKAGE" />
    </intent-filter>
    </receiver>

    <service
    android:name="com.onesignal.HmsMessageServiceOneSignal"
    android:exported="false" >
    <intent-filter>
    <action android:name="com.huawei.push.action.MESSAGING_EVENT" />
    </intent-filter>
    </service>

    <activity
    android:name="com.onesignal.NotificationOpenedActivityHMS"
    android:noHistory="true"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" >
    <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    </intent-filter>
    </activity>

    <service android:name="com.onesignal.FCMIntentService" />
    <service
    android:name="com.onesignal.FCMIntentJobService"
    android:permission="android.permission.BIND_JOB_SERVICE" />
    <service
    android:name="com.onesignal.FocusDelaySyncService"
    android:stopWithTask="true" />
    <service
    android:name="com.onesignal.FocusDelaySyncJobService"
    android:permission="android.permission.BIND_JOB_SERVICE" />
    <service
    android:name="com.onesignal.SyncService"
    android:stopWithTask="true" />
    <service
    android:name="com.onesignal.SyncJobService"
    android:permission="android.permission.BIND_JOB_SERVICE" />

    <activity
    android:name="com.onesignal.PermissionsActivity"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />

    <receiver android:name="com.onesignal.NotificationDismissReceiver" />
    <receiver android:name="com.onesignal.BootUpReceiver" >
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
    </receiver>
    <receiver android:name="com.onesignal.UpgradeReceiver" >
    <intent-filter>
    <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
    </receiver>

    <activity
    android:name="com.onesignal.NotificationOpenedReceiver"
    android:noHistory="true"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />

    <!--
    FirebaseMessagingService performs security checks at runtime,
    but set to not exported to explicitly avoid allowing another app to call it.
    -->
    <service
    android:name="com.google.firebase.messaging.FirebaseMessagingService"
    android:exported="false" >
    <intent-filter android:priority="-500" >
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
    </service>


    <!-- FIREBASE CORE -->
    <!-- common -->
    <service
    android:name="com.google.firebase.components.ComponentDiscoveryService"
    android:directBootAware="true"
    android:exported="false" >
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.iid.Registrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    </service>
    <provider
    android:name="com.google.firebase.provider.FirebaseInitProvider"
    android:authorities="APPLICATION_PACKAGE.firebaseinitprovider"
    android:exported="false"
    android:initOrder="100" />


    <!-- iid -->
    <receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
    </receiver>


    <!-- androidx.work -->
    <provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="APPLICATION_PACKAGE.workmanager-init"
    android:directBootAware="false"
    android:exported="false"
    android:multiprocess="true" />

    <service
    android:name="androidx.work.impl.background.systemalarm.SystemAlarmService"
    android:directBootAware="false"
    android:enabled="@bool/enable_system_alarm_service_default"
    android:exported="false" />
    <service
    android:name="androidx.work.impl.background.systemjob.SystemJobService"
    android:directBootAware="false"
    android:enabled="@bool/enable_system_job_service_default"
    android:exported="true"
    android:permission="android.permission.BIND_JOB_SERVICE" />
    <service
    android:name="androidx.work.impl.foreground.SystemForegroundService"
    android:directBootAware="false"
    android:enabled="@bool/enable_system_foreground_service_default"
    android:exported="false" />

    <receiver
    android:name="androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"
    android:directBootAware="false"
    android:enabled="true"
    android:exported="false" />
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy"
    android:directBootAware="false"
    android:enabled="false"
    android:exported="false" >
    <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy"
    android:directBootAware="false"
    android:enabled="false"
    android:exported="false" >
    <intent-filter>
    <action android:name="android.intent.action.BATTERY_OKAY" />
    <action android:name="android.intent.action.BATTERY_LOW" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy"
    android:directBootAware="false"
    android:enabled="false"
    android:exported="false" >
    <intent-filter>
    <action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
    <action android:name="android.intent.action.DEVICE_STORAGE_OK" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy"
    android:directBootAware="false"
    android:enabled="false"
    android:exported="false" >
    <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver"
    android:directBootAware="false"
    android:enabled="false"
    android:exported="false" >
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.TIME_SET" />
    <action android:name="android.intent.action.TIMEZONE_CHANGED" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
    android:directBootAware="false"
    android:enabled="@bool/enable_system_alarm_service_default"
    android:exported="false" >
    <intent-filter>
    <action android:name="androidx.work.impl.background.systemalarm.UpdateProxies" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.diagnostics.DiagnosticsReceiver"
    android:directBootAware="false"
    android:enabled="true"
    android:exported="true"
    android:permission="android.permission.DUMP" >
    <intent-filter>
    <action android:name="androidx.work.diagnostics.REQUEST_DIAGNOSTICS" />
    </intent-filter>
    </receiver>

    <!-- com.google.android.datatransport -->
    <service
    android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery"
    android:exported="false" >
    <meta-data
    android:name="backend:com.google.android.datatransport.cct.CctBackendFactory"
    android:value="cct" />
    </service>
    <service
    android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService"
    android:exported="false"
    android:permission="android.permission.BIND_JOB_SERVICE" >
    </service>

    <receiver
    android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"
    android:exported="false" />

    <service
    android:name="androidx.room.MultiInstanceInvalidationService"
    android:directBootAware="true"
    android:exported="false" />

    For more information see the detail in the Manifest Additions section.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/migrating-to-v11.2/index.html b/docs/pushnotifications/migrating-to-v11.2/index.html index c76730b93cd..905fd5743cd 100644 --- a/docs/pushnotifications/migrating-to-v11.2/index.html +++ b/docs/pushnotifications/migrating-to-v11.2/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v11.2

    v11.2 brings the latest release of OneSignal:

    • Android v4.8.3
    • iOS v3.12.3

    It also includes the new notification permissions for Android 13+.

    OneSignal Frameworks

    OneSignal now requires usage of dynamic frameworks. You will need to ensure you include the Frameworks folder in the appropriate place in your application. If using apm simply add the assets/ios folder contents to be packaged at the root of your application. If not, download the frameworks from the repository and place them in a Frameworks folder at the root of your application.

    See the OneSignal "Add the extension" documentation for more details.

    Android 13 (API 33) Permissions

    With Android 13 comes a new runtime user permission required to present a user with notifications.

    If you do not update your users will be presented with the permission notification on launch of your application.

    Authorisation process follows exactly the same code you have used for iOS and from a developer perspective no changes are needed, except that you need to handle a SHOULD_EXPLAIN case for Android, similar to other permissions.

    See the documentation on requesting authorisation for more information.

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/pushnotifications/migrating-to-v11.3/index.html b/docs/pushnotifications/migrating-to-v11.3/index.html index 7824bc1340c..aa4db18bf7f 100644 --- a/docs/pushnotifications/migrating-to-v11.3/index.html +++ b/docs/pushnotifications/migrating-to-v11.3/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v11.3

    v11.3 brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/pushnotifications/migrating-to-v13.0/index.html b/docs/pushnotifications/migrating-to-v13.0/index.html index 8e0fd1685c3..efdcbeffdf8 100644 --- a/docs/pushnotifications/migrating-to-v13.0/index.html +++ b/docs/pushnotifications/migrating-to-v13.0/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to v13.0

    v13.0 separates out some firebase dependencies in order that other services can be used in preference.

    This means that to update to v13.0 you need to add the com.google.firebase.messaging extension as a dependency to your application.

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/pushnotifications/notification-scenarios/index.html b/docs/pushnotifications/notification-scenarios/index.html index f95f48d9725..0ee42aa5da0 100644 --- a/docs/pushnotifications/notification-scenarios/index.html +++ b/docs/pushnotifications/notification-scenarios/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Notification Scenarios

    Foreground, background - Notification Scenarios

    While we have made all possible efforts to make the platforms the same there are very different methodologies taken by the different operating systems which will affect the details of when and if notifications will arrive.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/add-the-extension/index.html b/docs/pushnotifications/onesignal/add-the-extension/index.html index 92f262af949..5273bf81fe2 100644 --- a/docs/pushnotifications/onesignal/add-the-extension/index.html +++ b/docs/pushnotifications/onesignal/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -37,7 +37,7 @@ The seed id should be a unique ten character string and the identifier should be similar to your AIR application id.

    Android

    Firstly make sure you have generated your Google Service API Key. You can follow the guide by OneSignal:

    Manifest Additions

    You must add all the OneSignal related manifest additions along with several additions for Cloud Messaging. This includes all the manifest additions required for Firebase core / analytics implementation.

    The following shows the complete manifest additions node. You must replace APPLICATION_PACKAGE with your AIR application's Java package name, something like APPLICATION_PACKAGE. Generally this is your AIR application id prefixed by air. unless you have specified no air flair in your build options.

    <manifest android:installLocation="auto">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <permission android:name="APPLICATION_PACKAGE.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
    android:protectionLevel="signature" />
    <uses-permission android:name="APPLICATION_PACKAGE.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission
    android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission android:name="APPLICATION_PACKAGE.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
    <uses-permission android:name="APPLICATION_PACKAGE.permission.C2D_MESSAGE" />
    <!-- BADGE -->
    <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
    <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" />
    <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
    <uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE" />
    <uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT" />
    <uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE" />
    <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
    <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_APP_BADGE" />
    <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS" />
    <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ" />
    <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE" />
    <!-- Required, makes sure notifications are delivered on time. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!--
    Required so the device vibrates on receiving a push notification.
    Vibration settings of the device still apply.
    -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- Required so the device can access the internet. -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--
    At a minimum the location module requires course permission, the app has the option
    to also include ACCESS_FINE_LOCATION and/or ACCESS_BACKGROUND_LOCATION
    -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <queries>
    <intent>
    <action android:name="android.intent.action.VIEW" />
    <data android:scheme="https" />
    </intent>
    </queries>
    <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application android:appComponentFactory="androidx.core.app.CoreComponentFactory">
    <meta-data android:name="android.max_aspect" android:value="2.5" />
    <meta-data android:name="android.notch_support" android:value="true" />
    <service android:name="androidx.room.MultiInstanceInvalidationService"
    android:directBootAware="true" android:exported="false" />
    <provider android:name="androidx.startup.InitializationProvider"
    android:authorities="APPLICATION_PACKAGE.androidx-startup" android:exported="false">
    <meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer"
    android:value="androidx.startup" />
    <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
    android:value="androidx.startup" />
    <meta-data android:name="androidx.work.WorkManagerInitializer"
    android:value="androidx.startup" />
    </provider>
    <!-- NOTIFICATIONS -->
    <receiver
    android:name="com.distriqt.extension.pushnotifications.notifications.receivers.NotificationReceiver"
    android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_DELETED" />
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION" />
    <data android:scheme="dtpn" />
    </intent-filter>
    </receiver>
    <activity
    android:name="com.distriqt.extension.pushnotifications.notifications.NotificationActivity"
    android:exported="false">
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_SELECTED" />
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION" />
    <data android:scheme="dtpn" />
    </intent-filter>
    </activity>
    <provider android:name="com.distriqt.extension.pushnotifications.content.FileProvider"
    android:authorities="APPLICATION_PACKAGE.pushnotificationsfileprovider" android:exported="false"
    android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_pushnotifications_paths" />
    </provider>
    <!-- ONE SIGNAL -->
    <meta-data android:name="com.onesignal.NotificationServiceExtension"
    android:value="com.distriqt.extension.pushnotifications.onesignal.NotificationServiceExtension" />
    <receiver android:name="com.onesignal.notifications.receivers.FCMBroadcastReceiver"
    android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
    <!-- High priority so OneSignal payloads can be filtered from other FCM receivers -->
    <intent-filter android:priority="999">
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <category android:name="APPLICATION_PACKAGE" />
    </intent-filter>
    </receiver>
    <receiver android:name="com.onesignal.notifications.receivers.NotificationDismissReceiver"
    android:exported="true" />
    <receiver android:name="com.onesignal.notifications.receivers.BootUpReceiver"
    android:exported="true">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
    </receiver>
    <receiver android:name="com.onesignal.notifications.receivers.UpgradeReceiver"
    android:exported="true">
    <intent-filter>
    <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
    </receiver>
    <activity android:name="com.onesignal.notifications.activities.NotificationOpenedActivity"
    android:excludeFromRecents="true" android:exported="true" android:noHistory="true"
    android:taskAffinity="" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    <activity
    android:name="com.onesignal.notifications.activities.NotificationOpenedActivityAndroid22AndOlder"
    android:excludeFromRecents="true" android:exported="true" android:noHistory="true"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    <service android:name="com.onesignal.core.services.SyncService" android:exported="false"
    android:stopWithTask="true" />
    <service android:name="com.onesignal.core.services.SyncJobService" android:exported="false"
    android:permission="android.permission.BIND_JOB_SERVICE" />
    <activity android:name="com.onesignal.core.activities.PermissionsActivity"
    android:exported="false" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    <service android:name="com.google.firebase.components.ComponentDiscoveryService"
    android:directBootAware="true" android:exported="false">
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.inappmessaging.FirebaseInAppMessagingRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.inappmessaging.display.FirebaseInAppMessagingDisplayRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.analytics.connector.internal.AnalyticsConnectorRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    <meta-data
    android:name="com.google.firebase.components:com.google.firebase.abt.component.AbtRegistrar"
    android:value="com.google.firebase.components.ComponentRegistrar" />
    </service>
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
    android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
    </receiver>
    <!--
    FirebaseMessagingService performs security checks at runtime,
    but set to not exported to explicitly avoid allowing another app to call it.
    -->
    <service android:name="com.google.firebase.messaging.FirebaseMessagingService"
    android:directBootAware="true" android:exported="false">
    <intent-filter android:priority="-500">
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
    </service>
    <receiver android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
    android:enabled="true" android:exported="false" />
    <service android:name="com.google.android.gms.measurement.AppMeasurementService"
    android:enabled="true" android:exported="false" />
    <service android:name="com.google.android.gms.measurement.AppMeasurementJobService"
    android:enabled="true" android:exported="false"
    android:permission="android.permission.BIND_JOB_SERVICE" />
    <meta-data android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />
    <activity android:name="com.google.android.gms.common.api.GoogleApiActivity"
    android:exported="false" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    <service android:name="androidx.work.impl.background.systemalarm.SystemAlarmService"
    android:directBootAware="false" android:enabled="@bool/enable_system_alarm_service_default"
    android:exported="false" />
    <service android:name="androidx.work.impl.background.systemjob.SystemJobService"
    android:directBootAware="false" android:enabled="@bool/enable_system_job_service_default"
    android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />
    <service android:name="androidx.work.impl.foreground.SystemForegroundService"
    android:directBootAware="false"
    android:enabled="@bool/enable_system_foreground_service_default" android:exported="false" />
    <receiver android:name="androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"
    android:directBootAware="false" android:enabled="true" android:exported="false" />
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy"
    android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy"
    android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BATTERY_OKAY" />
    <action android:name="android.intent.action.BATTERY_LOW" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy"
    android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
    <action android:name="android.intent.action.DEVICE_STORAGE_OK" />
    </intent-filter>
    </receiver>
    <receiver
    android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy"
    android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver"
    android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.TIME_SET" />
    <action android:name="android.intent.action.TIMEZONE_CHANGED" />
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
    android:directBootAware="false" android:enabled="@bool/enable_system_alarm_service_default"
    android:exported="false">
    <intent-filter>
    <action android:name="androidx.work.impl.background.systemalarm.UpdateProxies" />
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.diagnostics.DiagnosticsReceiver"
    android:directBootAware="false" android:enabled="true" android:exported="true"
    android:permission="android.permission.DUMP">
    <intent-filter>
    <action android:name="androidx.work.diagnostics.REQUEST_DIAGNOSTICS" />
    </intent-filter>
    </receiver>
    <service
    android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService"
    android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE" />
    <receiver
    android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"
    android:exported="false" />
    <service
    android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery"
    android:exported="false">
    <meta-data android:name="backend:com.google.android.datatransport.cct.CctBackendFactory"
    android:value="cct" />
    </service>
    <activity android:name="com.distriqt.core.auth.AuthorisationActivity" android:exported="false"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    <provider android:name="com.google.firebase.provider.FirebaseInitProvider"
    android:authorities="APPLICATION_PACKAGE.firebaseinitprovider" android:directBootAware="true"
    android:exported="false" android:initOrder="100" />
    </application>
    </manifest>

    Amazon

    Amazon is a specific implementation of Android and requires some additional manifest additions if you are distributing your application via the Amazon AppStore.

    Firstly add the amazon namespace to your manifest tag:

    <manifest android:installLocation="auto"
    xmlns:amazon="http://schemas.amazon.com/apk/res/android"
    >

    Add the following permissions:

    <uses-permission android:name="com.amazon.device.messaging.permission.RECEIVE" />
    <permission android:name="APPLICATION_PACKAGE.permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="APPLICATION_PACKAGE.permission.RECEIVE_ADM_MESSAGE" />

    In the application tag, add the following:

    <amazon:enable-feature android:name="com.amazon.device.messaging" android:required="false"/>
    <service android:name="com.onesignal.ADMMessageHandler" android:exported="false" />
    <service android:name="com.onesignal.ADMMessageHandlerJob"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="false" />
    <receiver android:name="com.onesignal.ADMMessageHandler$Receiver"
    android:permission="com.amazon.device.messaging.permission.SEND" >
    <intent-filter>
    <action android:name="com.amazon.device.messaging.intent.REGISTRATION" />
    <action android:name="com.amazon.device.messaging.intent.RECEIVE" />
    <category android:name="APPLICATION_PACKAGE" />
    </intent-filter>
    </receiver>

    Follow the guide here to generate your Amazon API Key. You should end up with a file (api_key.txt) that you will need to add to the root of your application and ensure it is packaged into your application.

    danger

    Do not place the api_key.txt file in an assets folder as mentioned in the OneSignal documentation. Any assets from AIR are automatically added into this directory, so add it at the top level of your application package.

    info

    You will need to be using a recent version of AIR to be able to support these additional manifest namespaces and tags.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/amazon/index.html b/docs/pushnotifications/onesignal/amazon/index.html index ffca8a5e3a0..117985dfc04 100644 --- a/docs/pushnotifications/onesignal/amazon/index.html +++ b/docs/pushnotifications/onesignal/amazon/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Amazon SDK Setup

    If you wish to use Amazon device messaging in OneSignal you will need to do some additional changes to your installation.

    We will assume you have already setup your OneSignal account and have your App ID. If not see the setup section.

    Amazon API Key File

    Download the agconnect-services.json file:

    • From the AppGallery Connect Project List select your app.

    • Ensure you have added your certificate SHA fingerprint to your app configuration.

    • Click on the "agconnect-services.json" button to download this file.

    • Place this file at the root of your application and ensure it is packaged.

    Update Manifest

    In order to support Amazon we need to add a few things to the manifest additions in your app descriptor.

    Using apm you can generate a custom configuration which can be merged into your app descriptor by apm. Firstly create a configuration for android:

    apm generate config android

    Then edit the file created at config/android/AndroidManifest.xml.

    Firstly add the amazon namespace at the top of the file:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:amazon="http://schemas.amazon.com/apk/res/android"
    >

    Then add the following permissions, services and receivers, so your file should resemble:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:amazon="http://schemas.amazon.com/apk/res/android"
    >
    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33"/>

    <uses-permission android:name="com.amazon.device.messaging.permission.RECEIVE" />
    <permission android:name="${applicationId}.permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.RECEIVE_ADM_MESSAGE" />

    <application>

    <amazon:enable-feature android:name="com.amazon.device.messaging" android:required="false"/>
    <service android:name="com.onesignal.notifications.services.ADMMessageHandler" android:exported="false" />
    <service android:name="com.onesignal.notifications.services.ADMMessageHandlerJob"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="false" />
    <receiver android:name="com.onesignal.notifications.receivers.ADMMessageReceiver"
    android:permission="com.amazon.device.messaging.permission.SEND"
    android:exported="true" >
    <intent-filter>
    <action android:name="com.amazon.device.messaging.intent.REGISTRATION" />
    <action android:name="com.amazon.device.messaging.intent.RECEIVE" />
    <category android:name="${applicationId}" />
    </intent-filter>
    </receiver>

    </application>

    </manifest>
    info

    Do not change the ${applicationId} references as these will be automatically handled by the merge process.

    Then regenerate your application descriptor.

    apm generate app-descriptor
    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/huawei/index.html b/docs/pushnotifications/onesignal/huawei/index.html index 6ba0b55e3c8..e631e41fac3 100644 --- a/docs/pushnotifications/onesignal/huawei/index.html +++ b/docs/pushnotifications/onesignal/huawei/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ You should add the listing below to your manifest, ensure you merge the application node with any existing node in your manifest. The following listing should replace any additions you made if you originally installed the Firebase implementation of OneSignal.

    caution

    Ensure you replace:

    • APPLICATION_PACKAGE with your AIR application's Java package name, something like air.com.distriqt.test. Generally this is your AIR application id prefixed by air. unless you have specified no air flair in your build options.
    <manifest android:installLocation="auto" >
    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <permission android:name="APPLICATION_PACKAGE.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>
    <uses-permission android:name="APPLICATION_PACKAGE.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <queries>
    <intent>
    <action android:name="com.huawei.hms.core.aidlservice"/>
    </intent>
    <intent>
    <action android:name="com.huawei.hms.core"/>
    </intent>
    <package android:name="com.huawei.works"/>
    </queries>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <permission android:name="APPLICATION_PACKAGE.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="APPLICATION_PACKAGE.permission.C2D_MESSAGE"/>
    <!-- BADGE -->
    <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
    <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>
    <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
    <uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/>
    <uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
    <uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>
    <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
    <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="android.permission.READ_APP_BADGE"/>
    <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ"/>
    <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE"/>
    <!--
    Required so the device vibrates on receiving a push notification.
    Vibration settings of the device still apply.
    -->
    <uses-permission android:name="android.permission.VIBRATE"/>
    <!--
    At a minimum the location module requires course permission, the app has the option
    to also include ACCESS_FINE_LOCATION and/or ACCESS_BACKGROUND_LOCATION
    -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <permission android:name="APPLICATION_PACKAGE.permission.PROCESS_PUSH_MSG" android:protectionLevel="signature"/>
    <!-- PUSH_PROVIDER and PUSH_WRITE_PROVIDER are both provider registered permissions for the notification switch. -->
    <!-- The SDK's notification bar switch, EMUI 9.x becomes write to the local sp, sharing the file through the provider to the push-rom, which reads the sp file to get the status of the notification bar switch. -->
    <permission android:name="APPLICATION_PACKAGE.permission.PUSH_PROVIDER" android:protectionLevel="signature"/>
    <permission android:name="APPLICATION_PACKAGE.permission.PUSH_WRITE_PROVIDER" android:protectionLevel="signature"/>
    <uses-permission android:name="APPLICATION_PACKAGE.permission.PROCESS_PUSH_MSG"/>
    <uses-permission android:name="APPLICATION_PACKAGE.permission.PUSH_PROVIDER"/>
    <application android:appComponentFactory="androidx.core.app.CoreComponentFactory">
    <service android:name="androidx.room.MultiInstanceInvalidationService" android:directBootAware="true" android:exported="false"/>
    <provider android:name="androidx.startup.InitializationProvider" android:authorities="APPLICATION_PACKAGE.androidx-startup" android:exported="false">
    <meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup"/>
    <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer" android:value="androidx.startup"/>
    <meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup"/>
    </provider>
    <service android:name="androidx.work.impl.background.systemalarm.SystemAlarmService" android:directBootAware="false" android:enabled="@bool/enable_system_alarm_service_default" android:exported="false"/>
    <service android:name="androidx.work.impl.background.systemjob.SystemJobService" android:directBootAware="false" android:enabled="@bool/enable_system_job_service_default" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE"/>
    <service android:name="androidx.work.impl.foreground.SystemForegroundService" android:directBootAware="false" android:enabled="@bool/enable_system_foreground_service_default" android:exported="false"/>
    <receiver android:name="androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver" android:directBootAware="false" android:enabled="true" android:exported="false"/>
    <receiver android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy" android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy" android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BATTERY_OKAY"/>
    <action android:name="android.intent.action.BATTERY_LOW"/>
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy" android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.DEVICE_STORAGE_LOW"/>
    <action android:name="android.intent.action.DEVICE_STORAGE_OK"/>
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy" android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver" android:directBootAware="false" android:enabled="false" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="android.intent.action.TIME_SET"/>
    <action android:name="android.intent.action.TIMEZONE_CHANGED"/>
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver" android:directBootAware="false" android:enabled="@bool/enable_system_alarm_service_default" android:exported="false">
    <intent-filter>
    <action android:name="androidx.work.impl.background.systemalarm.UpdateProxies"/>
    </intent-filter>
    </receiver>
    <receiver android:name="androidx.work.impl.diagnostics.DiagnosticsReceiver" android:directBootAware="false" android:enabled="true" android:exported="true" android:permission="android.permission.DUMP">
    <intent-filter>
    <action android:name="androidx.work.diagnostics.REQUEST_DIAGNOSTICS"/>
    </intent-filter>
    </receiver>
    <service android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE"/>
    <receiver android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver" android:exported="false"/>
    <service android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery" android:exported="false">
    <meta-data android:name="backend:com.google.android.datatransport.cct.CctBackendFactory" android:value="cct"/>
    </service>
    <provider android:name="com.huawei.agconnect.core.provider.AGConnectInitializeProvider" android:authorities="APPLICATION_PACKAGE.AGCInitializeProvider" android:exported="false"/>
    <service android:name="com.huawei.agconnect.core.ServiceDiscovery" android:exported="false"/>
    <!-- 用于判断是否集成了本lib -->
    <meta-data android:name="availableLoaded" android:value="yes"/>
    <!-- 为后续统计第三方app集成了哪些Kit,因此需要Kit在自己的AndroidManifest.xml文件中定义业务标签元数据 -->
    <meta-data android:name="com.huawei.hms.client.service.name:base" android:value="base:6.11.0.301"/>
    <!-- SDK依赖的HMSCore的最低api level元数据 -->
    <meta-data android:name="com.huawei.hms.min_api_level:base:hmscore" android:value="1"/>
    <activity android:name="com.huawei.hms.activity.BridgeActivity" android:configChanges="orientation|locale|layoutDirection|fontScale|screenSize|smallestScreenSize|screenLayout|uiMode" android:excludeFromRecents="true" android:exported="false" android:hardwareAccelerated="true" android:screenOrientation="behind" android:theme="@style/Base_Translucent">
    <meta-data android:name="hwc-theme" android:value="androidhwext:style/Theme.Emui.Translucent"/>
    </activity>
    <activity android:name="com.huawei.hms.activity.EnableServiceActivity" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout" android:exported="false"/>
    <activity android:name="com.huawei.hms.hwid.internal.ui.activity.HwIdSignInHubActivity" android:configChanges="fontScale|uiMode" android:excludeFromRecents="true" android:exported="false" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    <activity android:name="com.huawei.hms.account.internal.ui.activity.AccountSignInHubActivity" android:excludeFromRecents="true" android:exported="false" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    <!-- 切记同步修改 HuaweiIdAuthInternalConstant.HMS_SDK_VERSION -->
    <meta-data android:name="com.huawei.hms.client.service.name:hwid" android:value="hwid:6.11.0.300"/>
    <meta-data android:name="com.huawei.hms.min_api_level:hwid:hwid" android:value="1"/>
    <!-- 5.3.0 独立授权依赖的api_level为11 -->
    <!-- 5.3.0 setCarrierId依赖的api_level为13 -->
    <meta-data android:name="com.huawei.hms.min_api_level:hwid:account" android:value="13"/>
    <!-- NOTIFICATIONS -->
    <receiver android:name="com.distriqt.extension.pushnotifications.notifications.receivers.NotificationReceiver" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
    </intent-filter>
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_DELETED"/>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION"/>
    <data android:scheme="dtpn"/>
    </intent-filter>
    </receiver>
    <activity android:name="com.distriqt.extension.pushnotifications.notifications.NotificationActivity" android:exported="false">
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_SELECTED"/>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION"/>
    <data android:scheme="dtpn"/>
    </intent-filter>
    </activity>
    <provider android:name="com.distriqt.extension.pushnotifications.content.FileProvider" android:authorities="APPLICATION_PACKAGE.pushnotificationsfileprovider" android:exported="false" android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/distriqt_pushnotifications_paths"/>
    </provider>
    <!-- ONE SIGNAL -->
    <meta-data android:name="com.onesignal.NotificationServiceExtension" android:value="com.distriqt.extension.pushnotifications.onesignal.NotificationServiceExtension"/>
    <service android:name="com.distriqt.extension.pushnotifications.onesignal.OneSignalHMSService" android:exported="false">
    <intent-filter>
    <action android:name="com.huawei.push.action.MESSAGING_EVENT"/>
    </intent-filter>
    </service>
    <receiver android:name="com.onesignal.notifications.receivers.FCMBroadcastReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
    <!-- High priority so OneSignal payloads can be filtered from other FCM receivers -->
    <intent-filter android:priority="999">
    <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
    <category android:name="APPLICATION_PACKAGE"/>
    </intent-filter>
    </receiver>
    <activity android:name="com.onesignal.notifications.activities.NotificationOpenedActivityHMS" android:exported="true" android:noHistory="true" android:theme="@android:style/Theme.Translucent.NoTitleBar">
    <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    </intent-filter>
    </activity>
    <receiver android:name="com.onesignal.notifications.receivers.NotificationDismissReceiver" android:exported="true"/>
    <receiver android:name="com.onesignal.notifications.receivers.BootUpReceiver" android:exported="true">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
    </intent-filter>
    </receiver>
    <receiver android:name="com.onesignal.notifications.receivers.UpgradeReceiver" android:exported="true">
    <intent-filter>
    <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
    </intent-filter>
    </receiver>
    <activity android:name="com.onesignal.notifications.activities.NotificationOpenedActivity" android:excludeFromRecents="true" android:exported="true" android:noHistory="true" android:taskAffinity="" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    <activity android:name="com.onesignal.notifications.activities.NotificationOpenedActivityAndroid22AndOlder" android:excludeFromRecents="true" android:exported="true" android:noHistory="true" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    <service android:name="com.onesignal.core.services.SyncService" android:exported="false" android:stopWithTask="true"/>
    <service android:name="com.onesignal.core.services.SyncJobService" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE"/>
    <activity android:name="com.onesignal.core.activities.PermissionsActivity" android:exported="false" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    <activity android:name="com.distriqt.core.auth.AuthorisationActivity" android:exported="false" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    <provider android:name="com.huawei.hms.aaid.InitProvider" android:authorities="APPLICATION_PACKAGE.aaidinitprovider" android:exported="false" android:initOrder="500"/>
    <meta-data android:name="com.huawei.hms.client.service.name:opendevice" android:value="opendevice:6.11.0.300"/>
    <meta-data android:name="com.huawei.hms.min_api_level:opendevice:push" android:value="1"/>
    <receiver android:name="com.huawei.hms.support.api.push.PushMsgReceiver" android:directBootAware="true" android:exported="true" android:permission="APPLICATION_PACKAGE.permission.PROCESS_PUSH_MSG">
    <intent-filter>
    <!-- Mandatory, be used to receive notification bar message click event. -->
    <action android:name="com.huawei.intent.action.PUSH_DELAY_NOTIFY"/>
    <!-- Optional, compatible with old huawei phones. -->
    <action android:name="com.huawei.intent.action.PUSH"/>
    </intent-filter>
    </receiver>
    <receiver android:name="com.huawei.hms.support.api.push.PushReceiver" android:directBootAware="true" android:exported="true" android:permission="APPLICATION_PACKAGE.permission.PROCESS_PUSH_MSG">
    <intent-filter>
    <!-- Mandatory, be used to receive tokens. -->
    <action android:name="com.huawei.android.push.intent.REGISTRATION"/>
    <!-- Mandatory, be used to receive messages. -->
    <action android:name="com.huawei.android.push.intent.RECEIVE"/>
    </intent-filter>
    </receiver>
    <!-- Definition of receiving service for notification bar and pass-through message of non-huawei mobile phone. -->
    <service android:name="com.huawei.hms.support.api.push.service.HmsMsgService" android:directBootAware="true" android:enabled="true" android:exported="true" android:process=":pushservice">
    <intent-filter>
    <action android:name="com.huawei.push.msg.NOTIFY_MSG"/>
    <action android:name="com.huawei.push.msg.PASSBY_MSG"/>
    </intent-filter>
    </service>
    <provider android:name="com.huawei.hms.support.api.push.PushProvider" android:authorities="APPLICATION_PACKAGE.huawei.push.provider" android:exported="true" android:readPermission="APPLICATION_PACKAGE.permission.PUSH_PROVIDER" android:writePermission="APPLICATION_PACKAGE.permission.PUSH_WRITE_PROVIDER"/>
    <meta-data android:name="com.huawei.hms.client.service.name:push" android:value="push:6.11.0.300"/>
    <meta-data android:name="com.huawei.hms.min_api_level:push:push" android:value="1"/>
    <activity android:name="com.huawei.hms.support.api.push.TransActivity" android:exported="false"/>
    </application>
    </manifest>

    Initialise HMS

    There is one small code addition required, which is simply to initialise HMS to ensure the configuration is read from your agconnect services json file. We suggest doing this before initilaising the Push Notifications extension and setting up your service.

    Firstly add the import:

    import com.distriqt.extension.hms.base.Base;

    Then call initialise():

    var success:Boolean = Base.instance.initialise();

    This will return true if the json file was found and loaded correctly.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/index.html b/docs/pushnotifications/onesignal/index.html index 5cc42a5489f..793c26d6472 100644 --- a/docs/pushnotifications/onesignal/index.html +++ b/docs/pushnotifications/onesignal/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Setup

    OneSignal provides a simple interface to push notifications, letting content creators focus on quality user engagement instead of complex implementation.

    OneSignal's documentation is fairly comprehensive and will guide you through the majority of the setup, so we are just going to highlight the key points here.

    Create an Account

    The first step is to create an account with OneSignal.

    You can sign up here:

    Once you have created an account, log in to the app:

    Create an App

    The process is fairly straight forward to add a new app to your account. Follow the guide and create your app. You will initially just add one platform and you can add others later.

    • Click the "New App/Website" button;
    • Enter the name of your application and select one of the platforms (iOS/Android etc);
    • Follow the documentation to configure your application;

    Once complete you will need to take note of your OneSignal App ID. This is available in your app dashboard, under Settings / Keys & IDs.

    Your OneSignal App ID or just App ID, is the main identifier we use to differentiate your app from all other OneSignal apps. You will use this in all your SDK initialization codes and API calls. The App ID should not be treated as private.

    More information on the OneSignal App ID is available in Keys & IDs.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/migrating-to-v7.5/index.html b/docs/pushnotifications/onesignal/migrating-to-v7.5/index.html index 66ab0b43979..89a3e3d700a 100644 --- a/docs/pushnotifications/onesignal/migrating-to-v7.5/index.html +++ b/docs/pushnotifications/onesignal/migrating-to-v7.5/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    OneSignal - Migrating to v7.5

    Migrating

    v7.5 brings a few changes to OneSignal:

    • Addition of GDPR user consent
    • Android migration to Firebase Cloud Messaging (FCM)

    See the documentation on user consent

    Firebase Cloud Messaging

    v3.9.1 of the OneSignal SDK utilises FCM on Android.

    This means you will need to add the Firebase dependencies to your application and remove the Play Services GCM ANE.

    iOS still uses APNS directly so no changes are required if you only use iOS

    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/quick-start/index.html b/docs/pushnotifications/onesignal/quick-start/index.html index 9c30d7f402f..7a8de493dc0 100644 --- a/docs/pushnotifications/onesignal/quick-start/index.html +++ b/docs/pushnotifications/onesignal/quick-start/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    OneSignal - Quick Start

    • Setup OneSignal Account

    • Use AIR 33+

    • Install with apm:

      • apm install com.distriqt.PushNotifications-OneSignal
    • Configure apm:

      • apm project config set com.distriqt.PushNotifications
      • apm -b development project config set apsEnvironment development
      • apm -b development project config set getTaskAllow true
    • Generate app descriptor:

      • apm generate app-descriptor src/MyApp-app.xml

    Setup the Extension and Service

    • replace ONESIGNAL_APP_ID with your OneSignal App ID:
    Core.init();
    if (PushNotifications.isSupported)
    {
    var service:Service = new Service(
    Service.ONESIGNAL,
    ONESIGNAL_APP_ID );
    service.enableNotificationsWhenActive = true;

    PushNotifications.service.setup( service );
    }

    Request Authorisation

    function checkAuthorisation():void
    {
    switch (PushNotifications.service.authorisationStatus())
    {
    case AuthorisationStatus.AUTHORISED:
    // This device has been authorised.
    // You can register this device and expect:
    // - registration success/failed event, and;
    // - notifications to be displayed
    registerNotifications();
    break;

    case AuthorisationStatus.NOT_DETERMINED:
    // You are yet to ask for authorisation to display notifications
    // At this point you should consider your strategy to get your user to authorise
    // notifications by explaining what the application will provide
    PushNotifications.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
    PushNotifications.service.requestAuthorisation();
    break;

    case AuthorisationStatus.DENIED:
    // The user has disabled notifications
    // Advise your user of the lack of notifications as you see fit

    // For example: You can redirect to the settings page on iOS
    if (PushNotifications.service.canOpenDeviceSettings)
    {
    PushNotifications.service.openDeviceSettings();
    }
    break;
    }
    }

    function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    // Check the authorisation state again (as above)
    PushNotifications.service.removeEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
    checkAuthorisation();
    }

    Listen for Notifications and Register

    Call register after adding your event listeners as a notification may be dispatched immediately if your application was started from a notification

    function registerNotifications():void
    {
    PushNotifications.service.addEventListener( PushNotificationEvent.NOTIFICATION, notificationHandler );
    PushNotifications.service.addEventListener( PushNotificationEvent.NOTIFICATION_SELECTED, notificationHandler );

    PushNotifications.service.register();
    }

    function notificationHandler( event:PushNotificationEvent ):void
    {
    trace( "Notification: ["+event.type+"] state="+event.applicationState+" startup="+event.startup );
    trace( event.payload );
    }
    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/setup-your-service/index.html b/docs/pushnotifications/onesignal/setup-your-service/index.html index 900a56f38b4..83927bd304f 100644 --- a/docs/pushnotifications/onesignal/setup-your-service/index.html +++ b/docs/pushnotifications/onesignal/setup-your-service/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Setup your Service - OneSignal

    OneSignal does most of the initialisation of your application from the server so you should just need to add your app id to the service and call setup.

    The following shows how to configure the Service for usage with your One Signal app.

    var service:Service = new Service( 
    Service.ONESIGNAL,
    ONESIGNAL_APP_ID );
    service.enableNotificationsWhenActive = true;

    PushNotifications.service.setup( service );

    The ONESIGNAL_APP_ID will be your OneSignal App ID which you can retrieve from your App Settings under Keys & IDs.

    See the setup guide for more information on retrieving this value.

    Android notification sounds

    As of Android O notification sounds now need to be specified on a Channel. So in order to play a custom sound on a notification you need to setup a channel.

    Note you must have added the FileProvider correctly to your manifest additions for sounds to playback correctly.

    OneSignal will do this automatically through the dashboard however it requires resources for the notification sounds. The easier method is to setup the channels in your application and then just use the existing notification channel id when sending notifications.

    var service:Service = new Service( Service.ONESIGNAL, Config.oneSignalAppId )
    .setNotificationsWhenActive( true )
    ;

    service.channels.push(
    new ChannelBuilder()
    .setId( "sound_channel" )
    .setName( "Sound Channel" )
    .setSound( "assets/notifications/sounds/notification.mp3" )
    .setImportance( Channel.IMPORTANCE_HIGH )
    .build()
    );

    PushNotifications.service.setup( service );

    Then when sending your notification set the channel id to the id defined in your channel (sound_channel in the above example):

    • Using REST set the "existing_android_channel_id"
    • Using the dashboard set the Category to "(Created In App)" and set the Local Channel Id to your channel id.
    - + \ No newline at end of file diff --git a/docs/pushnotifications/onesignal/signing/index.html b/docs/pushnotifications/onesignal/signing/index.html index 7acaf4a54e6..4068d460217 100644 --- a/docs/pushnotifications/onesignal/signing/index.html +++ b/docs/pushnotifications/onesignal/signing/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    OneSignal - Signing

    This is no longer required from AIR 30+

    Signing your iOS application

    With AIR 27 Adobe has partially completed the ability to use dynamic frameworks in your iOS application. This is the additional Frameworks directory that you added to the build.

    Everything will work up to a point including debug builds should work well, however AIR will incorrectly sign a release version of your IPA and it will fail AppStore submission with an error from the Application Loader tool.

    Please vote to resolve this issue here: https://tracker.adobe.com/#/view/AIR-4198407

    To get around this, before you upload your application to iTunesConnect you will need to run a script to resign your IPA. This script is available in the repository alongside the OneSignal ANE in the OneSignal/scripts directory.

    This script will only work on a macOS machine with Xcode installed and your distribution certificate installed in Keychain

    Copy this script to a directory in your development environment.

    Firstly edit the script to change the details of the IPA, provisioning profile and signing identity for your application. These details are located at the top of the script.

    #####################################
    ## CONFIG

    # You need to set the values below for your application
    # We suggest they are full paths to the files.

    # The path to the ipa generated from your AIR application packaging
    IPA="/path/to/yourApp.ipa"

    # The distribution provisioning profile for your application
    PROVISIONING_PROFILE="/path/to/profile.mobileprovision"

    # The name of the signing identity. You get this by running the following in a terminal
    # and selecting the name of your distribution certificate:
    #
    # security find-identity -v -p codesigning
    SIGNING_IDENTITY="iPhone Distribution: XXXXXXXXX (XXXXX)"

    Now open a Terminal at the script location. You will need to run the script from this directory.

    ./resign

    This should output a few informational items to the console and then once complete you should have a new IPA file in the directory named: yourApp_resigned.ipa. If there were any errors or warnings displayed, make sure the information above is all correct.

    This resigned IPA is the file you should upload to iTunesConnect

    If you have any issues please contact us on github.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/pushy/index.html b/docs/pushnotifications/pushy/index.html index 2e5ceba2d46..fa13ee6da7d 100644 --- a/docs/pushnotifications/pushy/index.html +++ b/docs/pushnotifications/pushy/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ when you were setting up your application in the iOS developer center. The seed id should be a unique ten character string and the identifier should be similar to your AIR application id.

    Android

    Manifest Additions

    You must add all the Pushy related manifest additions.

    The following shows the complete manifest additions node. You must replace APPLICATION_PACKAGE with your AIR application's Java package name, something like air.com.distriqt.test. Generally this is your AIR application id prefixed by air. unless you have specified no air flair in your build options.

    <manifest android:installLocation="auto">
    <uses-sdk android:minSdkVersion="19" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application>
    <activity android:name="com.distriqt.core.auth.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:exported="false" />

    <!-- NOTIFICATIONS -->
    <receiver android:name="com.distriqt.extension.pushnotifications.notifications.receivers.NotificationReceiver" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_DELETED" />
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION" />
    <data android:scheme="dtpn" />
    </intent-filter>
    </receiver>
    <activity android:name="com.distriqt.extension.pushnotifications.notifications.NotificationActivity" android:exported="false">
    <intent-filter>
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_SELECTED" />
    <action android:name="APPLICATION_PACKAGE.NOTIFICATION_ACTION" />
    <data android:scheme="dtpn" />
    </intent-filter>
    </activity>
    <provider
    android:name="com.distriqt.extension.pushnotifications.content.FileProvider"
    android:authorities="APPLICATION_PACKAGE.pushnotificationsfileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_pushnotifications_paths" />
    </provider>


    <!-- Pushy Declarations -->

    <!-- Pushy Notification Receiver -->
    <!-- Incoming push notifications will invoke the following BroadcastReceiver -->
    <receiver android:name="com.distriqt.extension.pushnotifications.pushy.PushyReceiver" android:exported="false">
    <intent-filter>
    <!-- Do not modify this -->
    <action android:name="pushy.me" />
    </intent-filter>
    </receiver>

    <!-- Pushy Update Receiver -->
    <!-- Do not modify - internal BroadcastReceiver that restarts the listener service -->
    <receiver android:name="me.pushy.sdk.receivers.PushyUpdateReceiver" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
    </receiver>

    <!-- Pushy Boot Receiver -->
    <!-- Do not modify - internal BroadcastReceiver that restarts the listener service -->
    <receiver android:name="me.pushy.sdk.receivers.PushyBootReceiver" android:exported="false">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
    </receiver>

    <!-- Pushy Socket Service -->
    <!-- Do not modify - internal service -->
    <service android:name="me.pushy.sdk.services.PushySocketService" android:stopWithTask="false" />

    <!-- Pushy Job Service (added in Pushy SDK 1.0.35) -->
    <!-- Do not modify - internal service -->
    <service android:name="me.pushy.sdk.services.PushyJobService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:stopWithTask="false" />

    <!-- End Pushy Declarations -->



    </application>

    </manifest>

    Setup the Extension and Service

    To use Pushy you must specify the PUSHY service type. No additional identifier is required.

    try
    {
    Core.init();
    if (PushNotifications.service.isServiceSupported( Service.PUSHY ))
    {
    var service:Service = new Service( Service.PUSHY )
    .setNotificationsWhenActive( true );

    PushNotifications.service.setup( service );
    }
    }
    catch (e:Error)
    {
    trace( e );
    }

    You should then request authorisation as normal.

    Registration

    Register your application for notifications when you are ready. The Pushy "device token" is returned as the "service token" in our extension, to distinguish it from the actual device token identified from the OS (iOS in particular).

    So you should send the service token to your backend for sending notifications using Pushy:

    function registrationCompleteHandler( event:RegistrationEvent ):void
    {
    trace( "device token: " + PushNotifications.service.getDeviceToken() );
    trace( "service token: " + PushNotifications.service.getServiceToken() );

    // Send the servive token to your backend for notifications
    }

    The device token may be different from the service token so it is important to use the service token here.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/pushy/pushy-message/index.html b/docs/pushnotifications/pushy/pushy-message/index.html index 2d919149941..18ede6def18 100644 --- a/docs/pushnotifications/pushy/pushy-message/index.html +++ b/docs/pushnotifications/pushy/pushy-message/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content
    - + \ No newline at end of file diff --git a/docs/pushnotifications/pushy/pushy-payload/index.html b/docs/pushnotifications/pushy/pushy-payload/index.html index 77905d504a0..a33622cd129 100644 --- a/docs/pushnotifications/pushy/pushy-payload/index.html +++ b/docs/pushnotifications/pushy/pushy-payload/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Pushy Payload

    The payload for a pushy notification has two distinct sections for iOS and Android.

    The Android component is similar to the FCM payload and the iOS component similar to the APNs payload.

    Example payload:

    {
    "to": "a6345d0278adc55d3474f5",
    "data": {
    "message": "Hello World!"
    },
    "notification": {
    "body": "Hello World \u270c",
    "badge": 1,
    "sound": "ping.aiff"
    }
    }

    The to field is the device token for the destination device.

    The data object will contain any payload data you want to make available to your app's notification listener.

    The notification object within the sample request body is used to customize the built-in iOS notification and does not affect Android devices.

    In order to display a notification on Android, you must also include a notification object in the data payload, similar to how it is done with FCM.

    {
    "to": "a6345d0278adc55d3474f5",
    "data": {
    "message": "Hello World!",
    "notification" : {
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "Hello World",
    "badge" : 1,
    "sound" : "default"
    }
    },
    "notification": {
    "body": "Hello World",
    "badge": 1,
    "sound": "ping.aiff"
    }
    }

    You have access to all the fields defined in the FCM payload here, such as icons, grouping and images. See the documentation on the FCM payload for more information.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/receiving-notifications/index.html b/docs/pushnotifications/receiving-notifications/index.html index 907446a5ff0..95b6500092b 100644 --- a/docs/pushnotifications/receiving-notifications/index.html +++ b/docs/pushnotifications/receiving-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Receiving notifications

    There are several events that can be dispatched by a notification.

    The most important is the PushNotificationEvent.NOTIFICATION event. This event is dispatched as soon as possible after a notification is received. The exact timing of this event depends on the platform, the application settings (such as background modes) and the application state. See the notification scenarios section for more information.

    Next is the PushNotificationEvent.NOTIFICATION_SELECTED event. This event is dispatched when a user clicks a displayed notification. It will not be dispatched if the user dismisses or otherwise removes the notification without directly clicking on the notification.

    On Android, you additionally have the PushNotificationGroupEvent.GROUP_SELECTED event. This event is very similar to the NOTIFICATION_SELECTED event in that it is dispatched when the user clicks the notification, however as this notification was a group of notifications it is dispatched as a single event with an array of payloads indicating each of the individual events contained in the group.

    The PushNotificationEvent.ACTION is dispatched when a user clicks an action on a notification. This event currently is missed on iOS when the application is not running (background, suspended and foreground states operate correctly). This is due to an issue with AIR not allowing AIR application to launch into the background.

    // Previously called init, setup and checked authorisation

    PushNotifications.service.addEventListener( PushNotificationEvent.NOTIFICATION, notificationHandler );
    PushNotifications.service.addEventListener( PushNotificationEvent.NOTIFICATION_SELECTED, notificationHandler );
    PushNotifications.service.addEventListener( PushNotificationEvent.ACTION, actionHandler );
    PushNotifications.service.addEventListener( PushNotificationGroupEvent.GROUP_SELECTED, groupSelectedHandler );

    PushNotifications.service.register();


    function notificationHandler( event:PushNotificationEvent ):void
    {
    trace( "Notification: ["+event.type+"] state="+event.applicationState+" startup="+event.startup );
    trace( event.payload );
    }

    function actionHandler( event:PushNotificationEvent ):void
    {
    trace( "Action: ["+event.type+"] identifier="+event.identifier+" state="+event.applicationState+" startup="+event.startup );
    trace( event.payload );
    }

    function groupSelectedHandler( event:PushNotificationGroupEvent ):void
    {
    trace( "Group Selected: ["+event.type+"] groupKey="+event.groupKey+" state="+event.applicationState+" startup="+event.startup );
    for each (var payload:String in event.payloads)
    {
    trace( "PAYLOAD: "+ payload );
    }
    }
    - + \ No newline at end of file diff --git a/docs/pushnotifications/register-for-notifications/index.html b/docs/pushnotifications/register-for-notifications/index.html index 5444748e570..76bcb291d7f 100644 --- a/docs/pushnotifications/register-for-notifications/index.html +++ b/docs/pushnotifications/register-for-notifications/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Register for notifications

    Now that you have authorisation to access push notifications you can register your user's device. Registration involves a call to the server to obtain a registration id or device token. This is initiated by calling the register() function.

    The token may change at any time so you should also listen for the CHANGED event and update your server as your application requires.

    PushNotifications.service.addEventListener( RegistrationEvent.REGISTERING, registeringHandler );
    PushNotifications.service.addEventListener( RegistrationEvent.REGISTER_SUCCESS, registerSuccessHandler );
    PushNotifications.service.addEventListener( RegistrationEvent.CHANGED, registrationChangedHandler );
    PushNotifications.service.addEventListener( RegistrationEvent.REGISTER_FAILED, registerFailedHandler );
    PushNotifications.service.addEventListener( RegistrationEvent.ERROR, errorHandler );

    PushNotifications.service.register();
    function registeringHandler( event:RegistrationEvent ):void
    {
    trace( "Registration started" );
    }

    function registerSuccessHandler( event:RegistrationEvent ):void
    {
    trace( "Registration succeeded with ID: " + event.data );
    var deviceTokenOrRegistrationId:String = event.data;
    }

    function registrationChangedHandler( event:RegistrationEvent ):void
    {
    trace( "Registration ID has changed: " + event.data );
    var deviceTokenOrRegistrationId:String = event.data;
    }

    function registerFailedHandler( event:RegistrationEvent ):void
    {
    trace( "Registration failed" );
    }

    function errorHandler( event:RegistrationEvent ):void
    {
    trace( "Registration error: "+event.data );
    }

    Current Tokens

    Once registered you can access the current registration id / device token at any time by using the getDeviceToken() function. This will return the same string as the registration id / device token returned in either the REGISTER_SUCCESS or CHANGED event.

    var deviceTokenOrRegistrationId:String = PushNotifications.service.getDeviceToken();

    Additionally some services may have a secondary service identifier that the service server returned for this device. For example the OneSignal or Azure identifier. This can be retrieved by using the getServiceToken() function.

    var serviceToken:String = PushNotifications.service.getServiceToken();

    Depending on the service you are using you may have to use the device token or the service token to send notifications to the device.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/request-authorisation/index.html b/docs/pushnotifications/request-authorisation/index.html index b846fd632ce..66af3e6b3f7 100644 --- a/docs/pushnotifications/request-authorisation/index.html +++ b/docs/pushnotifications/request-authorisation/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ However the better method is to use the authorisationStatus() to determine the status, this will allow you to determine if your application has authorisation, has been denied or is not yet determined (i.e. the user has not yet been asked to grant authorisation).

    On iOS you will only be able to display the authorisation request dialog once! Hence it is very important that you inform your users why they should grant authorisation before requesting authorisation.

    To request authorisation you call requestAuthorisation(). This function will trigger the native dialog asking the user for authorisation.

    PushNotifications.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );

    switch (PushNotifications.service.authorisationStatus())
    {
    case AuthorisationStatus.AUTHORISED:
    // This device has been authorised.
    // You can register this device and expect:
    // - registration success/failed event, and;
    // - notifications to be displayed
    PushNotifications.service.register();
    break;

    case AuthorisationStatus.SHOULD_EXPLAIN:
    case AuthorisationStatus.NOT_DETERMINED:
    // You are yet to ask for authorisation or need to further explain
    // At this point you should consider your strategy to get your user to authorise
    // notifications by explaining what the application will provide
    PushNotifications.service.requestAuthorisation();
    break;

    case AuthorisationStatus.DENIED:
    // The user has disabled notifications
    // Advise your user of the lack of notifications as you see fit

    // For example: You can redirect to the settings page on iOS
    if (PushNotifications.service.canOpenDeviceSettings)
    {
    PushNotifications.service.openDeviceSettings();
    }
    break;
    }


    function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    // Check the authorisation state again (as above)
    }

    You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

    Device settings

    You can redirect the user to the device settings in order to get them to change the permission to access notifications.

    This can only be performed on some platforms and you should firstly check if it is supported before calling.

    if (PushNotifications.service.canOpenDeviceSettings)
    {
    PushNotifications.service.openDeviceSettings();
    }

    - + \ No newline at end of file diff --git a/docs/pushnotifications/set-badge-number/index.html b/docs/pushnotifications/set-badge-number/index.html index 7f43fa46d69..8f44f7bc2ff 100644 --- a/docs/pushnotifications/set-badge-number/index.html +++ b/docs/pushnotifications/set-badge-number/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ features onto Android users. So make sure you really want to use this functionality on Android before implementing.

    You will need to add the following permissions to your manifest additions to ensure your application has the correct permissions to update the badge number.

        <!--for Samsung-->
    <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>

    <!--for htc-->
    <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>

    <!--for sony-->
    <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
    <uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/>

    <!--for apex-->
    <uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>

    <!--for solid-->
    <uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>

    <!--for huawei-->
    <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
    <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>

    <!--for ZUK-->
    <uses-permission android:name="android.permission.READ_APP_BADGE"/>

    <!--for OPPO-->
    <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>

    <!--for EvMe-->
    <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ"/>
    <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE"/>

    Android 8

    Android 8.0 (API level 26) introduces functionality for displaying notification badges on app icons in supported launchers. Notification badges show notifications associated with one or more notification channels in an app, which the user has not yet dismissed or acted on. Users can turn off badges for notification channels or apps from the Settings app. Notification badges are also known as notification dots).

    Users can also long-press on an app icon to glance at the notifications associated with a notification badge in supported launchers. Users can then dismiss or act on notifications from the long-press menu in a similar way to the notification drawer.

    By default, each new notification in a channel increments the number displayed on the associated launcher long-press menu by one. After a user dismisses a notification or triggers a related action, that number decrements to reflect the change.

    Adjusting Badges

    By default, each notification channel reflects its active notifications in your app's launcher icon badge. You can use the setShowBadge() method to stop the presence of notifications from a channel being reflected by a badge. You can't programmatically modify this setting for a notification channel after it's created and submitted to the notification manager.

    Note: Users can turn off badges for notification channels or apps from the Settings app at any time.

    The following sample code illustrates how to hide badges in association with notifications from a notification channel:

    service.channels.push(
    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .setShowBadge( false )
    .build()
    );

    Windows

    On Windows it is part of the operating system and nothing additional is required. You can use the setBadgeNumber() method without any additional configuration.

    The badge will appear on the application tile pinned to the start menu:

    And on the application tile in the task bar (when application is closed):

    - + \ No newline at end of file diff --git a/docs/pushnotifications/setup-your-service/index.html b/docs/pushnotifications/setup-your-service/index.html index 42f66b91d35..13b2887acff 100644 --- a/docs/pushnotifications/setup-your-service/index.html +++ b/docs/pushnotifications/setup-your-service/index.html @@ -13,7 +13,7 @@ - + @@ -30,7 +30,7 @@ the notification event.

    service.setNotificationsWhenActive( true );

    Sandbox Mode

    Lastly in order to correctly test some of the services you should specify whether you are using the sandbox (testing) mode. This is not required by all platforms however some, including Firebase on iOS require this setting to be able to correctly test your application.

    Set sandboxMode to true for development environments and the default false for production.

    service.sandboxMode = true;

    Channels

    New to Android 8.0 (API level 26) is the concept of a notification channel.

    Notification channels provide a unified system to help users manage notifications. When you target Android 8.0 (API level 26), you must implement one or more notification channels to display notifications to your users. If you don't target Android 8.0 (API level 26) but your app is used on devices running Android 8.0 (API level 26), your app behaves the same as it would on devices running Android 7.1 (API level 25) or lower.

    Note: The user interface refers to notification channels as notification categories.

    You can create an instance of a Channel for each distinct type of notification you need to send. You can also create notification channels to reflect choices made by users of your app. For example, you may set up separate notification channels for each conversation group created by a user in a messaging app.

    Users can manage most of the settings associated with notifications using a consistent system UI. All notifications posted to the same notification channel have the same behavior. When a user modifies the behavior for any of the following characteristics, it applies to the notification channel:

    Users can visit Settings, or long-press a notification to change these behaviors, or even block a notification channel at any time. You can't programmatically modify the behavior of a notification channel after it's created and submitted to the notification manager; the user is in charge of those settings after creation. You can however rename a notification channel or update its description after creation.

    Creating Channels

    To create channels you add them to your Service definition. A Service.channels is an array of Channel objects that you should create when passing your service to the setup function.

    You should use the ChannelBuilder to create a Channel object.

    var service:Service = new Service();

    // Setup other service related properties

    service.channels.push(
    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .build()
    );

    You must add at least one channel.

    Channel Sounds

    Notification sounds on Android O (API v26) and higher now must be set on the Channel. Individual notification sounds will be ignored.

    To set a sound on a channel, use the setSound( path ) function and pass the local path to an mp3 file.

    eg:

    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .setSound( "assets/notifications/sounds/notification.mp3" )
    .build()

    This path should be relative to your application root.

    This path can also be a resource name if you are packaging raw mp3 resources with your application in a custom resources extension.

    Example

    The following example sets up the DEFAULT service with a category containing two actions.

    var service:Service = new Service( Service.DEFAULT, Config.gcmSenderId );
    service.sandboxMode = false;
    service.enableNotificationsWhenActive = true;

    service.categories.push(
    new CategoryBuilder()
    .setIdentifier( "INVITE_CATEGORY" )
    .addAction(
    new ActionBuilder()
    .setTitle( "Accept" )
    .setIdentifier( "ACCEPT_IDENTIFIER" )
    .build()
    )
    .addAction(
    new ActionBuilder()
    .setTitle( "Delete" )
    .setDestructive( true )
    .setIdentifier( "DELETE_IDENTIFIER" )
    .build()
    )
    .build()
    );

    service.channels.push(
    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .build()
    );

    PushNotifications.service.setup( service );
    - + \ No newline at end of file diff --git a/docs/pushnotifications/sounds/index.html b/docs/pushnotifications/sounds/index.html index a4324dc257a..cd1734ecf21 100644 --- a/docs/pushnotifications/sounds/index.html +++ b/docs/pushnotifications/sounds/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Sounds

    The following documentation describes how to get custom sounds to play when your notification arrives.

    Importantly these sounds are always affected by the user's sound settings and generally they can override what you provide (eg by muting the phone), so it's always worth checking your device before deciding sounds are failing.

    APNS

    With APNS the notification sound is sent as part of the payload on the notification. The sound field will specify the sound to use, the simplest case is to set it to "default" which will trigger the default notification sound on the device.

    {
    "aps" :
    {
    "alert" : "You have a notification",
    "badge" : 1,
    "sound" : "default"
    }
    }

    You can package a supported file type with your application to use as a custom sound. This sound file should just be included as any normal asset file. Then pass the path to the file in the sound field.

    For example, if we package a caf sound file called notification.caf in a sounds directory (at sounds/notification.caf) then the payload would be:

    {
    "aps" :
    {
    "alert" : "You have a notification",
    "badge" : 1,
    "sound" : "sounds/notification.caf"
    }
    }

    You cannot set the "default" sound on iOS, this is a user setting.

    Android

    Sounds on Android are handled slightly differently depending on the version of Android.

    Before Android 8.0 (v26) a sound field could be sent along with the notification payload and the file or resource would be played as a custom sound.

    {
    "data": {
    "notification" : {
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "The body of the notification",
    "sound" : "default"
    }
    }
    }

    This field will look for a local file or a raw resource mp3, matching the name specified. Resources will take priority over files.

    From Android 8.0 (v26), sounds must be associated with a "channel" and the channel specified in the notification payload affects the sound that is played.

    eg:

    new ChannelBuilder()
    .setId( "test_channel" )
    .setName( "Test Channel" )
    .setSound( "assets/notifications/sounds/notification.mp3" )
    .build()

    Channel Sounds

    FCM

    With FCM there are 2 methods of notifications being sent and processed. When the application is in the foreground our extension will handle the displaying of notifications, however when it is in the background our extension will only handle data notifications, message notifications (sent either through the notification API or through the console) will be handled by the Firebase SDK internally.

    Android 7 and lower

    Android uses individual sounds for notifications.

    When our extension handles the notification, the sound field can refer to a file or to a resource. If you are always using data notifications then you can safely use a file reference for your sound and package the sound with your application as you do with iOS.

    To use a file, the sound field should be the mp3 file path within your application package. For example, if we package an mp3 sound file called notification.mp3 in a sounds directory (at sounds/notification.caf) then the payload would be:

    {
    "data": {
    "notification" : {
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "The body of the notification",
    "sound" : "sounds/notification.mp3"
    }
    }
    }

    Note: You can leave the extension off if you want. i.e. "sound" : "sounds/notification"

    To use a resource, the sound field should be the name of the resource:

    "sound" : "notification_res_name"

    When the Firebase SDK handles the notification the sound field must refer to a resource. It will not look for files in your application.

    {
    "notification" : {
    "alert" : "You have a notification",
    "title" : "You have a notification",
    "body" : "The body of the notification",
    "sound" : "notification_res_name"
    }
    }

    Note: The absence of the data node means this is a message notification payload, not a data payload.

    To package a resource, you must add your mp3 file to the raw directory in your custom resources extension along with your icons and configuration values.

    Additionally you should use AIR 33 or higher. Previous versions of AIR can compress the raw resources making them unusable by services such as FCM.

    Android 8+

    Android 8+ uses the channel for notification sounds.

    Ensure you set the default channel:

    <meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="test_sound_channel"/>

    This default channel will be used for notifications that are sent without a specified channel.

    As you can always specify a channel in either a message or data notification you don't have the different scenarios that you have in older versions of Android. The channel can be created with either a file or a resource mp3 and both will work.

    Any sound property sent to an Android 8+ device will be ignored when creating the notification.

    Recommendation

    With this in mind, we recommend using a resource(s) for all sounds if possible. This approach gives you the most consistent experience across message and data notifications with Firebase Cloud Messaging.

    It does add some complexity in creating a custom resources extension containing your sounds however you will normally be doing this for your icons and FCM configuration values so shouldn't be too much of an addition.

    Then always specify the resource name in any references to sounds, you should continue to include the sound property in your payloads to correctly address older versions of Android and include the channel for Android 8+.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/tags/index.html b/docs/pushnotifications/tags/index.html index 50271a4f1ff..f72d814e178 100644 --- a/docs/pushnotifications/tags/index.html +++ b/docs/pushnotifications/tags/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Tags

    Tags are used by some services to assign variables to a user. This can then be used by the service to selective send notifications or to substitute variables in a notification to provide highly customised interactions with your users.

    For example, you could send a notification with your user's name and current stage they are on in your game:

    Hello Josh! We just improved our controls, come back and see if you can beat level 10!

    by setting tags such as:

    name: "Josh"
    current_stage: "10"

    Support

    Once you have setup your service you can query canSendTags to find out whether the current service supports tags. This allows you to react to cases where the user has push notifications but no tag support (eg with APNS).

    if (PushNotifications.service.canSendTags)
    {
    // Can subscribe to topics
    }

    Send Tags

    To assign a tag value to a user call the sendTag function with the tag name and the value to assign for the current user:

    PushNotifications.service.sendTag( "name", "Josh" );

    You can send multiple tags at the same time by sending an object:

    PushNotificaitons.service.sendTags( 
    {
    name: "Josh",
    current_stage: "10"
    }
    );

    Get Tags

    To retrieve a list of tags that have been set on the user call the getTags function.

    PushNotifications.service.getTags();

    This function will return true if the retrieval was started successfully and will subsequently dispatch a TagEvent.GET_TAGS_COMPLETE when the tags have been retrieved from the service.

    PushNotifications.service.addEventListener( TagEvent.GET_TAGS_COMPLETE, getTags_completeHandler );
    PushNotifications.service.getTags();

    function getTags_completeHandler( event:TagEvent ):void
    {
    trace( JSON.stringify( event.tags ) );
    }

    The event will have a tags object property which will contain all the tag key/value pairs.

    Delete Tags

    To delete a tag call the deleteTag function with the name of the tag to delete:

    PushNotifications.service.deleteTag( "current_level" );

    You can also delete multiple tags simultaneously using the deleteTags function:

    PushNotifications.service.deleteTags( [ "name", "current_level" ] );
    - + \ No newline at end of file diff --git a/docs/pushnotifications/topics/index.html b/docs/pushnotifications/topics/index.html index 922dfe0cc87..5f7fcda3624 100644 --- a/docs/pushnotifications/topics/index.html +++ b/docs/pushnotifications/topics/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ push notifications but no topic support (eg with APNS).

    if (PushNotifications.service.canSubscribeToTopics)
    {
    // Can subscribe to topics
    }

    Subscribe to a topic

    Subscrbing to a topic is as simple as calling subscribeToTopic with your topic name.

    For example

    PushNotifications.service.subscribeToTopic( "news" );

    This function returns the success of the operation, a success does not ensure the topic was subscribed, only that the request to subscribe was made.

    Note:

    Once you have called subscribe it may take several hours for the topic to appear in your service console. Do not expect the topic to be created instantly.

    Unsubscribe from a topic

    Similarly unsubscribing involves calling unsubscribeFromTopic with your topic name.

    PushNotifications.service.unsubscribeFromTopic( "news" );
    - + \ No newline at end of file diff --git a/docs/pushnotifications/user-consent/index.html b/docs/pushnotifications/user-consent/index.html index a52ccd92a36..b4fb0698305 100644 --- a/docs/pushnotifications/user-consent/index.html +++ b/docs/pushnotifications/user-consent/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    User Consent

    Currently only available for the OneSignal service implementation. Other services you will have to implement manually.

    In order to comply with GDPR or other regulations, you should make sure you appropriately disclose and get consent to send data to the notification service. For EU GDPR compliance in particular, recommend displaying a dialog to users and having them provide unambiguous consent for data to be shared with the notification service.

    If you require your users to consent to gathering information for usage then you can set the requiresUserPrivacyConsent option on your Service. This will delay initialisation and prevent any data from being sent to the service until the user has provided consent.

    var service:Service = new Service( Service.ONESIGNAL, Config.oneSignalAppId );
    service.requiresUserPrivacyConsent = true;

    Once you have gathered consent from the user you can inform the service by calling provideUserConsent:

    PushNotifications.service.provideUserConsent( true );
    - + \ No newline at end of file diff --git a/docs/pushnotifications/windows/add-the-extension/index.html b/docs/pushnotifications/windows/add-the-extension/index.html index 791139d5793..bc99a6d60e5 100644 --- a/docs/pushnotifications/windows/add-the-extension/index.html +++ b/docs/pushnotifications/windows/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Windows Push Notification Services

    About

    The Windows Push Notification Services (WNS) enable third-party developers to send toast, tile, badge, and raw updates from their own cloud service. This provides a mechanism to deliver new updates to your users in a power-efficient and dependable way.

    This section describes how to setup your AIR application to use WNS with this extension.

    WNS is supported by all of the variants of this extension. It is the core notification service on Windows and requires minimal additional libraries so we have included it in every variant.

    There are several additional things to consider on Windows:

    • Appx Packaging
    • Additional Dependencies
      • [.Net Framework]](#net-framework)
      • [C++ Redistributable]](#c-redistributable)

    Setup

    You should firstly setup WNS for your application. See the setup documentation to guide you through this process.

    Install

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.PushNotifications

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.PushNotifications.ane # PushNotifications extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds (rather than copying the files elsewhere) so that updates with apm will be pulled automatically into your build.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Additional Dependencies

    .Net Framework

    This extension requires v4.6 or higher of the .Net framework. This should come preinstalled on any Windows 10 or higher machine so if you are targetting those you should not have to do anything. If however you are targetting older versions of Windows you must ensure .Net v4.6 or higher is installed either manually or as part of an installer.

    C++ Redistributable

    The native code has a dependency on the Visual C++ 2017 Redistributable package. This package contains code that is required to run code developed using C++ in Visual Studio and is very common amongst Windows applications.

    There are two ways to ensure this is available to your application:

    • Create an installer that includes the redistributable installer;
    • Package the required DLL files from the redistributable with your application;

    The first is the suggested method. Installing the redistributable via an installer allows it to be put into the windows update process, allowing bug fixes and security updates to be handled automatically.

    The second method is only advised if you need a complete standalone application, where you don't (or cannot) use an installation process. This requires you to package DLLs from the redistributable with your application.

    Creating an Installer

    There are many methods to create application installers and many tutorials available. We suggest you find a method suitable to your environment and application and utilise the tutorials online.

    Some methods include:

    Tutorials:

    You need to include the x86 c++ 2017 redistributable in the installer, there are many examples and documentation online to achieve this.

    Packaging DLLs

    Packaging the DLLs into your application involves copying the DLLs specified below into your application root and including in your application package.

    The best option is to install Visual Studio 2017 and locate the Program Files[ (x86)]\Microsoft Visual Studio\2017\edition\VC\Redist\MSVC\lib-version folder, eg: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Redist\MSVC\14.16.27012\x86\Microsoft.VC141.CRT

    Alternatively, download and install the x86 redistributable from the Microsoft website. This should install the DLLs into C:\Windows\System32 folder.

    Open the folder and copy the following DLLs to your application:

    • msvcp140.dll
    • vcruntime140.dll

    If you are having issues locating these files, feel free to contact us for help.

    You should ensure you are allowed to package these files as per the Microsoft Software License terms but generally these are safe to redistribute subject to the license terms. More information here: Redistributing Visual C++ Files

    You should get legal advice if you are unsure.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/windows/windows-notification-service/index.html b/docs/pushnotifications/windows/windows-notification-service/index.html index d8721df6fee..2d64deafbcc 100644 --- a/docs/pushnotifications/windows/windows-notification-service/index.html +++ b/docs/pushnotifications/windows/windows-notification-service/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Setup WNS

    Credentials

    Before you can send notifications using WNS, your app must be registered with the Store Dashboard. This will provide you with credentials for your app that your cloud service will use in authenticating with WNS. These credentials consist of a Package Security Identifier (SID) and a secret key.

    To perform this registration, sign in to Partner Center. After you create your app, you can retrieve the credentials bygoing to the WNS/MPNS page and clicking on the Live Services site link.

    The live services page will contain the credentials you need. In particular, you'll need to note:

    • Application Secret, or "client secret";
    • Package SID, "or client id".

    These credentials are used when sending notifications and not needed in your application. Your application needs no specific identifiers, however it must be created with the same Identity as the application in the store, ie you will see the Application Identity tag in the image above matches the AppxManifest below.

    Each app has its own set of credentials for its cloud service. These credentials cannot be used to send notifications to any other app.

    See the WNS message section for an example usage.

    AppxManifest

    The windows notifications UWP support requires a couple of additions to your AppxManifest in order to receive notification events when the user interacts with the notification.

    You will need to use the "Sign Separately" method to package your appx as described here.

    If you don't make these changes then your application will not receive all the notification events.

    During the "Update Content" step you will need to edit the AppxManifest.xml file contained in the pacakged files directory and add the following:

    • Declaration for xmlns:com
    • Declaration for xmlns:desktop
    • In the IgnorableNamespaces attribute, com and desktop
    • com:Extension for the COM activator
    • desktop:Extension for windows.toastNotificationActivation to declare your toast activator
    <Package
    ...
    xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
    xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
    IgnorableNamespaces="... com desktop">
    ...
    <Applications>
    <Application>
    ...
    <Extensions>

    <!--Register COM CLSID LocalServer32 registry key-->
    <com:Extension Category="windows.comServer">
    <com:ComServer>
    <com:ExeServer Executable="YOURAPPLICATION.exe" Arguments="-ToastActivated" DisplayName="Toast activator">
    <com:Class Id="4db090a5-b5c9-4cbf-97a6-dd6a431f8749" DisplayName="Toast activator"/>
    </com:ExeServer>
    </com:ComServer>
    </com:Extension>

    <!--Specify which CLSID to activate when toast clicked-->
    <desktop:Extension Category="windows.toastNotificationActivation">
    <desktop:ToastNotificationActivation ToastActivatorCLSID="4db090a5-b5c9-4cbf-97a6-dd6a431f8749" />
    </desktop:Extension>

    </Extensions>
    </Application>
    </Applications>
    </Package>

    You also need to replace YOURAPPLICATION with the name of the Executable attribute in the Application node.

    For example, this is the entire AppxManifest.xml for the distriqt test application:

    <?xml version="1.0" encoding="utf-8"?>
    <Package
    xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
    xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
    xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
    xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
    xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
    xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    xmlns:rescap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/3"
    xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
    xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"
    xmlns:desktop3="http://schemas.microsoft.com/appx/manifest/desktop/windows10/3"
    xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
    xmlns:wincap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/windowscapabilities/3"
    IgnorableNamespaces="uap4 wincap3 rescap3 desktop desktop2 desktop3 com">
    <Identity Name="distriqt.airnativeextensions" ProcessorArchitecture="x86" Publisher="CN=38CAD93E-B1A7-480F-B65D-3545798BA205" Version="1.0.0.0" />
    <Properties>
    <DisplayName>distriqt.airnativeextensions</DisplayName>
    <PublisherDisplayName>distriqt</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
    </Properties>
    <Resources>
    <Resource Language="en-us" />
    <Resource uap:Scale="100" />
    <Resource uap:Scale="125" />
    <Resource uap:Scale="150" />
    <Resource uap:Scale="200" />
    <Resource uap:Scale="400" />
    </Resources>
    <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.16299.15" />
    </Dependencies>
    <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <Capability Name="internetClient" />
    </Capabilities>
    <Applications>
    <Application Id="distriqt.airnativeextensions" Executable="testnotifications.exe" EntryPoint="Windows.FullTrustApplication">
    <uap:VisualElements DisplayName="distriqt.airnativeextensions" Description="distriqt.airnativeextensions" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
    <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\Square310x310Logo.png" Square71x71Logo="Assets\Square71x71Logo.png">
    <uap:ShowNameOnTiles>
    <uap:ShowOn Tile="square150x150Logo" />
    <uap:ShowOn Tile="wide310x150Logo" />
    <uap:ShowOn Tile="square310x310Logo" />
    </uap:ShowNameOnTiles>
    </uap:DefaultTile>
    </uap:VisualElements>

    <Extensions>
    <!--Register COM CLSID LocalServer32 registry key-->
    <com:Extension Category="windows.comServer">
    <com:ComServer>
    <com:ExeServer Executable="testnotifications.exe" Arguments="-ToastActivated" DisplayName="Toast activator">
    <com:Class Id="aa28441a-fba8-45dc-887e-149495769502" DisplayName="Toast activator"/>
    </com:ExeServer>
    </com:ComServer>
    </com:Extension>

    <!--Specify which CLSID to activate when toast clicked-->
    <desktop:Extension Category="windows.toastNotificationActivation">
    <desktop:ToastNotificationActivation ToastActivatorCLSID="aa28441a-fba8-45dc-887e-149495769502" />
    </desktop:Extension>

    </Extensions>
    </Application>
    </Applications>
    </Package>

    Terminology

    WNS refers to a "notification channel" that is created for you to send notifications to. This channel is the value that is returned as the "device token" from this extension.

    Supported Features

    WNS supports actions, selection and notification events.

    Actions need to be specified through the payload of the notification and any categories and actions specified through the Service aren't used.

    It doesn't support channels or groups currently.

    Authorisation is not required, and will always be in the authorised state.

    Topic subscriptions are not supported.

    - + \ No newline at end of file diff --git a/docs/pushnotifications/windows/windows-wns-message/index.html b/docs/pushnotifications/windows/windows-wns-message/index.html index c690eadc9f4..a4db2f62ef1 100644 --- a/docs/pushnotifications/windows/windows-wns-message/index.html +++ b/docs/pushnotifications/windows/windows-wns-message/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Windows WNS Message

    In order to send a message to WNS you will need the information you noted from the service setup:

    • Application Secret, or "client secret";
    • Package SID, "or client id".

    Using this information you request an "access token" from WNS and then send a notification using this access token to the user's "channel uri".

    The "channel uri" identifies the user and is used as the destination of a notification. This is returned via the "device token" accessors in this extension.

    var wnsChannelUri:String = PushNotifications.service.getDeviceToken();

    You then place the access token in the authorisation header of a post request to the channel uri, where the content of the request is the WNS payload.

    PHP Example

    The following is a simple example of using PHP to send a notification:

    <?php
    // SERVICE CONFIG
    $clientId = 'ms-app://s-1-15-2-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX';
    $clientSecret = '/XXYYXXYYXXYYXXYYXXYYXXYYXXYY';

    // USER - You will need to get this from the device
    $channelUri = 'https://sg2p.notify.windows.com/?token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

    //TOAST MESSAGE
    $toastMessage =
    "<toast launch='payload=%7B%22test%22%3A%22value%22%7D'>\
    <visual lang='en-US'>\
    <binding template='ToastGeneric'>\
    <image src='https://airnativeextensions.com/images/extensions/icons/ane-pushnotifications-icon.png' placement='appLogoOverride' />\
    <text>Test Notification</text>\
    <text>A notification sent via WNS</text>\
    </binding>\
    </visual>\
    </toast>";


    ////////////////////////////////////////////////////////////
    // GET ACCESS TOKEN
    //

    $fields = array(
    'grant_type' => 'client_credentials',
    'client_id' => "$clientId",
    'client_secret' => "$clientSecret",
    'scope' => 'notify.windows.com'
    );
    $fields_string = "";
    foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
    rtrim($fields_string, '&');

    $tokenRequest = curl_init();
    curl_setopt($tokenRequest, CURLOPT_URL, 'https://login.live.com/accesstoken.srf');
    curl_setopt($tokenRequest, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
    curl_setopt($tokenRequest, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($tokenRequest, CURLOPT_POST, count($fields));
    curl_setopt($tokenRequest, CURLOPT_POSTFIELDS, $fields_string);

    $output = json_decode(curl_exec($tokenRequest));
    curl_close($tokenRequest);
    $accessToken = $output->{'access_token'};



    ////////////////////////////////////////////////////////////
    // SEND PUSH
    //

    $sendPush = curl_init();

    $headers = array(
    'Content-Type: text/xml',
    "Content-Length: " . strlen($toastMessage),
    "X-WNS-Type: wns/toast",
    "Authorization: Bearer $accessToken"
    );

    curl_setopt($sendPush, CURLOPT_URL, $channelUri );
    curl_setopt($sendPush, CURLOPT_HEADER, true);
    curl_setopt($sendPush, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($sendPush, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($sendPush, CURLOPT_POST, 1);
    curl_setopt($sendPush, CURLOPT_POSTFIELDS, $toastMessage);

    $output = curl_exec($sendPush);
    curl_close($sendPush);

    ?>

    C# Documentation

    Microsoft has documentation on using C# to send a notification here:

    - + \ No newline at end of file diff --git a/docs/pushnotifications/windows/windows-wns-payload/index.html b/docs/pushnotifications/windows/windows-wns-payload/index.html index 70a2d3066ba..c6d29f24ac5 100644 --- a/docs/pushnotifications/windows/windows-wns-payload/index.html +++ b/docs/pushnotifications/windows/windows-wns-payload/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Windows WNS Payload

    The payload for the WNS notificaiton contains a Windows Toast XML structure.

    There are a couple of important fields you will need to specify in order that the notification works correctly with the Push Notifications extension.

    The simplest structure is a simple text notification, containing a single line of text:

    <toast launch='payload=PAYLOADFORTHENOTIFICATION'>
    <visual lang='en-US'>
    <binding template='ToastGeneric'>
    <text>Test Notification</text>
    </binding>
    </visual>
    </toast>

    The important thing to note in all notifications in the launch attribute of the root toast node. This must contain your payload.

    You can either specify it as a url encoded parameters as above incuding the payload parameter, or if this isn't included the entire value of the launch attribute will be returned as the payload. We recommend the parameter approach as it matches up with actions.

    Text

    You can include multiple lines of text, each wrapped in a text node, eg:

    <toast launch='payload=%7B%22test%22%3A%22value%22%7D'>
    <visual lang='en-US'>
    <binding template='ToastGeneric'>
    <text>Test Notification</text>
    <text>A notification sent via WNS</text>
    </binding>
    </visual>
    </toast>

    The first will be used as a title for the notification and subsequent lines will be used as the content of the notification.

    Images

    To add an image to your notification add an image node to your visual component, alongside the text nodes.

    <toast launch='payload=%7B%22test%22%3A%22value%22%7D'>
    <visual lang='en-US'>
    <binding template='ToastGeneric'>
    <image src='ms-appx:///assets/notifications/bigImage.png' placement='inline' />
    <text>Test Notification</text>
    <text>A notification sent via WNS</text>
    </binding>
    </visual>
    </toast>

    You can specify their placement as one of the following:

    • appLogoOverride: Acts as a large icon for the notification, appearing beside the text;
    • inline: Adds the image into the content of the notification;
    • hero: Adds the image at the top of the notification as a "hero" image (only supported on recent versions of Windows);

    Example:

    <image src='https://airnativeextensions.com/images/extensions/icons/ane-pushnotifications-icon.png' placement='appLogoOverride' />
    <image src='ms-appx:///assets/notifications/bigImage.png' placement='inline' />
    <image src='ms-appx:///assets/notifications/bigImage3.png' placement='hero' />

    The source of the notification as either a url or an application packaged asset.

    To specify a url, use the complete url of the file as the src attribute.

    <image src='https://airnativeextensions.com/images/extensions/icons/ane-pushnotifications-icon.png' placement='appLogoOverride' />

    To specify a packaged asset, use the relative path to the asset in your application package, prefixed by ms-appx:///. For example to use an asset packaged as assets/notifications/bigImage.png, you would use ms-appx:///assets/notifications/bigImage.png as the src:

    <image src='ms-appx:///assets/notifications/bigImage.png' placement='inline' />

    Actions

    Actions are added to a notification in an actions node alongside the visual node:

    <toast>
    <visual>
    </visual>
    <actions>
    </actions>
    </toast>

    The actions node contains a series of action nodes, each specifying an action button the user can press.

    <toast launch='payload=%7B%22test%22%3A%22value%22%7D'>
    <visual lang='en-US'>
    <binding template='ToastGeneric'>
    <text>Test Notification</text>
    </binding>
    </visual>
    <actions>
    <action
    content='Accept'
    activationType='foreground'
    arguments='action=ACCEPT_IDENTIFIER&amp;payload=%7B%22test%22%3A%22value%22%2C%20%22action%22%3A%22accept%22%7D' />
    </actions>
    </toast>

    An action has the following attributes:

    • content: The label on the action button;
    • activationType: Must be foreground;
    • arguments: The arguments need to be in a url encoded paramaters format in order that the extension can correctly process the user interaction with the action, and they must include:
      • action: The value being the identifier of the action returned in the ACTION event (ACCEPT_IDENTIFER in the above example);
      • payload: the payload of the notification returned in the ACTION event, this can be different or the same as the main notification payload in the launch parameter, but must be duplicated here. The above example contains a json string (url encoded):
        { 
        "test": "value",
        "action": "accept"
        }

    Example

    The following is an example of a payload containing all of the above features:

    <toast launch='payload=%7B%22test%22%3A%22value%22%7D'>
    <visual lang='en-US'>
    <binding template='ToastGeneric'>
    <image src='https://airnativeextensions.com/images/extensions/icons/ane-pushnotifications-icon.png' placement='appLogoOverride' />
    <image src='ms-appx:///assets/notifications/bigImage.png' placement='inline' />
    <image src='ms-appx:///assets/notifications/bigImage3.png' placement='hero' />
    <text>Test Notification</text>
    <text>A notification sent via WNS</text>
    </binding>
    </visual>
    <actions>
    <action content='Accept' arguments='action=ACCEPT_IDENTIFIER&amp;payload=%7B%22test%22%3A%22value%22%2C%20%22action%22%3A%22accept%22%7D' activationType='foreground' />
    <action content='Delete' arguments='action=DELETE_IDENTIFIER&amp;payload=%7B%22test%22%3A%22value%22%2C%20%22action%22%3A%22delete%22%7D' activationType='foreground' />
    </actions>
    </toast>

    References:

    - + \ No newline at end of file diff --git a/docs/reactivex/changelog/index.html b/docs/reactivex/changelog/index.html index 754f3bdd248..c3a2eb1e73a 100644 --- a/docs/reactivex/changelog/index.html +++ b/docs/reactivex/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    - + \ No newline at end of file diff --git a/docs/restartapp/add-the-extension/index.html b/docs/restartapp/add-the-extension/index.html index 729c8745b71..e1a803f6d79 100644 --- a/docs/restartapp/add-the-extension/index.html +++ b/docs/restartapp/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.RestartApp

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.RestartApp.ane # RestartApp extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (RestartApp.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/restartapp/changelog/index.html b/docs/restartapp/changelog/index.html index a518a9841cf..76b66bde367 100644 --- a/docs/restartapp/changelog/index.html +++ b/docs/restartapp/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v3.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.02.11 [v3.0.14]

    Add air package
    Add new documentation site including apm usage

    2020.03.20 [v3.0.013]

    Android X migration (resolves #3)

    2019.07.02 [v2.0.008]

    Android 64bit support (resolves #2)

    2019.01.11 [v1.0.007]

    v1.0 release build

    2019.01.09 [v1.0.006]

    Initial extension beta release

    2019.01.09 [v1.0.006]

    Initial extension beta release
    - + \ No newline at end of file diff --git a/docs/restartapp/index.html b/docs/restartapp/index.html index 9d171e81870..bda473fd752 100644 --- a/docs/restartapp/index.html +++ b/docs/restartapp/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:

    ❤️ Sponsor

    RestartApp

    The RestartApp extension gives you the ability to force a restart of your application, terminating the current process and triggering a relaunch of the application.

    Features

    • Restart your running application on the following platforms:
      • Android
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    if (RestartApp.service.canRestartApplication)
    {
    RestartApp.service.restartApplication();
    }

    - + \ No newline at end of file diff --git a/docs/restartapp/restart-application/index.html b/docs/restartapp/restart-application/index.html index 3fcf525ad29..7a718bd8f7d 100644 --- a/docs/restartapp/restart-application/index.html +++ b/docs/restartapp/restart-application/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Restart Application

    Restarting the application is simply a matter of calling the restartApplication() method:

    RestartApp.service.restartApplication();

    Calling this function will terminate and schedule an immediate restart of the current application.

    To check if restarting the application is supported on the current device platform and version you can check the canRestartApplication flag:

    if (RestartApp.service.canRestartApplication)
    {
    RestartApp.service.restartApplication();
    }
    else
    {
    // Not supported on this device / platform
    }
    - + \ No newline at end of file diff --git a/docs/rootchecker/add-the-extension/index.html b/docs/rootchecker/add-the-extension/index.html index 1563fc51105..85b0914015d 100644 --- a/docs/rootchecker/add-the-extension/index.html +++ b/docs/rootchecker/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.RestartApp

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.RootChecker.ane # RootChecker extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (RootChecker.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/rootchecker/changelog/index.html b/docs/rootchecker/changelog/index.html index 8dcd2448563..23afd7d0093 100644 --- a/docs/rootchecker/changelog/index.html +++ b/docs/rootchecker/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v1.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.02.15 [v1.0.13]

    Update docs to use apm
    Add air package

    2021.03.12 [v1.0.012]

    Updated to latest build process  
    Added Android-x64 support

    2020.03.25 [v1.0.010]

    Android X migration (resolves #1)

    2019.11.11 [v0.1.005]

    Updated images

    2019.11.11 [v0.1.005]

    Added license + updates images

    2019.11.11 [v0.1.005]

    Initial release
    - + \ No newline at end of file diff --git a/docs/rootchecker/index.html b/docs/rootchecker/index.html index 47236df88be..f2fd0c41feb 100644 --- a/docs/rootchecker/index.html +++ b/docs/rootchecker/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    RootChecker

    The RootChecker extension gives you the ability to check whether the current device has been "rooted".

    Features

    • Check for root access (jail broken device)

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    if (RootChecker.instance.isRooted)
    {
    // device has been rooted / jail broken
    }

    - + \ No newline at end of file diff --git a/docs/rootchecker/root-check/index.html b/docs/rootchecker/root-check/index.html index d70370c4e97..9b8750b90f6 100644 --- a/docs/rootchecker/root-check/index.html +++ b/docs/rootchecker/root-check/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Root Check

    To check whether the device has been "rooted" or jail broken you check the isRooted flag.

    Calling this will perform several native tests in order to guess whether the device is rooted. It is not a complete check as once a device has root access they can modify the device as they see fit to avoid detection.

    if (RootChecker.instance.isRooted)
    {
    // device has been rooted / jail broken
    }
    - + \ No newline at end of file diff --git a/docs/scanner/add-the-extension/index.html b/docs/scanner/add-the-extension/index.html index e27b953ba30..8096ad9d6c8 100644 --- a/docs/scanner/add-the-extension/index.html +++ b/docs/scanner/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Scanner

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Scanner.ane # Scanner extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    • You will need to set the usage description strings for use in the authorisation dialogs. Call the following to step through the configuration values for this extension:
    apm project config set com.distriqt.Scanner

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Scanner.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/scanner/changelog/index.html b/docs/scanner/changelog/index.html index 6901b3fe3af..bf496368dda 100644 --- a/docs/scanner/changelog/index.html +++ b/docs/scanner/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.25 [v5.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #70)
    feat(android): Move to new permissions request process

    2022.02.11 [v5.0.62]

    Update for Android 31
    Update docs to use apm

    2021.10.12 [v5.0.61]

    Add air package

    2021.08.03 [v5.0.60]

    Android: Fixed issue with single result scan activity (resolves #64)
    Added more refocus functionality
    Android: Added security to activities

    2021.04.14 [v5.0.054]

    Corrected default implementation (SWC) function definitions to match native

    2021.03.22 [v5.0.053]

    Added more robust checks for camera modes on Android and ability to use front camera with the activity method
    Removed ios_min_version

    2021.03.05 [v5.0.046]

    Added ability to position a camera preview within a viewport for scanning (resolves #58, resolves #36)
    Added ability to scan a bitmap data reference for symbols directly (resolves #16)

    2020.11.25 [v4.2.017]

    iOS: Resolved issue with new view controller modal presentation style (resolves #61)

    2020.05.08 [v4.1.013]

    iOS: Replaced UIWebView usage with WKWebView (resolves #59)

    2020.03.20 [v4.0.008]

    Android X migration (resolves #55)

    2019.08.15 [v3.0.004]

    Android 64bit support (resolves #50)
    Updated minimum iOS version to 9.0

    2019.02.21 [v2.2.034]

    Updated minimum iOS version option (resolves #45)

    2019.01.11 [v2.1.032]

    Removed application keys

    2018.06.20 [v2.0.019]

    iOS: Added information about usage description strings (resolves #38)

    2017.10.26 [v2.0.017]

    Updated to better handle Android application ids

    2017.07.18 [v2.0.015]

    Updated documentation

    2017.07.18 [v2.0.013]

    Android: Added torch mode implementation (resolves #30)

    2017.07.10 [v2.0.010]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.30 [v2.0.008]

    Updated documentation

    2016.12.30 [v2.0.008]

    Updated documentation

    2016.12.30 [v2.0.008]

    Updated documentation

    2016.12.30 [v2.0.008]

    Update SDKs + new documentation

    2016.10.24 [v2.0.004]

    iOS: Removed focus range restriction on stop scan (#25)

    2016.09.16 [v2.0.001]

    Minor updates and new version system

    2016.07.21

    Added missing example files (resolves #22)

    2016.07.02

    Removed invalid iOS simulator build (resolves #20)

    2016.04.04

    iOS: Fixed UI ordering (resolves #18)
    Android: Added authorisation process for Marshmallow (resolves #15)
    Android: Updated zbar lib

    2016.02.19

    Added authorisation status to check for camera permission (resolves #13, resolves #3)

    2015.10.04

    iOS: Update for iOS 9, black bar at bottom of scanner (resolves #10)

    2015.07.02

    Android: Fixed orientation issue with default landscape devices (resolves #7)
    Android: Implemented checks to ensure camera is available on resume (resolves #4)

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.02.03

    Added check for .debug suffix in application id

    2014.12.22

    iOS: Included arm64 support (resolves #1) 
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.11

    Android: Corrected dispose function crashing application while scanner running (fixes distriqt/airnativeextensions#315)

    2014.12.08

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.02

    New application based key check, removing server checks

    2014.10.19

    Update for iOS 8 and Android Additions
    - iOS: iOS 8 updates
    - iOS: Added overlay in ScannerOptions to use as a custom target area (resolves #154)
    - Updated singleResult documentation (resolves #231)
    - Android: Added auto-orientation code
    - Android: Added overlay in ScannerOptions to use as a custom target area
    - + \ No newline at end of file diff --git a/docs/scanner/index.html b/docs/scanner/index.html index bae25e1b74a..253e4be51e3 100644 --- a/docs/scanner/index.html +++ b/docs/scanner/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Scanner

    The Scanner extension allows you to display an interface using the camera to scan for codes such as QR Codes, bar codes and other such encoded information. It supports many popular symbologies (types of bar codes) including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.

    However the particular support will be determined by the underlying algorithm in use.

    The extension currently supports the following algorithms for code detection:

    Features

    • Provides the ability to create a bar code scanning interface as a:
      • Fullscreen activity; or,
      • Camera viewport contained within your application;
    • Uses the built in default camera for scanning;
    • Works across iOS and Android with the same code;
    • Sample project code and ASDocs reference;

    The simple API allows you to quickly integrate scanning in your AIR application. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with the extension quickly and easily.

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    Scanner.service.addEventListener( ScannerEvent.CODE_FOUND, codeFoundHandler );

    Scanner.service.startScanInViewport(
    new ViewportOptions()
    .setFrame( 100, 100, 500, 300 )
    );

    function codeFoundHandler( event:ScannerEvent ):void
    {
    trace( "code found: " + event.result.data );
    }

    More information here:

    com.distriqt.Scanner

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/scanner/migrating-to-androidx/index.html b/docs/scanner/migrating-to-androidx/index.html index 55dfb59f816..02f2da79fc3 100644 --- a/docs/scanner/migrating-to-androidx/index.html +++ b/docs/scanner/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/scanner/migrating-to-v5.1/index.html b/docs/scanner/migrating-to-v5.1/index.html index c29c3de6fe1..fe2a8142d30 100644 --- a/docs/scanner/migrating-to-v5.1/index.html +++ b/docs/scanner/migrating-to-v5.1/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v5.1

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/scanner/migrating-to-version-5/index.html b/docs/scanner/migrating-to-version-5/index.html index dfa97955b03..14b159e4dbf 100644 --- a/docs/scanner/migrating-to-version-5/index.html +++ b/docs/scanner/migrating-to-version-5/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to version 5

    Version 5 brings several new features including:

    - Displaying the camera preview in a viewport;

    With these new features we have cleaned up the API and refactored several of the methods.

    Options

    Most notably the old ScannerOptions class has been broken up into several options classes controlling different aspects of the process:

    • ScannerOptions : Now only contains options to control the scanning algorithm (eg symbologies);
    • ActivityOptons: Contains all the view elements and text that is used in the fullscreen scanning activity (which was the only method in the previous versions);
    • CameraOptions: Contains options for configuring the camera such as whether to use the front or rear camera;
    • ViewportOptions (NEW): Contains options for configuring the viewport implementation;

    These classes are used in the start scanning methods, used to initiate the scanning process.

    Scanning

    There are now 2 approaches to use to create your scanning interface.

    • startScanActivity(): This method is equivalent to the old startScan() method but with the new options;
    • startScanInViewport(): Allows you to launch a camera preview contained to a viewport within your application;

    Migrating

    If you wish to continue using the previous full screen activity method the startScan() method has been removed and you should now use startScanActivity().

    So you may have something like the following code:

    var options:ScannerOptions = new ScannerOptions();
    options.singleResult = true;

    Scanner.service.startScan( options );

    This should become:

    var uiOptions:ActivityOptions = new ActivityOptions();
    uiOptions.singleResult = false;

    var scanOptions:ScannerOptions = new ScannerOptions();

    var cameraOptions:CameraOptions = new CameraOptions();

    Scanner.service.startScanActivity(
    uiOptions,
    scanOptions,
    cameraOptions
    );

    You can pass null for any of these options if you just wish to use the defaults. eg the above is the equivalent of:

    var uiOptions:ActivityOptions = new ActivityOptions();
    uiOptions.singleResult = false;

    Scanner.service.startScanActivity( uiOptions );

    Events

    The events are mainly the same except that the code found results are no longer directly attached to the Event object, but contained within a ScanResult instance.

    So the following code:

    Scanner.service.addEventListener( ScannerEvent.CODE_FOUND, codeFoundHandler );

    function codeFoundHandler( event:ScannerEvent ):void
    {
    trace( event.data );
    trace( event.symbologyType );
    }

    becomes:

    Scanner.service.addEventListener( ScannerEvent.CODE_FOUND, codeFoundHandler );

    function codeFoundHandler( event:ScannerEvent ):void
    {
    trace( event.result.data );
    trace( event.result.symbologyType );
    }
    - + \ No newline at end of file diff --git a/docs/scanner/requesting-access/index.html b/docs/scanner/requesting-access/index.html index ed43bc32de3..781f444bf23 100644 --- a/docs/scanner/requesting-access/index.html +++ b/docs/scanner/requesting-access/index.html @@ -13,7 +13,7 @@ - + @@ -29,7 +29,7 @@ be able to ask multiple times.

    You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

    On iOS the user must be asked at runtime, which you only get one chance to ask, after which you must direct the user to manually change the permissions in the settings.

    The following code will work across both platforms:

    trace( "Scanner Authorisation Status: " + Scanner.service.authorisationStatus() );
    Scanner.service.addEventListener( AuthorisationEvent.CHANGED, authorisationChangedHandler );
    switch (Scanner.service.authorisationStatus())
    {
    case AuthorisationStatus.NOT_DETERMINED:
    case AuthorisationStatus.SHOULD_EXPLAIN:
    // REQUEST ACCESS: This will display the permission dialog
    Scanner.service.requestAccess();
    return;

    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    case AuthorisationStatus.RESTRICTED:
    // ACCESS DENIED: You should inform your user appropriately
    return;

    case AuthorisationStatus.AUTHORISED:
    // AUTHORISED: Scanner will be available
    break;
    }

    You will then receive a change event if the user accepted your permission request:

    private function authorisationChangedHandler( event:AuthorisationEvent ):void
    {
    switch (event.status)
    {
    case AuthorisationStatus.SHOULD_EXPLAIN:
    // Should display a reason you need this feature
    break;

    case AuthorisationStatus.AUTHORISED:
    // AUTHORISED: Camera will be available
    break;

    case AuthorisationStatus.RESTRICTED:
    case AuthorisationStatus.DENIED:
    // ACCESS DENIED: You should inform your user appropriately
    break;
    }
    }

    Usage Description

    You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

    The image below is an example of the authorisation dialog. The content "Require Camera" is the usage description message you can set.

    You set these values through adding the usage description keys to your application descriptor's info additions or simply by setting up your configuration options in your apm project.

    - + \ No newline at end of file diff --git a/docs/scanner/scanning-bitmap-data/index.html b/docs/scanner/scanning-bitmap-data/index.html index 10d0814fe46..05a27322161 100644 --- a/docs/scanner/scanning-bitmap-data/index.html +++ b/docs/scanner/scanning-bitmap-data/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Scanning Bitmap Data

    This method of scanning doesn't utilise the camera directly, instead you can use other methods to acquire image data and use the extension to scan the image for any symbols directly.

    For example you could allow the user to select an image from their camera roll or capture an image using the CameraUI interface.

    Once you have acquired your image data, you can scan the image for symbols by calling the scanBitmap() method. This method is synchronous.

    var image:BitmapData = ...; // Your image data

    var scanResults:Array = Scanner.service.scanBitmap( image );

    The scanResults array returned from this method is an Array of ScanResult objects.

    (This is the same format as the data returned in the ScannerEvent.CODE_FOUND event from the camera based methods).

    var scanResults:Array = Scanner.service.scanBitmap( image );

    for each (var result:ScanResult in scanResults)
    {
    trace( "code found: " + result.data
    + "[" + result.symbologyType + "] " );
    }

    If no results were found the scanResults array will be empty.

    Options

    When scanning bitmaps there are some options that can be used. The ScannerOptions class represents any options relating to the scanning algorithm to use, such as the list of symbol types to enable.

    To create a ScannerOptions you can use the properties on an instance of the class or use the builder methods.

    var scanOptions:ScannerOptions = new ScannerOptions();
    scanOptions.symbologies = [ Symbology.QRCODE ];

    or

    var scanOptions:ScannerOptions = new ScannerOptions()
    .setSymbologies( [ Symbology.QRCODE ] );

    In order to set these options call setScanBitmapOptions() passing the ScannerOptions instance. For example:

    Scanner.service.setScanBitmapOptions(
    new ScannerOptions()
    .setSymbologies( [ Symbology.QRCODE ] )
    );

    You can call this function once and it will apply to every call of scanBitmap() (unless you dispose the extension).

    - + \ No newline at end of file diff --git a/docs/scanner/scanning/index.html b/docs/scanner/scanning/index.html index 26033b77b78..1a71d6df168 100644 --- a/docs/scanner/scanning/index.html +++ b/docs/scanner/scanning/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Scanning

    Once you have setup your application and gained permission to access the camera, then there are three approaches you can take to scan, 2 that utilise the camera directly and a third option to scan a provided image.

    The first is using a fullscreen activity which will take over the fullscreen of your application, presenting a camera preview and some UI elements.

    The second is to show a preview contained within an area (viewport) of your application. This view will sit above any other elements however you can create a UI around the preview to control the scanner or present feedback to your user.

    The third is to scan an image directly by passing bitmap data to the extension.

    Below we describe the methods using the camera. You can find information on bitmap data scanning here.

    Authorisation

    Ensure you have requested authorisaton to use the camera before attempting to use these methods.

    Scan Activity

    To start the fullscreen scan activity, call the startScanActivity() method passing in the required options. This method takes several parameters:

    • ActivityOptions: instance describing the appearance of the fullscreen UI elements;
    • ScannerOptions: describing the options for the scanning algorithm (eg symbologies);
    • CameraOptions: options for configuring the camera such as whether to use the front or rear camera;

    You can pass in null (the default) for all the options to simply use the defaults.

    Scanner.service.startScanActivity();

    This function will return a Boolean value indicating the success of the start request. If it returns false there may be another scan in progress or there was an error.

    To specify options:

    var scanOptions:ScannerOptions = new ScannerOptions();
    scanOptions.symbologies = [];

    var uiOptions:ActivityOptions = new ActivityOptions();
    uiOptions.singleResult = false;
    uiOptions.heading = "Scan a barcode";
    uiOptions.cancelLabel = "FINISH";
    uiOptions.colour = 0x4863A0;
    uiOptions.textColour = 0xFFFFFF;

    uiOptions.overlay = _overlay.bitmapData;
    uiOptions.overlayAutoScale = true;

    var cameraOptions:CameraOptions = new CameraOptions();
    cameraOptions.refocusInterval = 0;
    cameraOptions.camera = CameraOptions.CAMERA_REAR;
    cameraOptions.torchMode = CameraOptions.TORCH_AUTO;

    var success:Boolean = Scanner.service.startScanActivity(
    scanOptions,
    uiOptions,
    cameraOptions
    );

    Scan in Viewport

    To start the scan in a viewport call the startScanInViewport() method passing in the required options. This method takes several parameters:

    • ViewportOptions: instance describing the viewport for the camera preview;
    • ScannerOptions: describing the options for the scanning algorithm (eg symbologies);
    • CameraOptions: options for configuring the camera such as whether to use the front or rear camera;

    You can pass in null (the default) for all the options to simply use the defaults, however we suggest you at least pass a valid ViewportOptions instance to set the initial frame for the camera preview.

    var frame:Rectangle = ...;

    var viewportOptions:ViewportOptions = new ViewportOptions()
    .setFrame( frame );

    Scanner.service.startScanInViewport( viewportOptions );

    To specify all the options:

    var viewportOptions:ViewportOptions = new ViewportOptions()
    .setFrame( new Rectangle( 100, 100, 500, 300 ) );

    var scanOptions:ScannerOptions = new ScannerOptions()
    .setSymbologies( [ Symbology.QRCODE ] );

    var cameraOptions:CameraOptions = new CameraOptions()
    .setCamera( CameraOptions.CAMERA_REAR )
    .setTorchMode( CameraOptions.TORCH_AUTO );

    var success:Boolean = Scanner.service.startScanInViewport(
    viewportOptions,
    scanOptions,
    cameraOptions
    );

    Updating the Viewport

    You can change the viewport frame for the camera preview while scanning is in progress.

    To change the viewport frame call the setScanViewport() method passing the new frame:

    Scanner.service.setScanViewport(
    new Rectangle( 50, 200, 600, 600 )
    );

    Stop Scanning

    To stop the scan process, call the stopScan() method. This will stop the active scan process independent of the method you are using to scan (i.e. activity or viewport).

    Scanner.service.stopScan();

    This will stop the scan process and release any camera resources.

    Events

    There are several events dispatched at various points of the scanning process, these are defined by the ScannerEvent and ScannerErrorEvent classes.

    • ScannerEvent.CODE_FOUND: Dispatched when a code was detected;
    • ScannerEvent.SCAN_START: Dispatched when a scanning process was started;
    • ScannerEvent.SCAN_STOPPED: Dispatched when a scanning process was stopped / terminated;
    • ScannerEvent.CANCELLED: Dispatched when the user cancels the scan activity;
    • ScannerErrorEvent.ERROR: Dispatched when an error occurred in the scan process;

    The most important is probably the CODE_FOUND event that is dispatched with the scan result. This event has a result property that contains information about the scan result as an instance of the ScanResult class.

    Scanner.service.addEventListener( ScannerEvent.CODE_FOUND, codeFoundHandler );

    function codeFoundHandler( event:ScannerEvent ):void
    {
    var result:ScanResult = event.result;

    trace( "code found: " + result.data );
    }

    Options

    When scanning there are some options that can be used.

    Scanner Options

    The ScannerOptions class represents any options relating to the scanning algorithm to use, such as the list of symbol types to enable. An instance of this can be passed to any of the scan methods.

    To create a ScannerOptions you can use the properties on an instance of the class or use the builder methods.

    var scanOptions:ScannerOptions = new ScannerOptions();
    scanOptions.symbologies = [ Symbology.QRCODE ];

    or

    var scanOptions:ScannerOptions = new ScannerOptions()
    .setSymbologies( [ Symbology.QRCODE ] );

    Camera Options

    The CameraOptions class represents any configuration options around the camera functionality, such as device position.

    To create a CameraOptions you can use the properties on an instance of the class or use the builder methods.

    var cameraOptions:CameraOptions = new CameraOptions();
    cameraOptions.camera = CameraOptions.CAMERA_REAR;
    cameraOptions.torchMode = CameraOptions.TORCH_AUTO;

    or

    var cameraOptions:CameraOptions = new CameraOptions()
    .setCamera( CameraOptions.CAMERA_REAR )
    .setTorchMode( CameraOptions.TORCH_AUTO );

    Viewport Options

    The ViewportOptions class represents the options to define the area of the screen to use as the viewport for the startScanInViewport() method.

    The most important option here is the frame which defines the area of the screen to place the camera preview. It should be in native pixel coordinates.

    var viewportOptions:ViewportOptions = new ViewportOptions()
    .setFrame( new Rectangle( 100, 100, 500, 300 ) );

    Activity Options

    The ActivityOptions class describes the appearance of the fullscreen UI elements for the startScanActivity() method.

    Options include:

    • cancelLabel: The label to place on the cancel button;
    • singleResult: If this option is true then the scanner will automatically stop and close the interface when a code is successfully scanned;
    • colour: The colour for the background of the interface elements;
    • textColour: The text colour for the text elements;

    For more details see the asdocs reference for the ActivityOptions class.

    - + \ No newline at end of file diff --git a/docs/sensormanager/add-the-extension/index.html b/docs/sensormanager/add-the-extension/index.html index 0aff558a06d..c498e8221f6 100644 --- a/docs/sensormanager/add-the-extension/index.html +++ b/docs/sensormanager/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.SensorManager

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.SensorManager.ane # SensorManager extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (SensorManager.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/sensormanager/changelog/index.html b/docs/sensormanager/changelog/index.html index 46df893d341..2abe223520f 100644 --- a/docs/sensormanager/changelog/index.html +++ b/docs/sensormanager/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v1.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2022.02.13 [v1.0.10]

    Add air package
    Update docs to use apm
    Initial release
    - + \ No newline at end of file diff --git a/docs/sensormanager/index.html b/docs/sensormanager/index.html index 483eae1230f..c491d6d286a 100644 --- a/docs/sensormanager/index.html +++ b/docs/sensormanager/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    SensorManager

    The SensorManager extension gives you the ability to retrieve data from the device sensors.

    The objective is to centralise some of the simpler sensors to provide a simple common interface for detecting sensor data and changes from the device hardware.

    Features:

    • Proximity sensor
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    SensorManager.service.proximity.addEventListener( ProximityEvent.CHANGED, proximity_changedHandler );
    SensorManager.service.proximity.startMonitoring();

    function proximity_changedHandler( event:ProximityEvent ):void
    {
    trace( "proximity changed: " + event.state );
    }

    - + \ No newline at end of file diff --git a/docs/sensormanager/proximity/index.html b/docs/sensormanager/proximity/index.html index e9ce68970fc..68b32195645 100644 --- a/docs/sensormanager/proximity/index.html +++ b/docs/sensormanager/proximity/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Proximity

    The proximity sensor is a sensor that lets you determine how close the face of a device is to an object (known as the proximity sensor). Most commonly this is used to detect if the user is holding the device to their face (eg during a phone call) so that the device can deactivate the screen and controls.

    The proximity sensor is accessed through the proximity property on the SensorManager singleton:

    SensorManager.service.proximity 

    This object dispatches events and provides the interface for you to access the proximity sensor.

    Monitoring Proximity

    In order to start monitoring proximity you need to call startMonitoring(). This function will initiate proximity detection.

    SensorManager.service.proximity.startMonitoring();

    After this has been called ProximityEvent.CHANGED events will be dispatched whenever the proximity state changes.

    SensorManager.service.proximity.addEventListener( ProximityEvent.CHANGED, proximity_changedHandler );


    function proximity_changedHandler( event:ProximityEvent ):void
    {
    trace( "proximity changed: " + event.state );
    }

    You can also directly access the current state at any time using the proximityState property:

    var state:String = SensorManager.service.proximity.proximityState;

    The values of the proximity state are definded in the ProximityState class:

    • ProximityState.UNKNOWN: The state has yet to be determined or is unavailable;
    • ProximityState.NEAR: The user is near to the device;
    • ProximityState.FAR: The user is far from the device;
    caution

    On iOS the screen will be automatically dimmed when the proximity sensor is enabled and the proximity state is determined to be "near" (close to the user).

    Stop Monitoring

    To stop proximity monitoring you call the stopMonitoring() function.

    SensorManager.service.proximity.startMonitoring();

    After calling this the proximity state will be invalid.

    You should also remove any proximity event listeners you may have added.

    SensorManager.service.proximity.removeEventListener( ProximityEvent.CHANGED, proximity_changedHandler );
    - + \ No newline at end of file diff --git a/docs/share/add-the-extension/index.html b/docs/share/add-the-extension/index.html index 07a2cd85109..6df8769cb74 100644 --- a/docs/share/add-the-extension/index.html +++ b/docs/share/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ when certain permissions are requested. If you are sharing images then there is a chance the user may select to save to their camera roll in which case the following is displayed the first time your user attempts to access the camera roll.

    From iOS 10 you must add a string to your Info Addition to set the text in this dialog:

    <key>NSPhotoLibraryUsageDescription</key>
    <string>Access to photo library is required to save images.</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>Access to photo library is required to save images.</string>

    The second key was added in iOS 11.2. You should add both keys to your info additions.

    Android

    Queries

    Android 11 introduces changes related to package visibility. These changes affect apps only if they target Android 11. In order for you to correctly query if an application is installed you will need to add the package names you wish to query to the manifest.

    If you are going to be launching or querying installed applications then you must define the package name of these applications in your additions. For example the following adds WhatsApp and Instagram:

    <queries>
    <package android:name="com.whatsapp" />
    <package android:name="com.instagram.android" />
    </queries>

    To add these additions you need to add some additional configuration. Firstly add a custom Android configuration file by running:

    apm generate config android

    Edit the config/android/AndroidManifest.xml file that was generated to resemble the following, adding the queries node:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <queries>
    <package android:name="com.whatsapp" />
    <package android:name="com.instagram.android" />
    </queries>

    </manifest>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    iOS

    Usage Description

    You can customise the usage description messages as you see fit to suit your application. These messages are displayed in the main body area of the iOS authorisation dialog with the title and buttons being standard (and not customisable).

    The image below is an example of the authorisation dialog. The content "Access to photo library is required to save images." is the usage description message you can set.

    You set these values through adding the usage description keys to your application descriptor's info additions or simply by setting up your configuration options in your apm project.

    Query Schemes

    If you are going to be launching or querying installed applications then you must define the schemes of these applications in your additions. For example the following adds WhatsApp and Instagram:

    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>instagram</string>
    <string>whatsapp</string>
    </array>

    To add these additions you need to add some additional configuration. Firstly add a custom iOS configuration file by running:

    apm generate config ios

    Edit the config/ios/InfoAdditions.xml file that was generated to resemble the following, adding the LSApplicationQueriesSchemes node:

    <plist version="1.0">
    <dict>

    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>instagram</string>
    <string>whatsapp</string>
    </array>

    </dict>
    </plist>

    Once you have added this configuration run the steps above to update / generate your application descriptor.

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    Core.init();
    if (Share.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/share/add-the-plugin/index.html b/docs/share/add-the-plugin/index.html index c055f500e6a..944109a15f2 100644 --- a/docs/share/add-the-plugin/index.html +++ b/docs/share/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Plugin

    First step is always to add the plugin to your development environment.

    Asset Store

    Open the Asset Store in your browser and add the plugin to your assets.

    Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

    Manual Installation

    In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.Share.unitypackage.

    You can manually download the extension from our repository:

    Import the Plugin

    This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

    The plugin will be added to your project and you can now use the plugins functionality in your application.

    Resolve Android Dependencies

    This plugin depends on some common Android libraries, particularly the Google Play Core Library, which enables in-app reviews.

    You can get these dependencies using one of the following methods.

    Unity Jar Resolver

    This is the suggested method.

    Use the Unity Jar Resolver plugin to download and manage the Android dependencies.

    Importing

    If you already use the Unity Jar Resolver in your project you can skip this step.

    • Download the latest version of the Unity Jar Resolver
    • Import the plugin by selecting Assets / Import Package / Custom Package ... and locate the plugin you downloaded. The plugin will be in the zip named: external-dependency-manager-latest.unitypackage
    • In the Import Unity Package window, click Import

    Resolving

    By default, the resolver should run automatically and will add the dependencies required by this plugin.

    If you have need to resolve the dependencies manually then you will need to:

    • Open the menu under: Assets / External Dependency Manager / Android Resolver
    • Select Resolve or Force Resolve

    More information on the Unity Jar Resolver can be found here

    Custom Gradle Template

    Unity's in-built gradle build support and exporting to android studio does not support per plugin gradle script. Therefore, this plugin cannot add the dependencies by itself.

    The mainTemplate.gradle is generated when you enable the Custom Gradle Template property on the Player window.

    The build.gradle exists in generated Gradle project when you enable the Export Project property on the Player window and Build the project.

    Update the dependencies section in your mainTemplate.gradle or build.gradle as below:

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.google.android.play:core:1.9.1'
    }
    Proguard

    If you are using a custom proguard configuration you may need to add the following line to ensure the interface class for the plugin is accessible to unity at runtime.

    -keep class com.distriqt.extension.share.ShareUnityPlugin {*;}

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Share.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/share/android-events/index.html b/docs/share/android-events/index.html index 5daa2688b06..15007f9807e 100644 --- a/docs/share/android-events/index.html +++ b/docs/share/android-events/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Android Events

    A small note about events on Android.

    The result event may not always return success. The extension returns the event code returned from the application however as a lot of applications on Android don't necessarily respond with success or failure events you will most likely just get a ShareEvent.CLOSED.

    So you should be prepared to treat a cancelled or closed event as a success.

    - + \ No newline at end of file diff --git a/docs/share/appextension---introduction/index.html b/docs/share/appextension---introduction/index.html index 74ccd2339fd..925d5bb7f68 100644 --- a/docs/share/appextension---introduction/index.html +++ b/docs/share/appextension---introduction/index.html @@ -13,7 +13,7 @@ - + @@ -33,7 +33,7 @@ to use the native development tools, namely Xcode to create the App Extension and then you can package this as part of your AIR application by placing it in a specific place in your package.

    - + \ No newline at end of file diff --git a/docs/share/appextension---setup/index.html b/docs/share/appextension---setup/index.html index b2c820edf91..b139c4debb8 100644 --- a/docs/share/appextension---setup/index.html +++ b/docs/share/appextension---setup/index.html @@ -13,7 +13,7 @@ - + @@ -40,7 +40,7 @@ by unzipping your application's ipa and looking for the appex file in the folder:

    unzip APPLICATION.ipa

    Now if you install this application you should see your extension appear in the iOS share menu.

    Next steps

    Right now the extension doesn't really do alot, just installs itself as a potential avenue for share activities.

    Next we need to add some code to the App Extension.

    - + \ No newline at end of file diff --git a/docs/share/appextension---share-extension/index.html b/docs/share/appextension---share-extension/index.html index ed5e7e616f4..373f191b6ad 100644 --- a/docs/share/appextension---share-extension/index.html +++ b/docs/share/appextension---share-extension/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    AppExtension - Share Extension

    Share Extension Functionality

    TODO::

    Some code for your main App Extension file:

    Your view controller should look something like the following to start:

    @interface ShareViewController ()

    @end

    @implementation ShareViewController

    - (BOOL)isContentValid {
    // Do validation of contentText and/or NSExtensionContext attachments here
    return YES;
    }

    - (void)didSelectPost {
    // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.

    // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
    }

    - (NSArray *)configurationItems {
    // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
    return @[];
    }

    @end

    This is just a rough dump of some code I was playing with to get a url to share

    @implementation ShareViewController
    {
    NSUInteger _itemCount;
    NSString* _invokeArgs;
    }


    - (BOOL) isContentValid
    {
    // Do validation of contentText and/or NSExtensionContext attachments here
    return YES;
    }

    - (void) didSelectPost
    {
    // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
    NSLog( @"distriqt:SHAREEXTENSION:didSelectPost" );

    NSLog( @"distriqt:SHAREEXTENSION:%@", self.contentText );

    NSExtensionItem* item = self.extensionContext.inputItems.firstObject;

    _invokeArgs = NULL;
    _itemCount = item.attachments.count;

    for (NSItemProvider* itemProvider in item.attachments)
    {
    if ([itemProvider hasItemConformingToTypeIdentifier: (NSString*)kUTTypeURL])
    {
    NSLog( @"distriqt:SHAREEXTENSION:item is url" );
    [itemProvider loadItemForTypeIdentifier: (NSString*)kUTTypeURL
    options: nil
    completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error)
    {
    NSURL* url = (NSURL*)item;
    NSLog( @"distriqt:SHAREEXTENSION:loaded:%@", url );
    if ([url.absoluteString rangeOfString: @"youtube"].location == NSNotFound)
    {

    }
    else
    {

    }
    [self invokeApp: url.absoluteString];
    }];
    }
    else if ([itemProvider hasItemConformingToTypeIdentifier: (NSString*)kUTTypeImage])
    {
    NSLog( @"distriqt:SHAREEXTENSION:item is image" );
    [itemProvider loadItemForTypeIdentifier: (NSString*)kUTTypeImage
    options: nil
    completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error)
    {
    [self invokeApp: @""];
    }];
    }
    }

    }


    - (NSArray *) configurationItems
    {
    // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
    return @[];
    }


    - (void) invokeApp: (NSString *)invokeArgs
    {
    // Prepare the URL request
    // this will use the custom url scheme of your app
    // and the paths to the photos you want to share:
    NSString * urlString = [NSString stringWithFormat: @"%@://%@", @"distriqt-test", ( NULL == invokeArgs ? @"" : invokeArgs ) ];
    NSURL * url = [NSURL URLWithString: urlString];

    NSString *className = @"UIApplication";
    if (NSClassFromString( className ))
    {
    id object = [ NSClassFromString(className) performSelector: @selector(sharedApplication) ];
    [object performSelector: @selector(openURL:) withObject: url];
    }

    // Now let the host app know we are done, so that it unblocks its UI:
    [super didSelectPost];
    }

    @end

    This code uses a custom url scheme to launch the application so you'll need to add the following to your InfoAdditions in your application descriptor:

        <key>CFBundleURLTypes</key>
    <array>
    <dict>
    <key>CFBundleURLSchemes</key>
    <array>
    <string>distriqt-test</string>
    </array>
    </dict>
    </array>
    - + \ No newline at end of file diff --git a/docs/share/changelog/index.html b/docs/share/changelog/index.html index 320d47d6752..eafa522d8cc 100644 --- a/docs/share/changelog/index.html +++ b/docs/share/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.07.06 [v7.6.0]

    feat(unity,android): new implementation of callbacks allowing share events on android
    feat(unity,android): update core lib to new common location

    2023.06.16 [v7.4.2]

    fix(unity,android): update manifest requirements
    fix(unity,ios): correct activity type returned from sharing on iOS

    2023.05.19 [v7.4.1]

    fix(android): update implicit pending intents to explicit

    2023.01.24 [v7.4.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #201)
    feat(android): Move to new permissions request process

    2022.12.06 [v7.3.0]

    feat(android): add ability to add description to share file functionality (resolves #195)

    2022.08.08 [v7.2.0]

    fix(ios): fix issue with new page style views dismissal not being detected
    feat(android): add ability to clear cached files (resolves #196)

    2022.04.13 [v7.1.3]

    Android: Fix preview image security exception when displayed in application chooser (resolves #194)

    2022.03.09 [v7.1.2]

    Android: Add missing queries entry for email availability check
    Update air package dependencies
    Correct links in documentation

    2022.02.13 [v7.1.1]

    Update for Android 31
    Update docs to use apm

    2022.01.07 [v7.1.0]

    Add scAddress to the SMS object to specify the service center address (resolves #189)

    2021.10.12 [v7.0.12]

    Add air package

    2021.08.05 [v7.0.10]

    iOS: Removed minimum ios version flag
    Android: Added security requirements to activities

    2021.03.08 [v7.0.008]

    Unity plugin

    2020.12.15 [v6.0.062]

    Added Android Intel x64 support
    Added SWC (resolves #185)
    Deprecated wiki
    Updated examples to latest AIR version

    2020.05.07 [v6.0.056]

    iOS: Fixed crash with sharing files (resolves #176)

    2020.04.05 [v6.0.052]

    iOS: Updated symbol names to avoid conflict with Message extension

    2020.03.20 [v6.0.051]

    Android X migration (resolves #174)

    2020.02.14 [v5.0.035]

    Updated email documentation (resolves #172)

    2020.01.24 [v5.0.035]

    Added email and sms functionality

    2019.10.03 [v4.1.025]

    Corrected issue with excludedActivityTypes in the shareFile method

    2019.10.01 [v4.1.023]

    iOS: Added excludedActivityTypes to share 
    Android: Corrected APK installation on Android M and lower (resolves #163)
    Android: Added setDataAndType to startActivity functionality (resolves #164)

    2019.08.15 [v4.0.005]

    Android 64bit update (resolves #161)
    Updated minimum iOS version to 9.0

    2019.04.08 [v3.7.033]

    Android: Added direct startActivity functionality (resolves #156)

    2019.03.12 [v3.6.023]

    Embedded iOS bitcode

    2019.02.26 [v3.6.022]

    Updated minimum iOS version to 8.0 (resolves #155)

    2018.12.24 [v3.5.021]

    Updated fileproviders to correctly work with APK paths (#152)

    2018.10.28 [v3.5.019]

    Android: Created specific file provider to avoid conflicts (resolves #148)
    Removed application key requirement

    2017.08.30 [v3.4.009]

    Updated documentation

    2017.08.30 [v3.4.009]

    Corrected Android caching (resolves #105)

    2017.07.10 [v3.4.006]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2017.04.02 [v3.4.005]

    Better aligned iOS and Android share file functionality

    2016.12.30 [v3.3.008]

    New documentation

    2016.11.28 [v3.3.007]

    Updated documentation

    2016.11.28 [v3.3.007]

    Added arrowDirection to control the available directions for the popover dialog (resolves #79)

    2016.11.16 [v3.3.003]

    iOS 10 Updates, Added internal caching of shared bitmap data (resolves #78)

    2016.11.15 [v3.2.017]

    Added start of AppExtension documentation

    2016.11.01 [v3.2.017]

    Android: Fixed issue with multiple FileProviders (resolves #77)

    2016.10.14 [v3.2.010]

    iOS: Corrected share with no text (resolves #71)

    2016.10.03 [v3.2.009]

    Android: Corrected shareFile failing with certain activities (resolves #76)

    2016.09.14 [v3.2.007]

    Android: Corrected permissions for external applications on some Android versions (resolves #72)

    2016.08.09 [v3.2.002]

    Android: Fixed APP KEY issue with invalid java package application ids

    2016.08.03

    Updated Core library compatibility

    2016.06.22

    Corrected file shares and opens using new FileProvider to correctly share access (resolves #64)

    2016.04.12

    Documentation update

    2016.04.12

    iOS: Minor correction for rare crashes on iPad (#54)

    2016.03.14

    Updated documentation

    2016.03.14

    Adding missing SocialPostEvent from default lib (resolves #43)

    2016.02.26

    iOS: Added twitter video upload functionality (resolves #32)

    2016.01.27

    Updated asdocs

    2016.01.27

    Added ability to launch applications (Android Intent / iOS openUrl)
    iOS: Added social shares using the SLComposeViewController
    Corrected typo in documentation
    iOS: UTI option (resolves #24)

    2015.11.12

    iOS: Added ability to 'open' a file in another app (allows sharing to Instagram etc) (resolves #12 #7)
    iOS: Added function to check if an application is installed
    iOS: Fixed crash with bitmap data being disposed (resolves #18)
    Android: Identified permission issue with sharing non-asset file (resolves #19)
    Android: Added option to decide whether to use a 'chooser'
    Android: Added support for package name limit

    2015.06.18

    Android: Added ability to set title of share dialog (resolves #3)

    2015.06.12

    Stability updates

    2015.06.11

    Android: Windows: Fix for bug in AIR packager resulting in missing resources

    2015.05.28

    Fixed issue with incorrect handling of missing ShareOptions (resolves #1)

    2015.05.22

    Updated documentation

    2015.05.12

    Updated example

    2015.05.12

    Release v1.0
    - + \ No newline at end of file diff --git a/docs/share/email/index.html b/docs/share/email/index.html index ccf26a39ad9..82300bd611e 100644 --- a/docs/share/email/index.html +++ b/docs/share/email/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Email

    Support

    You can check whether the current user can send emails using the isMailSupported call.

    This performs some basic checks as to whether the user can send an email.

    if (Share.service.email.isMailSupported)
    {
    // You should be able to send an email
    }
    • On Apple devices this checks that the user has an email account setup in the settings.
    • On Android devices this checks that there is an email client application installed.

    Simple Email

    Sending an email is a simple task of calling the sendMail() function, specifying the subject, body and recipients.

    var email:String = "emailaddress@test.com";
    var subject:String = "Sending HTML email from AIR using the distriqt Message ANE";
    var body:String = "The body content of the email";

    Share.service.email.sendMail(
    subject,
    body,
    email
    );

    Send Email with Options

    You can use the sendMailWithOptions() function to send more complex data, including:

    • CC and BCC recipients;
    • file attachments; and
    • HTML content;

    If you wish to send html content you can set the isHTML flag in the sendMailWithOptions() function to true and the extension will attempt to use the body text as html.

    The following example shows the supported HTML content:

    var email:String = "emailaddress@test.com";
    var subject:String = "Sending HTML email from AIR using the distriqt Message ANE";
    var ccRecipients:String = "";
    var bccRecipients:String = "";

    var body:String =
    "<div>"+
    "<p>This HTML email was sent using the distriqt <b>Message ANE</b></p>"+
    "A link: <a href='http://airnativeextensions.com'>airnativeextensions.com</a>"+
    "<br/>" +
    "Block: <blockquote>Some quote</blockquote>"+
    "<br/>" +
    "Bold: <b>This text should be bold</b>"+
    "<br/>" +
    "Italic: <i>This text should be italic</i>"+
    "<br/>" +
    "Colour: <font color='#ff0000'>This text should be red</font>"+
    "<div/>" ;

    Share.service.email.sendMailWithOptions(
    subject,
    body,
    email,
    ccRecipients,
    bccRecipients,
    [], // Attachments (see next section)
    true // isHTML flag
    );
    caution

    HTML content can depend on the client the user has installed. As this can vary greatly (on Android in particular) the HTML content functionality can have unexpected results in clients that don't respect or accept html content.

    Our extension uses the underlying standard method to format and flag the content as html however there are still cases you may encounter issues. We highly recommend you thoroughly test this feature to make sure it suits your needs.

    Attachments

    You can specify an Array of Attachment objects each representing a file to attach to the email.

    You create an attachment using the constructor and passing the native path to the file and we suggest passing a mime type.

    var attachmentImage:File = File.applicationStorage.resolvePath( "image.jpg" );

    var attachment:Attachment = new Attachment( attachmentFile.nativePath, "image/jpg" );

    Then you pass your attachments to the send mail function in an Array:

    var attachments:Array = [ attachment ];

    Share.service.email.sendMailWithOptions(
    subject,
    body,
    email,
    "",
    "",
    attachments
    );
    - + \ No newline at end of file diff --git a/docs/share/index.html b/docs/share/index.html index 32b96404a3a..df2d3d7d462 100644 --- a/docs/share/index.html +++ b/docs/share/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Share

    The Share extension gives you access to the default share menu to send files and information to other applications. You can use one simple line of AS3 / C# to display the built-in native share dialogs allowing your user to share files and content with other applications.

    For example, your user could use this to:

    • save an image to the camera roll,
    • send as an attachment on an email,
    • save a pdf to Dropbox,
    • plus much more.

    Additionally this extension now has the ability to launch other applications on the user's device allowing you to deeply integrate with other applications.

    You can pass detailed extras to an explicit Intent on Android allowing amazing integration with other applications, launching specific views in other applications or sending detailed information for another application to use within an activity.

    The email and sms APIs allow you to quickly integrate sending emails and sms in your application with just a few lines of code. Identical code base can be used across all supported platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with sharing quickly and easily.

    Features

    • Share text/image/url/files with other applications
    • Launch applications directly
      • Pass parameters and data
    • Email
      • Provides ability to compose an email using the native UI
      • Multiple To, CC and BCC Addresses
      • Multiple Attachments using a file path reference
      • Default implementation using a "mailto" link
      • Send preformatted HTML emails on iOS and Android;
    • SMS
      • Create an SMS and send with the native UI
      • Send an SMS without UI on Android
    • Single API interface - your code works across iOS and Android with no modifications
    • Sample project code and ASDocs reference

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    Share.service.share( "some text", null, "https://airnativeextensions.com" );

    More information here:

    com.distriqt.Share

    License

    You can purchase a license for using this extension:

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/share/launch-applications/index.html b/docs/share/launch-applications/index.html index f76d0d3d85b..bfef047ebd3 100644 --- a/docs/share/launch-applications/index.html +++ b/docs/share/launch-applications/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Launch Applications

    This function allows your application to start another application on the device. It uses different methods on iOS and Android however both will allow you to specify start up parameters to an application:

    • On Android it uses an explicit Intent with a package, type, action and extras
    • On iOS it uses a custom url scheme with query parameters

    The simplest example of launching another application if installed.

    var app:Application = new Application( "com.instagram.android", "instagram://" );

    if (Share.service.applications.isInstalled( app ))
    {
    Share.service.applications.launch( app );
    }

    An example of launching Instagram and opening a specific user profile

    var app:Application = new Application( "com.instagram.android", "instagram://" );

    var options:ApplicationOptions = new ApplicationOptions();
    options.action = ApplicationOptions.ACTION_VIEW;
    options.data = "http://instagram.com/_u/distriqt";
    options.parameters = "user?username=distriqt";

    if (Share.service.applications.isInstalled( app ))
    {
    Share.service.applications.launch( app, options );
    }

    iOS

    On iOS you must add the application schemes you wish to query or launch to your info additions. If you don't perform these additions you will always receive false from the isInstalled() and the launch functions.

    You should add the LSApplicationQueriesSchemes value to your InfoAdditions in your application descriptor, and include the schemes for the applications you intend to query.

    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>instagram</string>
    <string>whatsapp</string>
    </array>

    For more information see Add the Extension

    Android

    Android 11 introduces changes related to package visibility. These changes affect apps only if they target Android 11. In order for you to correctly query if an application is installed you will need to add the package names you wish to query to the manifest.

    <queries>
    <package android:name="PACKAGENAME" />
    </queries>

    For example if you are querying whatsapp and instagram:

    <queries>
    <package android:name="com.whatsapp" />
    <package android:name="com.instagram.android" />
    </queries>

    For more information see Add the Extension

    Start Actvity

    Android only

    This functionality allows you to use the Android Intent system to launch an Intent directly.

    This is sometimes required when you need particular control over how the data is passed to an Intent.

    Use the Intent class to create an Intent and then pass it to the startActivity function.

    For example to launch a url in the Chrome application

    var intent:Intent = new Intent();
    intent.action = "android.intent.action.VIEW";
    intent.data = "https://distriqt.com";
    intent.packageName = "com.android.chrome";

    var success:Boolean = Share.service.applications.startActivity( intent );

    The return value of the startActivity function will be false if no activity could be launched matching the Intent and will be true if an activity was started.

    You can also add extras to the intent through the extras property. This should be set to an Object containing simple data values (eg String, int, Number) that are passed to the activity.

    intent.extras = {
    extraName: "some value"
    };
    - + \ No newline at end of file diff --git a/docs/share/migrating-from-message/index.html b/docs/share/migrating-from-message/index.html index 0e6eb037e2f..28e67648391 100644 --- a/docs/share/migrating-from-message/index.html +++ b/docs/share/migrating-from-message/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating from Message

    From version 5.0, we have added all of the Message ANE functionality to this ANE and will eventually be deprecating the Message ANE in favour of this Share ANE.

    The functionality between the Message and Share ANEs seemed to overlap too much so we decided to reduce overheads involved for developers and combine the two ANEs into the Share ANE.

    In order to migrate from the Message ANE to the Share ANE you'll need to update the email and sms functionality separately. This guide is assuming you will be removing the Message ANE, in favour of the functionality in the Share ANE.

    Firstly, remove the Message ANE from your build.

    Email functionality

    Email functionality in the Share ANE is accessed through the Share.service.email accessor, so:

    if (Message.isMailSupported)
    {
    Message.service.sendMail( ... );
    }

    becomes:

    if (Share.service.email.isMailSupported)
    {
    Share.service.email.sendMail( ... );
    }

    Similarly for sendMailWithOptions().

    Some refactoring has also been done on the associated classes:

    • Attachments: com.distriqt.extension.message.MessageAttachment -> com.distriqt.extension.share.email.Attachment
    • Events:
      • com.distriqt.extension.message.events.MessageEvent -> com.distriqt.extension.share.events.EmailEvent

    SMS Functionality

    SMS functionality in the Share ANE is accessed through the Share.service.sms accessor, so:

    if (Message.service.smsManager.isSMSSupported)
    {
    Message.service.smsManager.sendSMS( ... );
    }

    becomes:

    if (Share.service.sms.isSMSSupported)
    {
    Share.service.sms.sendSMS( ... );
    }

    Similarly for sendSMSWithUI(), getSubscriptions(), authorisationStatus(), and requestAuthorisation().

    Some refactoring has also been done on the associated classes:

    • SMS Object: com.distriqt.extension.message.objects.SMS -> com.distriqt.extension.share.sms.SMS
    • Events:
      • com.distriqt.extension.message.events.MessageSMSEvent -> com.distriqt.extension.share.events.SMSEvent
      • com.distriqt.extension.message.events.AuthorisationEvent -> com.distriqt.extension.share.events.AuthorisationEvent

    Share Functionality

    The share functionality from the Message ANE has been removed completely as it already existed in the Share ANE.

    iOS

    No changes to the info additions are required.

    Android

    Remove the MessageFileProvider (the ShareFileProvider will be used instead now):

    <provider
    android:name="com.distriqt.extension.message.content.MessageFileProvider"
    android:authorities="APPLICATION_ID.messagefileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/distriqt_message_paths" />
    </provider>

    Change the package name of the AuthorisationActivity as below (message > share):

    <activity android:name="com.distriqt.extension.share.permissions.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" />

    If you are using SMS receiver functionality, remove the MessageSMSReceiver and add the following:

    <receiver android:name="com.distriqt.extension.share.receivers.SMSReceiver" android:exported="true" > 
    <intent-filter android:priority="1000">
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
    </receiver>
    - + \ No newline at end of file diff --git a/docs/share/migrating-to-androidx/index.html b/docs/share/migrating-to-androidx/index.html index 43f9eb3c4c4..6a0f6c22de8 100644 --- a/docs/share/migrating-to-androidx/index.html +++ b/docs/share/migrating-to-androidx/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Migrating to AndroidX

    Android X

    AndroidX is a major improvement to the original Android Support Library, which is no longer maintained. androidx packages fully replace the Support Library by providing feature parity and new libraries.

    As there will be no further updates to the Android Support libraries we are migrating all our extensions to AndroidX. Importantly Android Support libraries are not compatible with AndroidX so applications have to migrate all functionality from the support libraries to AndroidX together.

    This means you cannot use older extensions that rely on the Android Support libraries with the latest builds of our extensions and you must upgrade all of our extensions simultaneously.

    Generally migrating is fairly simple.

    Simply use the table below to swap the extensions you currently have in your application.

    Android SupportAndroid X
    com.distriqt.androidsupport.V4androidx.core
    com.distriqt.androidsupport.AppCompatV7androidx.appcompat
    com.distriqt.androidsupport.CardViewV7androidx.cardview
    com.distriqt.androidsupport.CustomTabsandroidx.browser
    com.distriqt.androidsupport.Designcom.google.android.material
    com.distriqt.androidsupport.InstallReferrercom.android.installreferrer
    com.distriqt.androidsupport.RecyclerViewandroidx.recyclerview

    We have included all these extensions in the existing Android Support repository and will continue to use this repository to hold any common Google provided Android libraries that aren't dependent on the Google Play Services.

    When migrating we also suggest you check the manifest additions and "Add the Extension" documentation. Some of the extensions will require changes to the manifest, where references to the Android Support libraries were being used. And there may be additional extensions required.

    - + \ No newline at end of file diff --git a/docs/share/migrating-to-v7.4/index.html b/docs/share/migrating-to-v7.4/index.html index 304cab5a811..29a392b4e44 100644 --- a/docs/share/migrating-to-v7.4/index.html +++ b/docs/share/migrating-to-v7.4/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Migrating to v7.4

    This version brings an updated process for requesting permissions on Android. AIR has introduced a new process for us to better handle permission requests so we have updated the extension to support this.

    The authorisation process remains the same however there is a small change to the manifest.

    This update requires the latest version of the Core ANE (v7+).

    If you are using apm all you need to do is update to the latest build and regenerate your application descriptor. apm will handle the rest.

    apm update 
    apm generate app-descriptor src/Main-app.xml
    - + \ No newline at end of file diff --git a/docs/share/positioning/index.html b/docs/share/positioning/index.html index c18f100f293..b759c96d2c8 100644 --- a/docs/share/positioning/index.html +++ b/docs/share/positioning/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ to the button:

    var options:ShareOptions = new ShareOptions();
    options.position = new Rectangle( 100, 100, 200, 50 );
    options.arrowDirection = ShareOptions.ARROWDIRECTION_ANY;

    Share.service.share( "Share text", null, "http://airnativeextensions.com", options );

    Or we could limit the dialog to only appear to the left or right of the position by using bitwise-OR to combine the required directions:

    var options:ShareOptions = new ShareOptions();
    options.position = new Rectangle( 100, 100, 200, 50 );
    options.arrowDirection = ShareOptions.ARROWDIRECTION_LEFT | ShareOptions.ARROWDIRECTION_RIGHT;

    Share.service.share( "Share text", null, "http://airnativeextensions.com", options );

    Centering

    If you need to center the dialog you can simply use the center of the screen as the position and supply ARROWDIRECTION_NONE as the arrowDirection.

    For example:

    var options:ShareOptions = new ShareOptions();
    options.position = new Rectangle( stage.stageWidth*0.5, stage.stageHeight * 0.5, 0, 0 );
    options.arrowDirection = ShareOptions.ARROWDIRECTION_NONE;

    Share.service.share( "Share text", null, "http://airnativeextensions.com", options );

    - + \ No newline at end of file diff --git a/docs/share/share-files/index.html b/docs/share/share-files/index.html index d6f168e4791..6678ceadbfa 100644 --- a/docs/share/share-files/index.html +++ b/docs/share/share-files/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ an activity whereas opening will actually pass the file data for opening.

    Generally this operation gives better functionality than the share file.

    On iOS this uses the UIDocumentInteractionController to display a list of applications that can open the specified file.

    var path:String = File.applicationDirectory.nativePath + File.separator + "assets" + File.separator + "TestDocument.pdf";

    Share.service.showOpenIn( path, "TestDocument.pdf", "application/pdf" );

    Opening a File: Example

    The below shows an example of opening an igo (instagram only file) and setting the packageName and UTI to limit the applications displayed to only be Instagram. We also use the isApplicationInstalled to check that Instagram is installed. More on this function in the Launch Applications section.

    if (Share.service.isApplicationInstalled( "com.instagram.android", "instagram://app" ))
    {
    var instagramImage:File = File.applicationStorageDirectory.resolvePath( "assets/instagram.igo" );

    var options:ShareOptions = new ShareOptions();
    options.packageName = "com.instagram.android";
    options.UTI = "com.instagram.photo";

    Share.service.showOpenIn( instagramImage.nativePath, "", "image/*", options );
    }
    - + \ No newline at end of file diff --git a/docs/share/simple-share/index.html b/docs/share/simple-share/index.html index 7d69a472adc..9dcc4db8208 100644 --- a/docs/share/simple-share/index.html +++ b/docs/share/simple-share/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Simple Share

    Displaying an action to share text, image data or/and URL is simply a process of calling share() with data you wish to share.

    An action dialog will be displayed with a list of applications that will accept the content for sharing. This generally includes applications like: Messaging, Email, Twitter, Facebook.

    [Embed("assets/image.png")]
    public var TestImage:Class;

    Core.init();
    if (Share.isSupported)
    {
    Share.service.addEventListener( ShareEvent.COMPLETE, share_shareHandler );
    Share.service.addEventListener( ShareEvent.CANCELLED, share_shareHandler );
    Share.service.addEventListener( ShareEvent.FAILED, share_shareHandler );
    Share.service.addEventListener( ShareEvent.CLOSED, share_shareHandler );

    // Here we have embedded an image "assets/image.png" in our application (above)
    var image:Bitmap = new TestImage() as Bitmap;

    Share.service.share( "some text", image.bitmapData, "http://airnativeextensions.com" );
    }

    function share_shareHandler( event:ShareEvent ):void
    {
    trace( event.type + "::" + event.activityType + "::" + event.error );
    }
    - + \ No newline at end of file diff --git a/docs/share/sms/index.html b/docs/share/sms/index.html index fb2669a9738..ae436b1ce4b 100644 --- a/docs/share/sms/index.html +++ b/docs/share/sms/index.html @@ -13,7 +13,7 @@ - + @@ -25,7 +25,7 @@ You will still need to list them in your manifest and then follow the same code below as for iOS, except that on Android you will be able to ask multiple times. You should respect the SHOULD_EXPLAIN status by displaying additional information to your user about why you require this functionality.

    The following code will work across both platforms:

    Share.service.sms.addEventListener( AuthorisationEvent.CHANGED, authorisationStatus_changedHandler );

    switch (Share.service.sms.authorisationStatus())
    {
    case AuthorisationStatus.SHOULD_EXPLAIN:
    case AuthorisationStatus.NOT_DETERMINED:
    // REQUEST ACCESS: This will display the permission dialog
    Share.service.sms.requestAuthorisation();
    return;

    case AuthorisationStatus.DENIED:
    case AuthorisationStatus.UNKNOWN:
    case AuthorisationStatus.RESTRICTED:
    // ACCESS DENIED: You should inform your user appropriately
    return;

    case AuthorisationStatus.AUTHORISED:
    // AUTHORISED: SMS will be available
    break;
    }

    function authorisationStatus_changedHandler( event:AuthorisationEvent ):void
    {
    trace( "authorisationStatus_changedHandler: "+event.status );
    }

    Sending an SMS

    Once you have authorisation, sending an SMS is a simple matter of calling sendSMS:

    if (Share.service.sms.isSMSSupported)
    {
    var sms:SMS = new SMS();
    sms.address = "0444444444";
    sms.message = "Testing Message ANE";

    Share.service.sms.sendSMS( sms );
    }

    Subscription Info

    In some devices there are multiple SIM cards and you may wish to specify the subscription to use to send the SMS.

    Firstly you must add the additional permission to READ_PHONE_STATE to be able to access the subscription information.

    Then call getSubscriptions() to retrieve an array of SubscriptionInfo objects representing the different sims.

    var subs:Array = Share.service.sms.getSubscriptions();
    for each (var sub:SubscriptionInfo in subs)
    {
    trace( "SIM: ["+sub.id+"] " + sub.displayName + "/"+sub.carrierName);
    }

    When sending an SMS you can specify the subscription id to use to send the SMS:

    Share.service.sms.sendSMS( sms, sub.id );
    note

    This is only supported on Android API v22+. If it is not supported (or if you haven't requested the additional permission) getSubscriptions() will return an empty array and the default sim will be used to send messages.

    Events

    You can listen for several events, as defined in the SMSEvent class, see the documentation in that class for more information on the events.

    Share.service.sms.addEventListener( SMSEvent.MESSAGE_SMS_CANCELLED,     smsEventHandler );
    Share.service.sms.addEventListener( SMSEvent.MESSAGE_SMS_DELIVERED, smsEventHandler );
    Share.service.sms.addEventListener( SMSEvent.MESSAGE_SMS_RECEIVED, smsEventHandler );
    Share.service.sms.addEventListener( SMSEvent.MESSAGE_SMS_SENT, smsEventHandler );
    Share.service.sms.addEventListener( SMSEvent.MESSAGE_SMS_SENT_ERROR, smsEventHandler );


    function smsEventHandler( event:SMSEvent ):void
    {
    trace( event.type +"::"+ event.details + "::"+event.sms.toString() );
    }
    - + \ No newline at end of file diff --git a/docs/share/unity/index.html b/docs/share/unity/index.html index c09000812f6..ba5f3f3a0a5 100644 --- a/docs/share/unity/index.html +++ b/docs/share/unity/index.html @@ -13,7 +13,7 @@ - + @@ -40,7 +40,7 @@ If you don't perform these additions you will always receive false from the isInstalled() and the launch functions.

    You should add the LSApplicationQueriesSchemes value to your Info.plist, and include the schemes for the applications you intend to query.

    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>instagram</string>
    <string>whatsapp</string>
    </array>

    Start Actvity

    Android only

    This functionality allows you to use the Android Intent system to launch an Intent directly.

    This is sometimes required when you need particular control over how the data is passed to an Intent.

    Use the Intent class to create an Intent and then pass it to the StartActivity function.

    For example to launch a url in the Chrome application

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.packageName = "com.android.chrome";
    intent.data = "https://distriqt.com";

    Share.Instance.Applications.StartActivity(intent);

    The return value of the StartActivity function will be false if no activity could be launched matching the Intent and will be true if an activity was started.

    Email

    Email Support

    You can check whether the current user can send emails using the isMailSupported call.

    This performs some basic checks as to whether the user can send an email.

    if (Share.Instance.Email.IsMailSupported)
    {
    // You should be able to send an email
    }

    Simple Email

    Sending an email is a simple task of calling the SendMail() function, specifying the subject, body and recipients.

    string subject = "Test email from unity";
    string body = "Some awesome message I want to send";
    string toRecipients = "unityplugins@distriqt.com";

    Share.Instance.Email.OnCompose += Email_OnCompose;
    Share.Instance.Email.OnAttachmentError += Email_OnAttachmentError;

    bool success = Share.Instance.Email.SendMail(subject, body, toRecipients);
    private void Email_OnCompose(EmailEvent e)
    {
    Debug.Log("Email_OnCompose: " + e.details);
    }

    private void Email_OnAttachmentError(EmailEvent e)
    {
    Debug.Log("Email_OnAttachmentError: " + e.details);
    }

    Send Email with Options

    You can use the sendMailWithOptions() function to send more complex data, including:

    If you wish to send html content you can set the isHTML flag in the sendMailWithOptions() function to true and the extension will attempt to use the body text as html.

    The following example shows the supported HTML content:

    string subject = "Test email from unity";
    string body = "Some awesome message I want to send";
    string toRecipients = "unityplugins@distriqt.com";
    string ccRecipients = "distriqt@distriqt.com";
    string bccRecipients = "airnativeextensions@distriqt.com";

    string body =
    "<div>"+
    "<p>This HTML email was sent using the distriqt <b>Message ANE</b></p>"+
    "A link: <a href='http://airnativeextensions.com'>airnativeextensions.com</a>"+
    "<br/>" +
    "Block: <blockquote>Some quote</blockquote>"+
    "<br/>" +
    "Bold: <b>This text should be bold</b>"+
    "<br/>" +
    "Italic: <i>This text should be italic</i>"+
    "<br/>" +
    "Colour: <font color='#ff0000'>This text should be red</font>"+
    "<div/>" ;

    Share.Instance.Email.SendMailWithOptions(
    subject,
    body,
    toRecipients,
    ccRecipients,
    bccRecipients,
    null, // Attachments (see next section)
    true // isHTML flag
    );

    HTML content can depend on the client the user has installed. As this can vary greatly (on Android in particular) the HTML content functionality can have unexpected results in clients that don't respect or accept html content.

    Our extension uses the underlying standard method to format and flag the content as html however there are still cases you may encounter issues. We highly recommend you throughly test this feature to make sure it suits your needs.

    Attachments

    You can specify an Array of Attachment objects each representing a file to attach to the email.

    You create an attachment using the constructor and passing the native path to the file and we suggest passing a mime type.

    Attachment attachment = new Attachment();
    attachment.nativePath = imageFile; // Absolute native path to file

    Then you pass your attachments to the send mail function in an Attachment[] array:

    Attachment[] attachments = new Attachment[1];
    attachments[0] = attachment;

    Share.Instance.Email.SendMailWithOptions(
    subject,
    body,
    toRecipients,
    "",
    "",
    attachments
    );

    SMS

    SMS Supported

    You can check whether the current user can send sms using the IsSMSSupported call.

    if (Share.Instance.SMS.IsSMSSupported)
    {
    // You should be able to send an sms
    }

    Sending an SMS with UI

    The example below shows how to send an SMS using the native UI:

    if (Share.Instance.SMS.IsSMSSupported)
    {
    Share.Instance.SMS.OnSMSSent += SMS_OnSMSSent;
    Share.Instance.SMS.OnSMSSentError += SMS_OnSMSSentError;
    Share.Instance.SMS.OnSMSCancelled += SMS_OnSMSCancelled;

    SMS sms = new SMS();
    sms.address = "0444444444";
    sms.message = "Sending an SMS with the distriqt plugin";

    Share.Instance.SMS.SendSMSWithUI( sms );
    }

    private function smsEventHandler( event:SMSEvent ):void
    {
    trace( event.type +"::"+ event.details + "::"+event.sms.toString() );
    }
    private void SMS_OnSMSCancelled(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSCancelled");
    }

    private void SMS_OnSMSSentError(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSSentError");
    }

    private void SMS_OnSMSSent(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSSent");
    }

    Android Advanced SMS operations

    On Android you can request permission to directly send and receive SMS messages without user interaction.

    Manifest Additions

    The plugin requires a few additions to the manifest to be able to start certain activities and to get permission to send and receive SMS.

    These are optional and so should be added manually currently.

    <uses-permission android:name="android.permission.SEND_SMS" /> 
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />

    <!-- To access SIM subscriptions -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />


    <application>

    <!-- TO RECEIVE SMS -->
    <receiver android:name="com.distriqt.extension.share.receivers.SMSReceiver" android:exported="true" >
    <intent-filter android:priority="1000">
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
    </receiver>

    </application>

    Requesting Authorisation

    Firstly you must request authorisation to send and receive messages.

    You can do this using the normal Permission process through Unity, eg to check whether you have permission to send sms directly:

    if (Permission.HasUserAuthorizedPermission("android.permission.SEND_SMS"))
    {
    //
    }

    More information here: https://docs.unity3d.com/Manual/android-RequestingPermissions.html

    Sending an SMS

    Once you have authorisation, sending an SMS is a simple matter of calling sendSMS:

    if (Share.service.sms.isSMSSupported)
    {
    SMS sms = new SMS();
    sms.address = "0444444444";
    sms.message = "Sending an SMS with the distriqt plugin";

    Share.Instance.SMS.SendSMS( sms );
    }

    Subscription Info

    In some devices there are multiple SIM cards and you may wish to specify the subscription to use to send the SMS.

    Firstly you must add the additional permission to READ_PHONE_STATE to be able to access the subscription information.

    Then call GetSubscriptions() to retrieve an array of SubscriptionInfo objects representing the different sims.

    SubscriptionInfo[] subs = Share.Instance.SMS.GetSubscriptions();
    foreach (SubscriptionInfo sub in subs)
    {
    Debug.Loh( "SIM: ["+sub.id+"] " + sub.displayName + "/"+sub.carrierName);
    }

    When sending an SMS you can specify the subscription id to use to send the SMS:

    Share.Instance.SMS.SendSMS( sms, sub.id );

    Note: This is only supported on Android API v22+. If it is not supported (or if you haven't requested the additional permission) GetSubscriptions() will return an empty array and the default sim will be used to send messages.

    Events

    You can listen for several events, as defined in the SMSManager class, see the documentation in that class for more information on the events.

    Share.Instance.SMS.OnSMSSent += SMS_OnSMSSent;
    Share.Instance.SMS.OnSMSSentError += SMS_OnSMSSentError;
    Share.Instance.SMS.OnSMSCancelled += SMS_OnSMSCancelled;
    Share.Instance.SMS.OnSMSDelivered += SMS_OnSMSDelivered;
    Share.Instance.SMS.OnSMSNotDelivered += SMS_OnSMSNotDelivered;
    Share.Instance.SMS.OnSMSReceived += SMS_OnSMSReceived;


    private void SMS_OnSMSCancelled(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSCancelled");
    }

    private void SMS_OnSMSSentError(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSSentError");
    }

    private void SMS_OnSMSSent(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSSent");
    }

    private void SMS_OnSMSReceived(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSReceived");
    }

    private void SMS_OnSMSNotDelivered(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSNotDelivered");
    }

    private void SMS_OnSMSDelivered(SMSEvent e)
    {
    Debug.Log("SMS_OnSMSDelivered");
    }

    Support

    If you need further support integrating or using this extension please feel free to contact us.

    We have been supporting developers for over 10 years and always happy to help.





    - + \ No newline at end of file diff --git a/docs/singular/add-the-extension/index.html b/docs/singular/add-the-extension/index.html index d2b945f1411..e92b3dfd38d 100644 --- a/docs/singular/add-the-extension/index.html +++ b/docs/singular/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ and you need to ensure they are packaged with your application.

    You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Singular.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/singular/advanced-options/index.html b/docs/singular/advanced-options/index.html index 44006b93bce..4d956ed1ae4 100644 --- a/docs/singular/advanced-options/index.html +++ b/docs/singular/advanced-options/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Advanced Options

    Use the createReferrerShortLink method to generate a shortened share link for the User to share the app with friends. Define the referring user details in your app code when the link is created. This allows for tracking referrer attributions in reporting.

    To create a short link:

    • Build a Singular Custom Source Link with defined deep links, that leads to your app download (see the Singular Links FAQ). This link will be referred to as a base link in the code below.
    • Any campaign override parameters to add to the link dynamically (see Tracking Link Parameters for the list of options).
    • The Name and ID of the referring user, in order to track new app installs back to the user who shared the link.
    // Define your Singular tracking link to be used as a base link
    var baseLink:String = "https://sample.sng.link/D52wc/cuvk?pcn=test";

    // Add your Referrer ID and Name
    var referrerId:String = "ref id";
    var referrerName:String = "referrer name";

    var passthroughParams:Object = {
    "param": "value"
    };

    Singular.instance.createReferrerShortLink(
    baseLink,
    referrerName,
    referrerId,
    passthroughParams,
    function ( success:Boolean, data:String ):void
    {
    trace( "createReferrerShortLink: " + success + " :: " + data );
    }
    );

    Adding Ad Revenue Attribution Support

    To add ad revenue attribution support in the Singular SDK or must first contact your Singular Customer manager to enable ad revenue attribution and then add the relevant code to your application.

    To track revenue, create a SingularAdData object with the appropriate parameters and pass it to the adRevenue() method.

    var data:SingularAdData = new SingularAdData( SingularAdData.ADMOB, "USD", 1.23 )
    .withAdUnitId( "admob-unit-id" )
    .withNetworkName( "mediation-adapter-name" );

    Singular.instance.adRevenue( data );

    Tracking Uninstalls

    note

    Uninstall tracking is only available to Enterprise customers. Additionally, uninstall tracking requires the app to support push notifications.

    You will need to integrate push notifications into your application using FCM on Android and Apple push notifications on iOS.

    You will also need to add the necessary configuration in the Singular dashboard.

    Once you have registered the device for push notifications, pass the device token to Singular SDK:

    Singular.instance.setDeviceToken( "fcm_or_ios_device_token" );

    Complying with Data Privacy Laws

    Singular provides privacy-safeguarding functionality to help you cooperate with any partners who may be complying with consumer privacy laws such as GDPR and CCPA (California Consumer Privacy Act). These partners want to be notified if the end-user has consented to share their private information.

    If you have implemented a way to ask users for consent to share their information, use the limitDataSharing() method to notify Singular of the user's choice.

    To indicate that the user consented (opted in) to share their information:

    Singular.instance.limitDataSharing( false );

    Or, if the user did not consent:

    Singular.instance.limitDataSharing( true );
    note

    The use of the method is optional, but there may be attribution information that the partner will share with Singular only if specifically notified that the user has opted in.

    Additional Methods for GDPR Compliance

    The Singular SDK provides several methods to help you comply with GDPR policies and let Singular know about user consent or non-consent for tracking.

    To notify Singular of user consent (opt-in) for tracking

    Singular.instance.trackingOptIn();

    To stop all tracking activities for this user on this app:

    Singular.instance.stopAllTracking();
    note

    Calling this method effectively disables the SDK, even after the app restarts (the state is persistent)! The only way to re-enable tracking is by calling resumeAllTracking().

    To resume tracking for this user on this app.

    Singular.instance.resumeAllTracking();

    Check the tracking status for this user on this app. Returns true if tracking has been stopped using stopAllTracking() and not resumed.

    var isAllTrackingStopped:Boolean = Singular.instance.isAllTrackingStopped();
    - + \ No newline at end of file diff --git a/docs/singular/changelog/index.html b/docs/singular/changelog/index.html index 85885c814f6..735ecc9ba46 100644 --- a/docs/singular/changelog/index.html +++ b/docs/singular/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.30 [v12.1.105]

    fix(iap): update to data sent with revenue with purchase method

    2023.09.08 [v12.1.104]

    feat(revenue): add integration of revenue event with InAppBilling Purchase objects

    2023.06.14 [v12.1.102]

    feat(api): add set/unset custom user id functions

    2023.05.17 [v12.1.101]

    initial release
    - + \ No newline at end of file diff --git a/docs/singular/index.html b/docs/singular/index.html index 4f71504be24..56e3853dbde 100644 --- a/docs/singular/index.html +++ b/docs/singular/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Singular

    The Singular extension gives you access to the Singular SDK for anayltics.

    We provide complete guides to get you up and running with sharing quickly and easily.

    Features

    • Access the Singular SDK - https://www.singular.net/
    • Single API interface - your code works across iOS and Android with no modifications
    • Sample project code and ASDocs reference

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    Initialise
    Singular.instance.init( 
    new SingularConfig( API_KEY, SECRET )
    );
    Track an event
    Singular.instance.event( SingularEvents.SUBSCRIBE );
    Custom event with arguments
    Singular.instance.event(
    "bonus_points_earned",
    {
    "points": 500
    }
    );

    More information here:

    com.singular

    License

    You can purchase a license for using this extension:

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/singular/initialise/index.html b/docs/singular/initialise/index.html index c5ddc8a29b2..30fb172c5c9 100644 --- a/docs/singular/initialise/index.html +++ b/docs/singular/initialise/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Initialise

    Creating a Configuration Object

    Before you initialize Singular functionality in your code, you have to create a Singular configuration object and set all your configuration options.

    This object will contain:

    • Your SDK Key and SDK Secret (to retrieve them, log into your Singular account and go to Developer Tools > SDK Keys).
    • Optionally, any SDK preferences you may want to set.
    Example: Creating a Configuration Object with Some Common Options
    var config:SingularConfig 
    = new SingularConfig( API_KEY, SECRET )
    .withSKAdNetworkEnabled( true )
    .withWaitForTrackingAuthorizationTimeoutInterval( 300 );

    See the documentation on the SingularConfig class for details on the available options.

    Initialising Singular

    The Singular SDK should be initialized every time your app is opened. This is a prerequisite to all Singular attribution functionality, and it also sends a new user session to Singular (sessions are used to calculate user retention).

    To initialise the SDK call the init() method passing the config object.

    var config:SingularConfig 
    = new SingularConfig( API_KEY, SECRET )
    .withSKAdNetworkEnabled( true )
    .withWaitForTrackingAuthorizationTimeoutInterval( 300 );

    var success:Boolean = Singular.instance.init( config );

    If you plan on handling deep links in your application you must add a handler for them before initialising the SDK.

    Deep links are handled through the SingularLinkEvent.RESOLVED event.

    Singular.instance.addEventListener( SingularLinkEvent.RESOLVED, linkResolvedHandler );

    function linkResolvedHandler( event:SingularLinkEvent ):void
    {
    var deepLink:String = event.params.deeplink;
    var passthrough:String = event.params.passthrough;
    var isDeferred:Boolean = event.params.isDeferred;
    }

    The event contains a SingularLinkParams object that contains the details of the link including the deepLink, passthrough parameters and whether it was a deferred link.

    Follow the documentation in Singular Link Prerequisites in order to setup your links.

    Android

    You will need to add some custom additions to your manifest to support deep links (this must be added inside the application tag). Replace URL_SCHEME with the url scheme your deep links are using on Android, ie the scheme part from: URL_SCHEME://your-link

    <activity>
    <intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="URL_SCHEME" />
    </intent-filter>
    </activity>
    note

    If you already have a launch activity in your manifest, just add the second intent-filter in the above example to your existing activity.

    iOS

    You will need to add some additions to your InfoAdditions to support deep links, replace URL_SCHEME with the url scheme your deep links are using on iOS, ie the scheme part from: URL_SCHEME://your-link:

    <key>CFBundleURLTypes</key>
    <array>
    <dict>
    <key>CFBundleURLSchemes</key>
    <array>
    <string>URL_SCHEME</string>
    </array>
    </dict>
    </array>

    Add the following to your Entitlements, replace SINGULAR_LINK with your singular link domain you created in the console, eg distriqt-test.sng.link:

    <key>com.apple.developer.associated-domains</key>
    <array>
    <string>applinks:SINGULAR_LINK</string>
    </array>

    Optional: Custom User ID

    The Singular SDK can send an internal user ID from your app to Singular.

    To set the user id pass the identifier as part of your configuration object:

    var config:SingularConfig 
    = new SingularConfig( API_KEY, SECRET )
    .withCustomUserId( "user_custom_id" )
    ...

    Optional: Global Properties

    The Singular SDK lets you define custom properties to be sent to the Singular servers along with every session and event sent from the app. These properties can represent any information you want about the user, the app mode/status, or anything else.

    You can define up to 5 global properties. They persist between app runs (with the latest value you gave them) until you unset them or the user uninstalls the app.

    Setting Global Properties through the Config Object

    To set global properties before initializing the SDK, use the withGlobalProperty() method in the SingularConfig object.

    var config:SingularConfig 
    = new SingularConfig( API_KEY, SECRET )
    .withGlobalProperty( "a_prop", "set from config", true )
    .withGlobalProperty( "b_prop", "set from config", true )
    ...

    Setting Global Properties After Initialisation

    Use the following methods to set, unset, and retrieve global properties at any time in the app's run.

    Set a property using setGlobalProperty():

    Singular.instance.setGlobalProperty( "a_prop", "set from sdk", true );

    Retrieve all current properties using the getGlobalProperties() method:

    var props:Object = Singular.instance.getGlobalProperties();

    for (var key:String in props)
    {
    trace( key + " = " + props[key] );
    }

    Clear a specific property using the unsetGlobalProperty() method:

    Singular.instance.unsetGlobalProperty( "a_prop" );

    Clear all global properties using the clearGlobalProperties() method:

    Singular.instance.clearGlobalProperties();

    Optional: Modifying the Session Timeout

    By default, if the app runs in the background for 60 seconds or more before returning to the foreground, the SDK will register a new session. To change this timeout value, use the withSessionTimeoutInSec() method and add it to the Config.

    var config:SingularConfig 
    = new SingularConfig( API_KEY, SECRET )
    .withSessionTimeoutInSec( 100 )
    ...
    - + \ No newline at end of file diff --git a/docs/singular/tracking-events/index.html b/docs/singular/tracking-events/index.html index 23b345cf352..1f19e73fd66 100644 --- a/docs/singular/tracking-events/index.html +++ b/docs/singular/tracking-events/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Tracking Events and Revenue

    Singular can collect data about in-app events to help analyze the performance of your campaigns and measure KPIs. For example, your organization may want to collect data about user logins, registrations, tutorial completions, or leveling up in a gaming app.

    Tracking Events

    Singular supports a variety of standard events. These commonly used events are often supported by ad networks for reporting and optimization. Another advantage is that when you use standard event names, Singular recognizes them automatically and adds them to the Events list without you having to define them manually. We recommend using standard events whenever possible.

    To log an event use the event() method, passing an event name and any optional attributes as key/value pairs in a standard Object.

    The standard Singular event names are defined as constants in the SingularEvents class and similarly standard attributes are defined in the SingularAttributes class.

    var args:Object = {};
    args[SingularAttributes.CONTENT] = "Tutorial name";
    args[SingularAttributes.CONTENT_ID] = "contentId";
    args[SingularAttributes.CONTENT_TYPE] = "type of content";
    args[SingularAttributes.SUCCESS] = true;

    var success:Boolean = Singular.instance.event( SingularEvents.TUTORIAL_COMPLETE, args );

    Send the standard event "Subscribe" (sng_subscribe), no attributes

    Singular.instance.event( SingularEvents.SUBSCRIBE );

    Send a custom event named "bonus_points_earned" with a custom attribute

    Singular.instance.event(
    "bonus_points_earned",
    {
    "points": 500
    }
    );

    Tracking Revenue

    Singular can collect data about revenue gained through the app to help analyze the performance and ROI of your campaigns. Singular will make the data available to you in reports, log export, and postbacks.

    To send revenue information call the revenue() method and pass the currency and amount.

    Singular.instance.revenue( "AUD", 1.99 );

    You can also pass product information along with the revenue information:

    Singular.instance.revenue(
    "AUD",
    0.86,
    "product_id", // product sku / id
    "test product", // product name
    "testing_cat", // product category
    1, // product quantity
    0.86 // product price
    );
    - + \ No newline at end of file diff --git a/docs/speech/add-the-extension/index.html b/docs/speech/add-the-extension/index.html index bb4ff144217..8d12ba62d95 100644 --- a/docs/speech/add-the-extension/index.html +++ b/docs/speech/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Speech

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Speech.ane # Speech extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    • You will need to set the configuration values for usage in the extension. Call the following to step through the configuration values for this extension:
    apm project config set com.distriqt.Speech

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Speech.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/speech/authorisation/index.html b/docs/speech/authorisation/index.html index 97261fc329f..114c65d84c2 100644 --- a/docs/speech/authorisation/index.html +++ b/docs/speech/authorisation/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Authorisation

    In order to use the speech recognition functionality you must first request certain permissions from the user.

    Authorisation Status

    You can determine the current authorisation status by calling:

    var authorisationStatus:String = Speech.instance.recogniser.authorisationStatus;

    This value will be one of the values defined in the AuthorisationStatus class:

    switch (Speech.instance.recogniser.authorisationStatus)
    {
    case AuthorisationStatus.AUTHORISED:
    // Your app is authorised to use speech recognition
    break;

    case AuthorisationStatus.DENIED:
    // Your app has been denied authorisation to use speech recognition
    break;

    ...
    }

    When the status is AuthorisationStatus.NOT_DETERMINED you can request authorisation.

    Request Authorisation

    You request authorisation by calling the requestAuthorisation() function. This call will dispatch an event when complete:

    Speech.instance.recogniser.addEventListener( AuthorisationEvent.CHANGED, auth_changedHandler );

    Speech.instance.recogniser.requestAuthorisation();


    function auth_changedHandler( event:AuthorisationEvent ):void
    {
    Speech.instance.recogniser.removeEventListener( AuthorisationEvent.CHANGED, auth_changedHandler );

    // Handle new authorisation status
    }
    - + \ No newline at end of file diff --git a/docs/speech/changelog/index.html b/docs/speech/changelog/index.html index 39d9cff6d58..3f52517e9de 100644 --- a/docs/speech/changelog/index.html +++ b/docs/speech/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.10.19 [v2.0.1]

    release build

    2023.09.03 [v2.0.0]

    feat: add text to speech functionality

    2023.09.03 [v1.3.0]

    initial release 

    feat(ios): add additional transcription result possibilities
    feat(android): add dispatch of partial results
    feat: add isListening flag to check if the recogniser is active
    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag
    feat(android): Move to new permissions request process

    2023.01.18 [v1.2.0]

    feat(ios): add additional transcription result possibilities
    feat(android): add dispatch of partial results
    feat: add isListening flag to check if the recogniser is active
    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag
    feat(android): Move to new permissions request process
    - + \ No newline at end of file diff --git a/docs/speech/index.html b/docs/speech/index.html index abee9b890c9..dd56c4c950d 100644 --- a/docs/speech/index.html +++ b/docs/speech/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Speech

    The Speech extension gives access to Text-to-Speech and Speech-to-Text (speech recognition) functionality.

    Features:

    • Speech recognition - attempts to listen to the microphone and convert audio to text
    • Text to speech - converts text strings to spoken audio output
    • Single API interface - your code works across supported platforms with no modifications
    • Sample project code and ASDocs reference

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    AIR
    Speech.instance.tts.initialise(
    function ( success:Boolean ):void
    {
    if (success)
    {
    Speech.instance.tts.speak( new Utterance( "Hello!" ) );
    }
    }
    );

    More information here:

    com.distriqt.Speech

    License

    You can purchase a license for using this extension:

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/speech/recognition/index.html b/docs/speech/recognition/index.html index 797e19a62c1..245b263d6cd 100644 --- a/docs/speech/recognition/index.html +++ b/docs/speech/recognition/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Speech Recognition

    All speech recognition functionality is handled through the SpeechRecogniser interface which can be accessed through the recogniser property on the main extension: Speech.instance.recogniser.

    Start listening

    To process audio from the microphone call the startListening() method. This will activate an audio recording session and start passing the audio through the speech recogniser.

    This process may dispatch the following events:

    • SpeechRecogniserEvent.RESULT: When the recogniser decodes audio to text;
    • SpeechRecogniserEvent.ERROR: If an error occurs;
    Speech.instance.recogniser.addEventListener( SpeechRecogniserEvent.RESULT, resultHandler );
    Speech.instance.recogniser.addEventListener( SpeechRecogniserEvent.ERROR, errorHandler );
    Speech.instance.recogniser.startListening();

    function resultHandler( event:SpeechRecogniserEvent ):void
    {
    trace( "result: " + event.result.formattedString );
    }

    function errorHandler( event:SpeechRecogniserEvent ):void
    {
    trace( "errorHandler [" + event.errorCode + "]:" + event.error )
    }

    startListening() will return a Boolean value, indicating whether the process was started successfully. It may return false if recognition is not supported or there was an error creating the audio session. (An error event may also be dispatched depending on the error).

    On a SpeechRecogniserEvent.RESULT event there is a result property which is an instance of the SpeechRecogniserResult class. This class contains a formattedString representing all the detected speech in the audio. It also contains a segments array representing each of the individual detected words.

    On a SpeechRecogniserEvent.ERROR there will be an errorCode that can be identified from the definitions in the SpeechRecogniserError class.

    Options

    Speech recognition has a few options you can set via an instance of the SpeechRecogniserOptions class passed as the parameter to the startListening() method.

    var options:SpeechRecogniserOptions = new SpeechRecogniserOptions();

    Speech.instance.recogniser.startListening( options );

    Using the options you can control whether you prefer "on device" or "network" recognition:

    var options:SpeechRecogniserOptions = new SpeechRecogniserOptions()
    .setPreferOnDevice( false );

    The default prefers on device, so if you want to use network enabled speech recognition (generally more accurate) you should disable this option as above.

    Listening

    You can check the isListening flag at any point to determine if the extension is currently actively listening for speech.

    if (Speech.instance.recogniser.isListening)
    {
    // extension is listening
    }

    Stop listening

    Once you have completed your recognition process you must call stopListening() to end the audio session and stop the speech recognition task.

    Speech.instance.recogniser.stopListening();

    You can remove your event listeners at this point.

    - + \ No newline at end of file diff --git a/docs/speech/texttospeech/index.html b/docs/speech/texttospeech/index.html index 684db3e3e6c..63787d0aec1 100644 --- a/docs/speech/texttospeech/index.html +++ b/docs/speech/texttospeech/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Text to Speech

    All text-to-speech functionality is handled through the TextToSpeech interface which can be accessed through the tts property on the main extension: Speech.instance.tts.

    Checking for support

    You can check whether text to speech functionality is available on the current device by checking the isSupported property:

    if (Speech.instance.tts.isSupported)
    {
    // TTS functionality is available on this device
    }

    Initialise

    You will need to initialise the Text to Speech functionality by calling the initialise() function and awaiting the result.

    You can await the result either through the callback function:

    Speech.instance.tts.initialise(
    function ( success:Boolean ):void
    {
    trace( "initialise complete: " + success )
    }
    );

    Or via standard events:

    • TextToSpeechEvent.INITIALISE_SUCCESS: If the text to speech functionality was initialised successfully;
    • TextToSpeechEvent.INITIALISE_ERROR: If an error occurred;
    Speech.instance.tts.addEventListener( TextToSpeechEvent.INITIALISE_SUCCESS, initialiseSuccessHandler );
    Speech.instance.tts.addEventListener( TextToSpeechEvent.INITIALISE_ERROR, initialiseErrorHandler );

    Speech.instance.tts.initialise();

    function initialiseSuccessHandler( event:TextToSpeechEvent ):void
    {

    }

    function initialiseErrorHandler( event:TextToSpeechEvent ):void
    {

    }

    Speak

    To use the text to speech output call the speak() method passing in an instance of the Utterance class. This class represents a series of spoken words and access to any available options.

    As a minimum you need to pass the text to be spoken to the constructor of the Utterance class:

    var utterance:Utterance = new Utterance( "Hello!" );

    Then to initiate this output:

    Speech.instance.tts.speak( utterance );

    Shutdown

    If you no longer require text to speech functionality you can call shutdown() to release any allocated resources and stop any current output. Once you call this method you will need to initialise the TTS functionality again.

    Speech.instance.tts.shutdown();

    This will also terminate any output currently in progress.

    - + \ No newline at end of file diff --git a/docs/square libs/changelog/index.html b/docs/square libs/changelog/index.html index 084a748b3fb..fe0504c2cb6 100644 --- a/docs/square libs/changelog/index.html +++ b/docs/square libs/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.03.27 [v4.2.0]
    feat(okhttp): update okio v1.17.5
    feat(okhttp3): update sdk v3.14.0 (okio v1.17.5)
    chore(picasso): update build
    2022.05.04 [v4.1.0]
    feat(sdk): updated SDK versions
    - okhttp v2.7.5
    - okhttp v3.12.1
    - okio v1.17.5
    - picasso v2.71828
    2022.05.04 [v4.1.0]
    feat(sdk): updated SDK versions
    - okhttp v2.7.5
    - okhttp v3.12.1
    - okio v1.17.5
    - picasso v2.71828
    2021.08.20 [v4.0.2]
    AIR package release
    2020.09.01 [v4.0.001]
    Updated SDK versions
    - okhttp v2.7.5
    - okhttp v3.11.0
    - okio v1.15.0
    - picasso v2.71828
    2020.04.20 [v3.0.0]
    Added okhttp3 library
    2020.04.02 [v2.0.0]
    Updated builds to latest
    2020.03.20 [v2.0.0]
    Android X migration (resolves #2)
    2019.08.13 [v1.1.0]
    Android 64bit update (resolves #1)
    2018.10.18 [v1.0.0]
    Update preparing for Firebase Firestore integration
    2018.09.20 [v1.0.0]
    Initial square open source libraries ANE release
    - + \ No newline at end of file diff --git a/docs/squarelibs/changelog/index.html b/docs/squarelibs/changelog/index.html index 7c53bd31741..864b0d23dd4 100644 --- a/docs/squarelibs/changelog/index.html +++ b/docs/squarelibs/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2022.05.04 [v4.1.0]
    feat(sdk): updated SDK versions
    - okhttp v2.7.5
    - okhttp v3.12.1
    - okio v1.17.5
    - picasso v2.71828
    2022.05.04 [v4.1.0]
    feat(sdk): updated SDK versions
    - okhttp v2.7.5
    - okhttp v3.12.1
    - okio v1.17.5
    - picasso v2.71828
    2021.08.20 [v4.0.2]
    AIR package release
    2020.09.01 [v4.0.001]
    Updated SDK versions
    - okhttp v2.7.5
    - okhttp v3.11.0
    - okio v1.15.0
    - picasso v2.71828
    2020.04.20 [v3.0.0]
    Added okhttp3 library
    2020.04.02 [v2.0.0]
    Updated builds to latest
    2020.03.20 [v2.0.0]
    Android X migration (resolves #2)
    2019.08.13 [v1.1.0]
    Android 64bit update (resolves #1)
    2018.10.18 [v1.0.0]
    Update preparing for Firebase Firestore integration
    2018.09.20 [v1.0.0]
    Initial square open source libraries ANE release
    - + \ No newline at end of file diff --git a/docs/styles/index.html b/docs/styles/index.html index 9695f96ece9..f3f2b17e1ad 100644 --- a/docs/styles/index.html +++ b/docs/styles/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    styles

    You can write content using GitHub-flavored Markdown syntax.

    trace( "test" );

    Markdown Syntax

    To serve as an example page when styling markdown based Docusaurus sites.

    Headers

    H1 - Create the best documentation

    H2 - Create the best documentation

    H3 - Create the best documentation

    H4 - Create the best documentation

    H5 - Create the best documentation
    H6 - Create the best documentation

    Emphasis

    Emphasis, aka italics, with asterisks or underscores.

    Strong emphasis, aka bold, with asterisks or underscores.

    Combined emphasis with asterisks and underscores.

    Strikethrough uses two tildes. Scratch this.


    Lists

    1. First ordered list item
    2. Another item
      • Unordered sub-list.
    3. Actual numbers don't matter, just that it's a number
      1. Ordered sub-list
    4. And another item.
    • Unordered list can use asterisks
    • Or minuses
    • Or pluses

    I'm an inline-style link

    I'm an inline-style link with title

    I'm a reference-style link

    You can use numbers for reference-style link definitions

    Or leave it empty and use the link text itself.

    URLs and URLs in angle brackets will automatically get turned into links. http://www.example.com/ or http://www.example.com/ and sometimes example.com (but not on GitHub, for example).

    Some text to show that the reference links can follow later.


    Images

    Here's our logo (hover to see the title text):

    Inline-style: alt text

    Reference-style: alt text

    Images from any folder can be used by providing path to file. Path should be relative to markdown file.

    img


    Code

    var s = 'JavaScript syntax highlighting';
    alert(s);
    s = "Python syntax highlighting"
    print(s)
    No language indicated, so no syntax highlighting.
    But let's throw in a <b>tag</b>.
    function highlightMe() {
    console.log('This line can be highlighted!');
    }

    Tables

    Colons can be used to align columns.

    TablesAreCool
    col 3 isright-aligned\$1600
    col 2 iscentered\$12
    zebra stripesare neat\$1

    There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown.

    MarkdownLessPretty
    Stillrendersnicely
    123

    Blockquotes

    Blockquotes are very handy in email to emulate reply text. This line is part of the same quote.

    Quote break.

    This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can put Markdown into a blockquote.


    Inline HTML

    Definition list
    Is something people use sometimes.
    Markdown in HTML
    Does *not* work **very** well. Use HTML tags.

    Line Breaks

    Here's a line for us to start with.

    This line is separated from the one above by two newlines, so it will be a separate paragraph.

    This line is also a separate paragraph, but... This line is only separated by a single newline, so it's a separate line in the same paragraph.


    Admonitions

    note

    This is a note

    tip

    This is a tip

    info

    This is important

    caution

    This is a caution

    danger

    This is a warning

    - + \ No newline at end of file diff --git a/docs/systemgestures/add-the-extension/index.html b/docs/systemgestures/add-the-extension/index.html index 1e773751f5d..78e4d5e064f 100644 --- a/docs/systemgestures/add-the-extension/index.html +++ b/docs/systemgestures/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    AIR SDK

    This ANE currently requires at least AIR 33+. This is required in order to support versions of Android > 9.0 (API 28). We always recommend using the most recent build with AIR especially for mobile development where the OS changes rapidly.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.SystemGestures

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.SystemGestures.ane # SystemGestures extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Supported

    Note you should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    if (SystemGestures.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/systemgestures/changelog/index.html b/docs/systemgestures/changelog/index.html index 53c67430e23..9a70a6e9b79 100644 --- a/docs/systemgestures/changelog/index.html +++ b/docs/systemgestures/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.27 [v2.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2021.10.12 [v2.1.46]

    Add air package
    Remove ios minimum version flag

    2021.02.09 [v2.1.045]

    Updated build to latest iOS version and corrected default lib

    2020.07.15 [v2.1.040]

    Added Home indicator control through setPrefersHomeIndicatorAutoHidden

    2020.03.20 [v2.0.034]

    Android X migration (resolves #6)

    2019.07.01 [v1.2.030]

    Android 64bit support (resolves #5)

    2018.08.09 [v1.1.027]

    Added swipe and native gestures
    tvOS support (resolves #1)

    2018.05.11 [v1.0.018]

    Documentation update

    2018.05.11 [v1.0.017]

    Public release
    - + \ No newline at end of file diff --git a/docs/systemgestures/defer-system-gestures/index.html b/docs/systemgestures/defer-system-gestures/index.html index 597972d66e2..8aebbd24433 100644 --- a/docs/systemgestures/defer-system-gestures/index.html +++ b/docs/systemgestures/defer-system-gestures/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Defer System Gestures

    On iOS 11 Apple has introduced a range of system gestures to interact with the OS without having to use the physical home button, such as to display Control Center.

    These system gestures can interfere with your application gestures, in which case iOS gives you the opportunity to defer these gestures allowing your application to grab these interactions. By deferring the gesture the OS will instead show a small tab, indicating the presence of the system UI without fully extending it. Your user can then repeat the gesture to get to the normal system UI, if they still require.

    Whenever possible, you should allow the system gestures to take precedence. However, immersive apps can set this property to make app-defined gestures take precedence over the system gestures.

    Deferring

    In order to defer the system gestures you will need to indicate the edges of the screen for which you want your gestures to take precedence over the system gestures. This is done by calling the setDeferredScreenEdges function and passing the ScreenEdges you require to defer.

    For example to defer the BOTTOM screen edge system gesture:

    SystemGestures.service.setDeferredScreenEdges( ScreenEdges.BOTTOM );

    To set multiple edges you should bitwise OR the ScreenEdges values together, eg: ScreenEdges.BOTTOM | ScreenEdges.LEFT

    For example to defer the BOTTOM and LEFT screen edges system gestures:

    SystemGestures.service.setDeferredScreenEdges( ScreenEdges.BOTTOM | ScreenEdges.LEFT );

    If you wish to disable all screen edge gestures use the ScreenEdges.ALL value: SystemGestures.service.setDeferredScreenEdges( ScreenEdges.ALL )

    Resetting

    To enable system gestures again you can call:

    SystemGestures.service.setDeferredScreenEdges( ScreenEdges.NONE );
    - + \ No newline at end of file diff --git a/docs/systemgestures/home-indicator/index.html b/docs/systemgestures/home-indicator/index.html index bfbbdb04970..587863bbc15 100644 --- a/docs/systemgestures/home-indicator/index.html +++ b/docs/systemgestures/home-indicator/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Home Indicator

    On certain iOS devices there is a visual home indicator for returning to the home screen. This appears as a white bar towards the bottom of the screen.

    The system default is for this indicator to be shown at all times however you can hide the indicator by calling the setPrefersHomeIndicatorAutoHidden() function:

    SystemGestures.service.setPrefersHomeIndicatorAutoHidden( true );

    This will indicate that the system is allowed to hide the visual indicator for returning to the Home screen.

    This is not a guarantee that the indicator will be hidden, just advising the system that it should hide the indicator when appropriate.

    The system takes your preference into account, but returning YES is not a guarantee that an indicator will be hidden.

    Also be aware that there are Apple guidelines around this indicator, basically:

    • avoid controls around the indicator;
    • don't add any adornments or attempt to change it's appearance;
    • generally show the indicator unless you have a passive viewing experience (eg video, photos etc)
    - + \ No newline at end of file diff --git a/docs/systemgestures/index.html b/docs/systemgestures/index.html index edbc56ab211..5373b187f5a 100644 --- a/docs/systemgestures/index.html +++ b/docs/systemgestures/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    This extension is provided for free. If it helps you please consider sponsoring the developers to continue support and development of the extension:

    ❤️ Sponsor

    SystemGestures

    The SystemGestures extension gives you the ability to control the system gestures, particularly on iOS 11 +.

    Features

    • Defer screen edge gestures to allow your immersive application access to edge gestures
    • Access native gestures and Apple remote events (menu / select / play pause)
    • Sample project code and ASDocs reference

    Documentation

    Latest documentation can be found in the documentation site along with the asdocs.

    Quick Example:

    SystemGestures.service.setDeferredScreenEdges( ScreenEdges.BOTTOM );

    Native Extensions

    The highest quality and widest range of Native Extensions for Adobe AIR

    With many native extensions available, we are the leading provider of native extensions for AIR developers. Our mobile solutions allow developers to fast-forward development and focus on building great games and apps.

    https://airnativeextensions.com

    Acknowledgements

    This extension was made possible with support by BeachBum Ltd. and continued support from distriqt.

    - + \ No newline at end of file diff --git a/docs/systemgestures/native-gesture-events/index.html b/docs/systemgestures/native-gesture-events/index.html index 3da61a9be3d..141ae1fd576 100644 --- a/docs/systemgestures/native-gesture-events/index.html +++ b/docs/systemgestures/native-gesture-events/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Native Gesture Events

    General Gestures

    There are a few gestures that a consistent across iOS and tvOS

    • NativeGestureEvent.GESTURE_SWIPE_UP: Dispatched when the user swipes up on the screen or on the Apple remote;
    • NativeGestureEvent.GESTURE_SWIPE_DOWN: Dispatched when the user swipes down on the screen or on the Apple remote;
    • NativeGestureEvent.GESTURE_SWIPE_LEFT: Dispatched when the user swipes left on the screen or on the Apple remote;
    • NativeGestureEvent.GESTURE_SWIPE_RIGHT: Dispatched when the user swipes right on the screen or on the Apple remote;

    Apple Remote Buttons

    There are a few native gesture events specific to the Apple remote button presses including:

    • NativeGestureEvent.SELECT: Dispatched when the touch area on the remote is presssed;
    • NativeGestureEvent.MENU: Dispatched when the Menu button on the remote is presssed;
    • NativeGestureEvent.PLAYPAUSE: Dispatched when the Play/Pause button on the remote is presssed;

    Listening for events

    Listening for these gesture events is the same as any other event listener. Use the addEventListener function on the SystemGestures instance:

    SystemGestures.service.addEventListener( NativeGestureEvent.GESTURE_SWIPE_DOWN, swipeHandler );


    function swipeHandler( event:NativeGestureEvent ):void
    {
    trace( "swipe: " + event.type );
    }

    Note: you shouldn't add these listeners in the first frame / class constructor on iOS. There appears to be some conflict with AIR on iOS so you should wait around 100 milliseconds from launch before attaching these listeners to ensure consistency.

    - + \ No newline at end of file diff --git a/docs/tutorials/android-adaptive-icons/index.html b/docs/tutorials/android-adaptive-icons/index.html index 40aec433666..5e37f507364 100644 --- a/docs/tutorials/android-adaptive-icons/index.html +++ b/docs/tutorials/android-adaptive-icons/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Android Adaptive Icons

    Android 8.0 (API level 26) introduces adaptive launcher icons, which can display a variety of shapes across different device models. For example, an adaptive launcher icon can display a circular shape on one OEM device, and display a squircle on another device. Each device OEM provides a mask, which the system then uses to render all adaptive icons with the same shape. Adaptive launcher icons are also used in shortcuts, the Settings app, sharing dialogs, and the overview screen.

    You can control the look of your adaptive launcher icon by defining 2 layers, consisting of a background and a foreground. You must provide icon layers as drawables without masks or background shadows around the outline of the icon.

    More information:

    Adobe AIR

    Currently AIR does not generate adaptive icons automatically. You will most likely see your icon surrounded by a white area as in the icon on the left below. By adding adaptive icons we can make our AIR application a first class citzen with an icon that adapts with the OS. The icon on the right implements the adaptive icons approach contained here.

    There are two steps to adding adaptive icons to your application:

    • Creating or generating the adaptive icon resources;
    • Packaging these resources with your application.

    There is no changes to the code of your application required, only the need to generate and package additional resources.

    Note: You should still package icons using the existing method in AIR (in the application descriptor) in order to correctly support older versions of Android that do not support adaptive icons (< v26)!

    Additionally if you want to enable "round" icons you need to add the android:roundIcon tag to your application node in the manifest additions:

    <manifest android:installLocation="auto">

    <uses-sdk android:targetSdkVersion="28" />

    <!-- PERMISSIONS ETC -->

    <application
    ...
    android:roundIcon="@mipmap/icon_round"
    ...
    >

    You must only use the android:roundIcon attribute if you require a different icon asset for circular masks, if for example the branding of your logo relies on a circular shape.

    Generating Adaptive Icons

    Adaptive icons use a foreground image and a background image or colour to create the icon.

    The foreground image can contain transparency but the background image should not.

    The simplest way to create the resources is to open up a new project in Android Studio and launch the image asset tool.

    • Launch Android Studio;
    • Create a new project with an empty activity and fill in some dummy information for the project;
    • Open the Android view in the Project explorer;
    • Right click on the res folder and select New > Image Asset

    This will launch the tool:

    • Select Launcher Icons (Adaptive and Legacy) from the icon type;
    • Enter icon in the Name field. It is important that you use this name to correctly integrate with AIR;
    • Set your foreground and background layers as per your requirements;
      • You can import an image for the foreground and background;
      • Scale images appropriately;
    • Click next and finish the process.

    You should now have a list of resources in the `res/mipmap-`* folders:

    These folders are the resources that you will need to package in the next section.

    The following link contains an example of the resources we have used in some of our example applications.

    The important file to note is the mipmap-anydpi-v26/icon.xml. This is the file that defines the adaptive icon layers as you see below:

    <?xml version="1.0" encoding="utf-8"?>
    <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@mipmap/icon_background"/>
    <foreground android:drawable="@mipmap/icon_foreground"/>
    </adaptive-icon>

    The other files are just the different sized image resources for the different device screen densities.

    Packaging

    There are several approaches you can take to package the resources you have created above with your application. The modern approach in AIR uses a "resources directory", a specific directory that you can inform AIR to treat as resources that should be added to your application package.

    Simply place all the resources you created above into this resources directory and follow this guide on adding the resources directory to your application.

    Summary:

    • Create a directory called res (or similar) in your application source;
    • Add your resources into this directory;
    • Add the <resdir>res</resdir> node to your application descriptor;
    • Package your application as normal.
    Legacy approaches

    Legacy approaches

    The following methods have been used in the past prior to the ability of using the resources directory.

    caution

    Do not use these approaches unless you cannot move to the new resources directory approach. These are deprecated and are no longer recommended.

    Resources in ANEs

    It is possible to to package your adaptive icon in a Custom Resources ANE.

    This has the advantage of not requiring modification of the AIR SDK, instead simply packaging an ANE with your application containing the adaptive icon.

    All that is required here is adding the resources created above to your custom resources extension and packaging that ANE with your application. Follow the directions in the repository link above to help create your custom resources extension, or contact us and we can create one for you.

    Modifying the AIR SDK

    The simplest method to give your AIR application an adaptive icon is to add your adaptive icon resources to the AIR SDK.

    This method requires no creation of an ANE and similarly requires no changes to your code, however you will have to modify your version of the AIR SDK, for each application you package.

    To get started open up the AIR SDK Android resources directory located at AIRSDK/lib/android/lib/resources/app_entry/res/. This directory contains all of the resources that AIR will package with your application.

    Copy all the resources you generated earlier in the mipmap folders into the AIR SDK directory, being careful to merge any existing folders. Now repackage your application with the modified SDK and you should now see the adaptive icon.

    - + \ No newline at end of file diff --git a/docs/tutorials/android-device-debugging/index.html b/docs/tutorials/android-device-debugging/index.html index d419e34fd9f..32481cc4e20 100644 --- a/docs/tutorials/android-device-debugging/index.html +++ b/docs/tutorials/android-device-debugging/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Android Device Debugging

    Android

    In order to debug an application on an Android device you need to enable "Developer Mode" and then enable USB debugging.

    Enabling developer mode opens up an additional settings menu that allows you to enable different development options.

    To enable "Developer mode":

    • Go to the settings menu
    • Open "System" and then "About phone"
    • Tap Build number several times and you should see a dialog that says "you're X taps away from being a developer".
    • Continue tapping the build number until the developer mode is enabled.

    To enable USB debuging:

    • Go to the settings menu
    • Open "System" and then the new "Developer options" menu
    • Make sure "USB debugging" is enabled.

    You will now be able to connect a usb cable to your device and use the adb tool to install applications (APKs) and access the device logs.

    - + \ No newline at end of file diff --git a/docs/tutorials/android-resources/index.html b/docs/tutorials/android-resources/index.html index 4fc84ac711b..0e81d0d2df1 100644 --- a/docs/tutorials/android-resources/index.html +++ b/docs/tutorials/android-resources/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Android Resources

    With Android additional files and static content are defined as resources, this includes images, layouts, strings, configuration, icons and more.

    Sometimes you will need to include resources with your AIR application either to configure a service (such as Firebase) or to provide visual assets for system interactions (such as notification icons).

    Note

    AIR in the past has not had a direct method for including these resources and instead you have had to build a native extension to package these resources with your application.

    However, with AIR 33.1.1.406, Harman has now introduced several options to simply include resources with your application.

    Gather Resources

    The first step is always to assemble your resources into a folder. Generally we use a folder named res to keep it inline with the Android equivalent however you should be able to use any folder name. For example:

    res/
    drawable/
    graphic.png
    mipmap/
    icon.png
    values/
    values.xml
    strings.xml

    Generally you will use tools to assemble these resources for you, such as the Android Asset Studio Notification Icon Generator

    Packaging

    Once you have your resources, you can use one of the methods below to package these resources with your application.

    Application Descriptor

    info

    Requires AIR 33.1.1.406 or higher

    The simplest method (and the method we suggest using) is specifying the resource directory in your application descriptor.

    To do this, simply add the resdir tag to your application descriptor:

    <resdir>res</resdir>

    Place this at the same level as the android tag, eg:

    <?xml version="1.0" encoding="utf-8" standalone="no"?>
    <application xmlns="http://ns.adobe.com/air/application/33.1">

    <!-- Other application descriptor elements -->

    <android>
    <manifestAdditions><![CDATA[
    <!-- MANIFEST ADDITIONS -->
    ]]></manifestAdditions>
    </android>

    <resdir>res</resdir>


    </application>

    The resdir can be either the:

    • relative path (as above);
    • absolute path;

    When using a relative path, specify the location of the folder relative to your content, eg:

    bin-debug/
    icons/
    icon16x16.png
    icon29x29.png
    icon32x32.png
    icon36x36.png
    ...
    example.swf
    example-app.xml
    res/
    values/
    values.xml

    We recommend using the relative path, especially if you are dealing with multiple developers where absolute paths could change between systems.

    Command Line

    info

    Requires AIR 33.1.1.300 or higher

    If you can modify the adt command used to build your application you can add a command line option to specify the resources directory similar to the previous method.

    To do this, add the -resdir option to your command specifying the path to your resources directory.

    Unfortunately this process cannot be used by most IDEs as you cannot modify the command directly so we don't suggest using this method.

    Custom ANE

    Previous to AIR 33.1.1.300/406 you would have had to generate a custom resources native extension and add this to your application.

    To this end we made a script available in the following repository to build this extension for you:

    https://github.com/distriqt/ANE-CustomResources/

    This project uses an Apache Ant build script to create and package an ANE with your custom Android resources.

    Follow the guide in the repository to generate this extension.

    This is still a viable solution for AIR, but we recommend the application descriptor solution for new applications.

    - + \ No newline at end of file diff --git a/docs/tutorials/android-splash-screen/index.html b/docs/tutorials/android-splash-screen/index.html index 7bb50e8593c..095f4498cef 100644 --- a/docs/tutorials/android-splash-screen/index.html +++ b/docs/tutorials/android-splash-screen/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Android Splash Screen

    Android doesn't have a built in method of displaying an image at launch like iOS does however there are some techniques we can use to achieve a similar goal.

    Modifying the AIR SDK

    The simplest method to give your AIR application a splash screen on Android is to change the theme of the main AIR activity to contain an image and a background colour.

    This method generally requires no modification to your application code, however you will have to modify your version of the AIR SDK.

    To get started open up the AIR SDK styles.xml file located at AIRSDK/lib/android/lib/resources/app_entry/res/values/styles.xml

    This file should contain the following:

    <resources>
    <style name="Theme.NoShadow" parent="android:style/Theme.NoTitleBar">
    <item name="android:windowContentOverlay">@null</item>
    </style>
    </resources>

    To start, remove android:windowContentOverlay and add a android:windowBackground as below:

    <resources>
    <style name="Theme.NoShadow" parent="android:style/Theme.NoTitleBar">
    <item name="android:windowBackground">@drawable/splash_background</item>
    </style>
    </resources>

    This will set a splash_background resource as the background. Lets create this resource by adding a splash_background.xml file at the following location: AIRSDK/lib/android/lib/resources/app_entry/res/drawable/splash_background.xml

    This is where we will create the background for your application which will appear as the splasg screen.

    Reverting

    To revert your changes you simply revert the styles.xml to the original contents above.

    i.e.

    <resources>
    <style name="Theme.NoShadow" parent="android:style/Theme.NoTitleBar">
    <item name="android:windowContentOverlay">@null</item>
    </style>
    </resources>

    Centered Application Icon

    A simple splash screen is to use your application icon and center it in the view with a background colour.

    Add the following content to the splash_background.xml file:

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/splash_background_color" />
    <item>
    <bitmap
    android:gravity="center"
    android:src="@mipmap/icon" />
    </item>
    </layer-list>

    We will define the background colour in the colors.xml located at AIRSDK/lib/android/lib/resources/app_entry/res/values/colors.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <color name="splash_background_color">#ff0000</color>
    </resources>

    Change this background colour to suit your application.

    Once you've made these changes to the AIR SDK any Android application that is built with this AIR SDK will display your splash screen.

    Image

    Alternatively if you want to use a custom image as the splash screen you can add an image file to the resources to use as the background.

    For example lets add a splash_image.png to the drawable directory (alongside splash_background.xml), you then need to modify splash_background.xml to use this image as below:

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
    <bitmap
    android:gravity="center"
    android:src="@drawable/splash_image" />
    </item>
    </layer-list>

    When using this method we advise that you add all the different dpi versions of your image to correctly support different screen sizes: Read more here: https://developer.android.com/guide/practices/screens_support.html

    Resources in ANEs

    It is possible to to package your splash screen in a Custom Resources ANE. This has the advantage of being able to modify the SDK once and then use a custom ANE to specify the splash screen for each of your applications, rather than have to modify the AIR SDK before each build.

    This is done by setting up a default splash screen drawable resource in your AIR SDK and then overriding this resource with resources packaged in the ANE. Normally this would result in a resource conflict however we can use a small trick here. By providing a non resolution specific drawable resource in the AIR SDK and then overriding it with resolution specific versions.

    AIR SDK Modifications

    Lets start by again adjusting the AIR SDK by specifying a splash_background resource in the styles.xml resource located at AIRSDK/lib/android/lib/resources/app_entry/res/values/styles.xml:

    <resources>
    <style name="Theme.NoShadow" parent="android:style/Theme.NoTitleBar">
    <item name="android:windowBackground">@drawable/splash_background</item>
    </style>
    </resources>

    Then lets create a fallback resource a simple 1x1 pixel black png called splash_background.png and place it in the AIR SDK at AIRSDK/lib/android/lib/resources/app_entry/res/drawable/splash_background.png. This is the resource that will be used if we don't package an ANE containing the override resource.

    You should find your AIR SDK packages normally and start with the expected black screen before loading your SWF.

    ANE Resource

    Next lets create the actual resource we will use for the splash in the ANE. You can use the same methods as above however instead of placing the drawable resource in drawable place a version in each of the resolution specific directories:

    • drawable-hdpi
    • drawable-mdpi
    • drawable-xhdpi
    • drawable-xxhdpi
    • drawable-xxxhdpi

    This is the important step! If you included the resource in the drawable directory your resource would conflict with the resource created in the AIR SDK and it will fail to package. However adding it to the resolution specific directories means it can override the AIR SDK resource without causing any issues.

    This small trick was pointed out by mfrasier on the Starling forum.

    You can use a simple stretched image drawable-hdpi/splash_background.png, a 9-patch png drawable-hdpi/splash_background.9.png, or an xml resource drawable-hdpi/splash_background.xml.

    We most commonly use the xml method, including another image that is centered in the layout as a drawable:

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
    <bitmap
    android:gravity="center"
    android:src="@drawable/splash_logo" />
    </item>
    </layer-list>

    Vector Drawables

    A VectorDrawable is a vector graphic defined in an XML file as a set of points, lines, and curves along with its associated color information. You can use vector drawables in your splash screen. It was introduced in Android 5.0 (API 21).

    We have run into some issues with getting them to scale when centered on Android API < 23, but the process we used is outlined below.

    Firstly create your vector drawable resource in the drawable directory (AIRSDK/lib/android/lib/resources/app_entry/res/drawable), say splash_icon.xml, for example this renders the battery charging image from the Android Guide:

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <group
    android:name="rotationGroup"
    android:pivotX="10.0"
    android:pivotY="10.0"
    android:rotation="15.0" >
    <path
    android:name="vect"
    android:fillColor="#FF000000"
    android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z"
    android:fillAlpha=".3"/>
    <path
    android:name="draw"
    android:fillColor="#FF000000"
    android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z"/>
    </group>
    </vector>

    This renders:

    Then to use this in your splash screen, change your splash_background.xml file to the below:

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/splash_background_color" />
    <item
    android:gravity="center"
    android:drawable="@drawable/splash_icon">
    </item>
    </layer-list>

    Using this method you can create fairly complex scalable images without adding much to your application.

    This was generated from the following vector drawable xml:

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="100dp"
    android:height="100dp"
    android:viewportHeight="512.0"
    android:viewportWidth="512.0">
    <path
    android:fillColor="#273B7A"
    android:pathData="M256,256m-256,0a256,256 0,1 1,512 0a256,256 0,1 1,-512 0" />
    <path
    android:fillColor="#121149"
    android:pathData="M506.4,309.5L300.1,103.3l-62.2,113.4l2.3,44.8l82.5,82.5l-3.4,3.4l-35.8,-35.8l-45.6,2.9h-64.7l-66.7,105.5l83.6,83.6C211.2,509 233.2,512 256,512C379,512 481.8,425.2 506.4,309.5z" />
    <path
    android:fillColor="#FFEDB5"
    android:pathData="M401.6,290.3c-3.3,-4.6 -9.3,-6.4 -14.6,-4.4c-0.1,0 -0.2,0.1 -0.2,0.1l-89.6,29.8c0,0.7 0,1.4 -0,2.2c-0.7,11.4 -9.6,20.6 -21,21.8l-54,5.6c-3.4,0.4 -6.5,-2.1 -6.8,-5.5c-0.4,-3.4 2.1,-6.6 5.5,-6.8l54,-5.6c5.3,-0.6 9.5,-4.9 9.8,-10.2c0.2,-2.9 -0.8,-5.8 -2.7,-8c-1.9,-2.2 -4.6,-3.5 -7.6,-3.7l-71.7,-4.7c-8.1,-0.5 -16,1.3 -23.1,5.1L85,358l25.6,51.6l23.8,-20.7c10.1,-8.8 23.5,-12.6 36.7,-10.4l79.4,13.2c14.6,1.9 29.1,-1.7 41.1,-10.2l108.1,-74.5C404.5,302.8 405.4,295.5 401.6,290.3z" />
    <path
    android:fillColor="#FEE187"
    android:pathData="M274.9,327.4c5.3,-0.6 9.5,-4.9 9.8,-10.2c0.2,-2.9 -0.8,-5.8 -2.7,-8c-1.9,-2.2 -4.6,-3.5 -7.6,-3.7l-15.9,-1v24.7L274.9,327.4z" />
    <path
    android:fillColor="#FEE187"
    android:pathData="M401.6,290.3c-3.3,-4.6 -9.3,-6.4 -14.6,-4.4c-0.1,0 -0.2,0.1 -0.2,0.1l-89.6,29.8c0,0.7 0,1.4 -0,2.2c-0.7,11.4 -9.6,20.6 -21,21.8l-17.7,1.8v50.6c11.8,-0.1 23.3,-3.8 33.1,-10.7l108.1,-74.5C404.5,302.8 405.4,295.5 401.6,290.3z" />
    <path
    android:fillColor="#FFC61B"
    android:pathData="M317.4,146c0,-34.7 -28.9,-62.8 -63.9,-61.4c-31.4,1.2 -57.1,26.5 -58.9,57.9c-1.2,21.6 8.7,40.9 24.6,52.7c10.1,7.6 16.3,19.2 16.3,31.9v21.3c0,11.3 9.2,20.5 20.5,20.5l0,0c11.3,0 20.5,-9.2 20.5,-20.5V227.4c0,-12.8 6.2,-24.6 16.5,-32.3C307.8,183.9 317.4,166 317.4,146z" />
    <path
    android:fillColor="#EAA22F"
    android:pathData="M255.4,84.6v184.2c0.2,0 0.4,0 0.6,0c11.3,0 20.5,-9.2 20.5,-20.5V227.4c0,-12.8 6.2,-24.6 16.5,-32.3c14.9,-11.2 24.5,-29 24.5,-49.1C317.4,111.9 289.6,84.3 255.4,84.6z" />
    <path
    android:fillColor="#A6A8AA"
    android:pathData="M235.5,227.9v20.5c0,11.3 9.2,20.5 20.5,20.5l0,0c11.3,0 20.5,-9.2 20.5,-20.5v-20.5L235.5,227.9z" />
    <path
    android:fillColor="#808183"
    android:pathData="M255.4,227.9v40.9c0.2,0 0.4,0 0.6,0c11.3,0 20.5,-9.2 20.5,-20.5v-20.5L255.4,227.9z" />
    <path
    android:fillColor="#FF5419"
    android:pathData="M244.2,183.8c-1.1,0 -2.3,-0.3 -3.3,-1.1c-2.5,-1.8 -3,-5.3 -1.2,-7.8l17.1,-23.4H244.2c-2.1,0 -4,-1.2 -5,-3.1c-1,-1.9 -0.8,-4.1 0.5,-5.8l23.6,-32.3c1.8,-2.5 5.3,-3 7.8,-1.2c2.5,1.8 3,5.3 1.2,7.8L255.2,140.4h12.6c2.1,0 4,1.2 5,3.1c1,1.9 0.8,4.1 -0.5,5.8l-23.6,32.3C247.6,183 245.9,183.8 244.2,183.8z" />
    <path
    android:fillColor="#C92F00"
    android:pathData="M272.3,117c1.8,-2.5 1.3,-6 -1.2,-7.8c-2.5,-1.8 -6,-1.3 -7.8,1.2l-7.9,10.8v18.9L272.3,117z" />
    <path
    android:fillColor="#C92F00"
    android:pathData="M267.8,140.4h-12.4v11.2h1.4l-1.4,1.9v18.9l16.9,-23.1c1.2,-1.7 1.4,-3.9 0.5,-5.8C271.8,141.6 269.9,140.4 267.8,140.4z" />
    <path
    android:fillColor="#D35933"
    android:pathData="M66.1,355.1l32.5,-22.2l40.5,64.7l-32.5,22.2z" />
    <path
    android:fillColor="#B54324"
    android:pathData="M139.1,397.6l-20.5,-32.8l-32.4,22.5l20.4,32.6z" />
    </vector>
    - + \ No newline at end of file diff --git a/docs/tutorials/device-logs/index.html b/docs/tutorials/device-logs/index.html index 15717bd34a6..28c49da09d5 100644 --- a/docs/tutorials/device-logs/index.html +++ b/docs/tutorials/device-logs/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Access the Device Logs

    Getting access to the device logs often yields additional information when attempting to isolate an issue with an ANE. We may sometimes ask for you to provide these logs in order for us to debug an issue or isolate a problem.

    Android

    On Android it is relatively simple to get the device logs. The debugger command line utility (adb/adb.exe) can be used to output the logs along with installing your application and is packaged as part of AIR at AIRSDK/lib/android/bin. If you have installed the Android SDK you can also use the version from there.

    Note: It is important you have set your device into debug mode.

    macOS (OSX)

    To access the logs:

    • open a Terminal
    • run adb logcat

    You can get more relevant information by using grep to filter the logs. For example, we often use the following:

    adb logcat | grep -E --color=always 'distriqt|AndroidRuntime|System.err'

    Windows

    To access the logs:

    • open a Command Prompt window
    • run AIRSDK\lib\android\bin\adb.exe logcat

    iOS

    On iOS, there are 2 types of logs, "Device Logs" and the "Console". The device logs are crash reports and generally aren't very useful to us unless we can resymbolcate your application. However the console is quite helpful and contains debugging information output from the ANE's.

    macOS (OSX)

    iOS has changed its logging method in iOS 10 so there are 2 ways to retrieve the logs depending on the version of iOS you have on your device.

    iOS < 10

    To get access to the console:

    • Open Xcode
    • Navigate to Window / Devices
      • click on your device in the left panel
      • ignore the "Device Logs" button (this is the crash reports mentioned)
      • click the small triangle in the bottom left of the right panel to expand the 'console log'
      • copy and paste this log when an issue occurs

    iOS 10 +

    To access the console open the Console application and select the device in the left hand panel.

    You can use the filter to search the logs for any relevant information.

    libimobiledevice

    Using these tools you can do a range of iOS device related tasks, such as installing an application and accessing the device logs.

    Firstly install the tools using homebrew:

    brew install --HEAD usbmuxd
    brew install --HEAD libimobiledevice
    brew install --HEAD ideviceinstaller

    Then in a terminal type:

    idevicesyslog

    Reference

    Windows

    It is possible to get the logs on a Windows machine. There are several methods that we have found to be reliable, using iTunes and the other using a program called iTools.

    If you know of a better way please let us know and we will add it to this answer.

    iOSLogInfo Tool

    Using this tool from Blackberry appears to be the best option for Windows developers.

    Requires the iOSLogInfo tool and iTunes installed.

    Steps:

    • Download and save the iOSLoginfo zip download by clicking here.
    • Extract the zip file contents.
    • Ensure iTunes for Windows is installed.
    • Connect your iOS device to a PC.
    • From a command prompt navigate to the location you extracted the above contents and run one of the following to start a live log collection session:
    sdsiosloginfo.exe -d

    OR to write the contents to a log file run:

    sdsiosloginfo.exe -d > c:\ios_log.log

    Reference

    iTools

    It is possible to get the device logs on a Windows machine using a program called iTools. You will need to get a copy of this program, be aware that there are spyware versions of this program so don't just download any version of it.

    We have had users have success with the version from this Chinese website (an english version is available): http://pro.itools.cn/.

    We in no way endorse or accept any responsibility for using this program, use at your own risk.

    iTunes

    The crash logs are transferred to iTunes everytime you sync your device. These aren't as helpful as the device logs but can yield information about an issue in some circumstances. To start plugin your device, launch iTunes and start the synchronisation process.

    The logs are copied to your file system which you can locate using the following:

    • Open Explorer
    • Enter %appdata%
    • Navigate to : Roaming\Apple computer\Logs\CrashReporter\Mobile Device\DEVICENAME

    You should see a list of log files starting with the name of the application, locate your application name and open the log

    libimobiledevice

    These tools should work on Windows as well however we haven't tested this option:

    Reference

    Disclaimer

    Any links to third-party software available on this website are provided “as is” without warranty of any kind, either expressed or implied and such software is to be used at your own risk.

    - + \ No newline at end of file diff --git a/docs/tutorials/getting-started-animate/index.html b/docs/tutorials/getting-started-animate/index.html index ed201aca831..20e5cf328b9 100644 --- a/docs/tutorials/getting-started-animate/index.html +++ b/docs/tutorials/getting-started-animate/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Getting Started - Animate

    This tutorial will guide you the process of adding an ANE to your AIR application project in Adobe Animate.

    An AIR Native Extension (ANE) is a single file with the extension ane. This file contains all of the native and actionscript libraries that are implemented by this extension. You don’t need access to a separate SWC file or to the source code to be able to use the ANE.

    Adding the Extension

    In Animate and Flash CC / CS6 Adobe have added the ability to simply add an ANE to your AIR project.

    You will need to open the Actionscript settings for your project. There are several ways to access this panel either directly through the properties or through the menu as we show below.

    In your AIR project FLA file, open your applications publish settings, by going to File > Publish Settings.

    Select the wrench icon next to the Script dropdown. This will bring up the ActionScript Settings dialog.

    Select the Library path tab and click Browse to a Native Extension (ANE) file, as shown above, and select the ANE file. You should now be able to use the extensions functionality in your project and CS6 will include the ANE code when you publish your application.

    This process should add the extension id to your application descriptor however we find it's always good practice to double check with Animate.

    Adding the Extension ID

    The extension id is a string that is used to identify the ANE and correctly package and create the extension. The extension id should be provided by the developer of the ANE.

    To add the extension id, open up your application descriptor and add the extension id to the extensions node as below:

    <?xml version="1.0" encoding="utf-8" ?>
    <application xmlns="http://ns.adobe.com/air/application/26.0">

    <!-- OTHER DESCRIPTOR INFORMATION -->

    <extensions>
    <extensionID>com.distriqt.Battery</extensionID>
    </extensions>

    </application>
    - + \ No newline at end of file diff --git a/docs/tutorials/getting-started-flashbuilder4.5/index.html b/docs/tutorials/getting-started-flashbuilder4.5/index.html index 8349616e464..e0ebf7cd591 100644 --- a/docs/tutorials/getting-started-flashbuilder4.5/index.html +++ b/docs/tutorials/getting-started-flashbuilder4.5/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Getting Started - Flash Builder 4.5

    An AIR Native Extension (ANE) is a single file with the extension ane. This file contains all of the native and actionscript libraries that are implemented by this extension. You don’t need access to a separate SWC file or to the source code to be able to use the ANE.

    Here we will add the extension to your build process so that your application can use the functionality provided by the extension.

    The older version of Flash Builder is a lot more complex to get running and unless you are forced to I highly recommend updating to 4.6/4.7. It involves a few scripts and tricks to get it running which we will show on OSX here, but you should be easily able to adapt it to other operating systems.

    There are many methods but this is what we have found to be the simplest.

    Firstly rename the ANE file to have the extension SWC.

    com.distriqt.Camera.ane    >     com.distriqt.Camera.swc

    Note: Changing the ANE file extension from .ane to .swc is not strictly necessary. When you browse to find the file, in the “Choose a SWC file” dialog box, you can change the setting of the Files Of Type drop-down field. It is set by default to .swc. Change it to .*. This will have the same effect.

    Then we include the SWC like we do any normal SWC, open:

    Project / Project Properties / Flex/Actionscript Build Path 

    In the Library Path tab, click Add SWC...

    Browse to the SWC file and select Open. The ANE file should now appear in the screen above. You need to now expand the SWC entry and double click the Link Type to open the Library Path Options dialog, as below:

    Change the Link Type to be External instead of the default Merged into code.

    You should now be able to compile your project, using Project > Build Project.

    Note: You won’t be able to run this application through the debugger as it won’t correctly package the extension through Flash builder.

    Application Descriptor

    All AIR applications have an application descriptor file. When an application uses a native extension, the application descriptor file includes an <extensions> element. This node is generally located as the last node in the application descriptor. For example the following shows two extensions added to an application:

    <extensions>
    <extensionID>com.distriqt.Core</extensionID>
    <extensionID>com.distriqt.Camera</extensionID>
    </extensions>

    You will need to manually add the extension ID to the application descriptor at this stage.

    To enable the extension in your application you need to add some additional information to your application descriptor. Basically this informs the compiler of what extensions are required in your application. Some IDEs will add this automatically but it is important to understand what is changing when you add an extension into your application.

    More details on the extensions ID can be found here.

    An extension may also require additional permissions or definitions in the application descriptor. For example, requesting permission to access the vibration function with a vibrate extension. You should carefully consult the extensions documentation and add any required additions to the application descriptor. Incorrectly updating the descriptor may mean the extension cannot correctly operate.

    Packaging

    Now you’ll need to open up a command line in the directory of your built application. The directory should contain:

    • application swf: myApp.swf
    • application descriptor: myApp-app.xml
    • any required files such as icons, Default.png
    • the ANE(s) (in a subdirectory we’ll assume extensionsDir in the following)

    The details on this command is dependent on the application you are developing and the platform you are targeting. You should review the documentation at the following url to determine the details of what the command should contain for your environment.

    http://help.adobe.com/en_US/air/build/WS597e5dadb9cc1e0253f7d2fc1311b491071-8000.html

    For example the following command will create an APK for Android:

    adt -package
    -target apk
    -storetype pkcs12 -keystore YOUR_SIGNING_KEY.p12
    myApp.apk
    myApp-app.xml
    myApp.swf icons
    -extdir extensionsDir
    - + \ No newline at end of file diff --git a/docs/tutorials/getting-started-flashbuilder4.7/index.html b/docs/tutorials/getting-started-flashbuilder4.7/index.html index 894d7ab1398..deec45909d2 100644 --- a/docs/tutorials/getting-started-flashbuilder4.7/index.html +++ b/docs/tutorials/getting-started-flashbuilder4.7/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Getting Started - Flash Builder 4.6/4.7

    Add the Extension

    An AIR Native Extension (ANE) is a single file with the extension ane. This file contains all of the native and actionscript libraries that are implemented by this extension. You don’t need access to a separate SWC file or to the source code to be able to use the ANE.

    Here we will add the extension to your build process so that your application can use the functionality provided by the extension.

    In your mobile project you want to add it into, open up the project properties by right clicking on your project and selecting Properties. Find the "Actionscript Build Path" (or "Flex Build Path" if it's a Flex project).

    You will see a tab up the top labeled Native Extensions in which you can Add ANE....

    Click on this and select the ANE extension file. Once it's added in, you can expand out the details of the extension to see the target platforms supported by the extension. Below I'm showing the details on our Android Camera Extension.

    The extension is now included in your project, however before you leave the project settings, go to the "Build Packaging" for the platforms you are deploying and check the extension is going to be packaged (and available) with them.

    You should now be able to return to your code and use the functionality and classes supplied in the extension, hopefully you've been supplied with documentation or example usage of the extension.

    - + \ No newline at end of file diff --git a/docs/tutorials/getting-started-flashdevelop/index.html b/docs/tutorials/getting-started-flashdevelop/index.html index 9d3c1d6e1bc..c6f8d6911f9 100644 --- a/docs/tutorials/getting-started-flashdevelop/index.html +++ b/docs/tutorials/getting-started-flashdevelop/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Getting Started - Flash Develop

    This tutorial will guide you the process of adding an ANE to your AIR application project in FlashDevelop.

    An AIR Native Extension (ANE) is a single file with the extension ane. This file contains all of the native and actionscript libraries that are implemented by this extension. You don’t need access to a separate SWC file or to the source code to be able to use the ANE.

    Adding the Extension

    For the purposes of this example we are going to create directories named extensions and extensions-extracted. You can name the directories as you require, and they can be the same directory if you wish, however we will keep them separated here to demonstrate the usage of each.

    • Copy the ANE to the extensions directory;
    • In FlashDevelop, right click on the ANE file and select Add To Library
    • Unzip the ANE to a folder named extension_id.ane, in the extensions-extracted directory
      • the extension id is not neccessarily the same as the name of the ANE file however with nearly all distriqt's ANEs it will be, see below to determine howto get the extension id from an ANE;

    An ANE is simply a zip container so you can directly unzip it, or if you need to, rename it to have the .zip extension and open it in your zip software.

    For example with the Battery ANE, you should have the following:

    extensions/com.distriqt.Battery.ane

    extensions-extracted/com.distriqt.Battery.ane/mimetype
    extensions-extracted/com.distriqt.Battery.ane/catalog.xml
    extensions-extracted/com.distriqt.Battery.ane/library.swf
    extensions-extracted/com.distriqt.Battery.ane/META-INF/ANE/extension.xml
    extensions-extracted/com.distriqt.Battery.ane/META-INF/ANE/Android-ARM/library.swf
    extensions-extracted/com.distriqt.Battery.ane/META-INF/ANE/Android-ARM/distriqt.extension.battery.android.jar
    ...

    Unzipping the extension to the extracted directory is used by Flash Develop for debug launches. You should ensure every time you update an ANE that you update the extracted folder as well.

    Adding the Extension ID

    FlashDevelop requires that you manually add the extension id to your application descriptor.

    The extension id is a string that is used to identify the ANE and correctly package and create the extension. The extension id should be provided by the developer of the ANE.

    To add the extension id, open up your application descriptor and add the extension id to the extensions node as below:

    <?xml version="1.0" encoding="utf-8" ?>
    <application xmlns="http://ns.adobe.com/air/application/26.0">

    <!-- OTHER DESCRIPTOR INFORMATION -->

    <extensions>
    <extensionID>com.distriqt.Battery</extensionID>
    </extensions>

    </application>

    Determining the Extension ID

    The native extension ID is not necessarily the name of the ANE file. If you are unsure of the extension id it can be determined from the extracted contents of the ANE.

    • Unzip the ANE;
    • Open META-INF/ANE/extension.xml;
    • Find the <id> tag, this will contain the extension id;

    For example for the Battery ANE:

    <extension xmlns="http://ns.adobe.com/air/extension/4.0">
    <id>com.distriqt.Battery</id>
    <versionNumber>1.0.0</versionNumber>
    <platforms>
    ...

    With the distriqt extensions the extension id is the name of the ANE file, eg for the Battery ANE the file is com.distriqt.Battery.ane and the extension id is com.distriqt.Battery.

    Extensions that have multiple versions, eg PushNotifications, where there are multiple files:

    • com.distriqt.PushNotifications.ane
    • com.distriqt.PushNotifications.AllServices.ane
    • com.distriqt.PushNotifications.Azure.ane
    • com.distriqt.PushNotifications.FCM.ane

    the extension id is the first part of the filename without the variant: i.e. com.distriqt.PushNotifications

    If you have any concerns drop a question in github and we will clear up any confusion.

    Modify Build Scripts

    FlashDevelop uses a series of scripts to package and run your application. We have to modify these scripts to be able to correctly specify the location of the extensions.

    Packager.bat

    The packager script is used to package your application. You will need to find the adt line and add the -extdir option specifying the directory containing the extensions as follows:

    call adt -package %OPTIONS% %SIGNING_OPTIONS% -target native %AIR_TARGET% %APP_XML% %FILE_OR_DIR% -extdir extensions/

    Run.bat

    The run script is used for debugging your content. We need to find the adl line which is the debug launcher and add the -extdir option as follows:

    adl "%APP_XML%" "%APP_DIR%" -extdir extensions-extracted/

    You will now be able to package and use the extension in your application.

    - + \ No newline at end of file diff --git a/docs/tutorials/getting-started-intellij/index.html b/docs/tutorials/getting-started-intellij/index.html index f7573c8cda1..fbd6aa9c411 100644 --- a/docs/tutorials/getting-started-intellij/index.html +++ b/docs/tutorials/getting-started-intellij/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Getting Started - IntelliJ

    This tutorial will guide you the process of adding an ANE to your AIR application project in IntelliJ IDEA.

    An AIR Native Extension (ANE) is a single file with the extension ane. This file contains all of the native and actionscript libraries that are implemented by this extension. You don’t need access to a separate SWC file or to the source code to be able to use the ANE.

    We are assuming you have already been through the process of getting AIR development setup in IntelliJ including:

    • enabling Flash/Flex support;
    • setting AIR SDK paths;
    • creating an AIR project.

    Adding the ANE

    Open the project you wish to use the ANE and open the module settings of the main module for your application.

    Select the Dependencies tab. This lists all the libraries that your project depends on including SWCs, ANEs and other build configurations.

    At the bottom of the window, select the + icon to add a dependency and select New library.

    Navigate to the location of your ANE and once selected it should appear in the window as a dependency. For example in the following screen shot we have added the Battery ANE:

    Adding the Extension ID

    IntelliJ requires that you manually add the extension id to your application descriptor.

    The extension id is a string that is used to identify the ANE and correctly package and create the extension. The extension id should be provided by the developer of the ANE.

    To add the extension id, open up your application descriptor and add the extension id to the extensions node as below:

    <?xml version="1.0" encoding="utf-8" ?>
    <application xmlns="http://ns.adobe.com/air/application/26.0">

    <!-- OTHER DESCRIPTOR INFORMATION -->

    <extensions>
    <extensionID>com.distriqt.Battery</extensionID>
    </extensions>

    </application>

    With the distriqt extensions the extension id is the name of the ANE file, eg for the Battery ANE the file is com.distriqt.Battery.ane and the extension id is com.distriqt.Battery.

    Extensions that have multiple versions, eg PushNotifications, where there are multiple files:

    • com.distriqt.PushNotifications.ane
    • com.distriqt.PushNotifications.AllServices.ane
    • com.distriqt.PushNotifications.Azure.ane
    • com.distriqt.PushNotifications.FCM.ane

    the extension id is the first part of the filename without the variant: i.e. com.distriqt.PushNotifications

    If you have any concerns drop a question in github and we will clear up any confusion.

    You will now be able to package and use the extension in your application.

    Specifying ANEs as Global Libraries

    A useful feature of IntelliJ is being able to setup global libraries. This allows you to setup the path to ANEs (or SWCs) that you use regularly as a global reference and then just select them from the list of globals when adding to a project.

    This is particularly useful for ANEs that are used across all projects, such as the Google Play Services ANEs, Android Support ANEs and the Core ANE.

    Adding a Global Library

    To add a global library, open your module settings and select Global Libraries:

    In the list above you can see all the Google Play Services, Android support and Core ANEs which we use in just about every project. Having them defined as globals makes it much easier to add them to your projects.

    To add a new global, click the + button at the top and select Actionscript/Flex:

    Then simply navigate to an ANE and select it.

    Using a Global Library

    To use a global library ANE simply go to the Dependencies tab of your module settings, select add a dependency and select Project or Global Library:

    Then select the global you wish to use and click OK:

    You will still need to add the extension id as previously described.

    Notes and Warnings

    Multiple ANEs in a single directory

    If you are using any of our ANEs with variants (eg Push Notifications), IntelliJ has a unusual bug of including the first ANE with matching extension id from the directory rather than the one you actually select through the file selection dialogs.

    So if you have a directory of several ANEs with the same extension id (as our variants have been in the past) and want to use the FCM variant and have just pointed IntelliJ to that ANE inside the github repository, you have to make sure to remove all the other ANEs from that directory to ensure the correct one gets packaged with your application.

    To avoid this we are in process of separating all our variant ANEs into different directories, so you may never encounter this issue. However we just want to make note of this issue in the IntelliJ IDE.

    This doesn't happen with other IDEs.

    Changing JDK

    If you have an older Android application you may have an 1024bit certificate that you are using to sign the application. In order to use these you must use a version of Java that supports them as they have been deprecated in current releases.

    If you don't use the older JDK then when entering the password for your certificate you may encounter an "invalid certificate" error.

    To handle older 1024 bit certificates you will need to ensure IntelliJ is using JDK version 1.8.112 (or earlier).

    Firstly download and install v1.8.0_112 of the JDK:

    v2018.2 + :

    Earlier:

    • "Double shift" to bring up search menu and type: "Switch boot jdk"
    • Select the JDK v112
    • Save and restart
    - + \ No newline at end of file diff --git a/docs/tutorials/getting-started/index.html b/docs/tutorials/getting-started/index.html index 127890e2df1..218a012311d 100644 --- a/docs/tutorials/getting-started/index.html +++ b/docs/tutorials/getting-started/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Adding an Extension

    These tutorials will cover adding a Native Extension for Adobe AIR to your application.

    We are going to be focusing on the native extensions developed by distriqt, but these guides should apply to any native extension (ANE).

    Native Extensions for Adobe AIR are code libraries that contain native code wrapped with an ActionScript API. Native extensions provide easy access to device-specific libraries and features that are not available in the built-in ActionScript classes.

    Their usage is similar to a SWC package of precompiled Flash symbols and code.

    In the following tutorials we are going to go through the process of adding an ANE to your AIR application using some of the most common AIR development tools. We assume you already understand the process of developing and deploying mobile applications using AIR so will just be concentrating on the additional steps required to get an ANE working.

    To get started select the IDE you are using from the list below:

    - + \ No newline at end of file diff --git a/docs/tutorials/index.html b/docs/tutorials/index.html index d4bcefca5f2..a30526bdaa7 100644 --- a/docs/tutorials/index.html +++ b/docs/tutorials/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Tutorials

    This site contains a range of tutorials for using native extensions in your applications.

    - + \ No newline at end of file diff --git a/docs/tutorials/ios-icons-assets-car/index.html b/docs/tutorials/ios-icons-assets-car/index.html index b15b143e307..02ed59fdcb3 100644 --- a/docs/tutorials/ios-icons-assets-car/index.html +++ b/docs/tutorials/ios-icons-assets-car/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Icons, Launch Storyboards and the Assets Catalog

    From iOS 11 Apple now requires a new process of adding icons to your application, you can no longer simply package them as you have done with previous versions of iOS and AIR. Instead you need to create an asset catalog (Assets.car file) and package in the root directory of your application.

    Note: The Assets.car file is needed for iOS 11+ when you are using AIR SDK v28+

    Additionallyu from iOS 13 Apple now requires a new process of adding launch / splash screens to your application, you can no longer simply package the "default.png" images in your application you have done with previous versions of iOS and AIR.

    Note: Apple will soon enforce launch screens with the iOS 13 requirement so this will be a prerequisite for publishing in the AppStore

    Contents:

    Method 1 Command Line

    note

    You will need a macOS machine with Xcode 9+ for this method to generate the Assets.car file

    This is the method we prefer as it is simpler to update and create than having to drag files into Xcode. We have a script that downloads the required assets, resizes an icon and launch screen image appropriately and calls the xcode utilities to generate the Assets.car (and launch screen).

    The script is available in the AIR-ImageScripts repository

    You will need to have installed imagemagick and the xcode command line utilities (see details in the repository if you need help installing them).

    To use it, create an icon.png file that is a high resolution icon file (we suggest 1024x1024) and a launch.png launch screen image (we suggest a large 2732x2732 pixel image). Place them in a directory and open a terminal at this location. You can either clone the repository and use the generate.sh script directly or call it as below:

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/distriqt/AIR-ImageScripts/master/generate.sh)"

    Once complete this will have generated an out directory that contains

    • Assets.car your asset catalogue
    • LaunchScreen.storyboardc directory is your custom launch screen storyboard
    • icons directory containing icon images sized for AIR.

    Copy these into your application as you require.

    You can use the icons directory in your application descriptor by adding the following:

    <icon>
    <image16x16>icons/icon16x16.png</image16x16>
    <image29x29>icons/icon29x29.png</image29x29>
    <image32x32>icons/icon32x32.png</image32x32>
    <image36x36>icons/icon36x36.png</image36x36>
    <image40x40>icons/icon40x40.png</image40x40>
    <image48x48>icons/icon48x48.png</image48x48>
    <image57x57>icons/icon57x57.png</image57x57>
    <image58x58>icons/icon58x58.png</image58x58>
    <image60x60>icons/icon60x60.png</image60x60>
    <image72x72>icons/icon72x72.png</image72x72>
    <image76x76>icons/icon76x76.png</image76x76>
    <image80x80>icons/icon80x80.png</image80x80>
    <image87x87>icons/icon87x87.png</image87x87>
    <image114x114>icons/icon114x114.png</image114x114>
    <image120x120>icons/icon120x120.png</image120x120>
    <image128x128>icons/icon128x128.png</image128x128>
    <image144x144>icons/icon144x144.png</image144x144>
    <image152x152>icons/icon152x152.png</image152x152>
    <image167x167>icons/icon167x167.png</image167x167>
    <image180x180>icons/icon180x180.png</image180x180>
    <image512x512>icons/icon512x512.png</image512x512>
    <image1024x1024>icons/icon1024x1024.png</image1024x1024>
    </icon>

    Method 2 Using Xcode

    Note: You will need a macOS machine with Xcode 9+ for this method to generate the Assets.car file

    Firstly you will need to open Xcode and create a new application

    • Start a new project and select the "Single View App" under the iOS section (or tvOS section if you are creating this file for a tvOS application).

    • Fill Product Name, Organization Name and Organization Identifier (no specific names required).

    • Save the project
    • In the left hand panel select the Assets.xcassets file

    • Select the AppIcon

    • Add all the required versions of the AppIcon

    • Build the project ( Product -> Build).
    • Right-click on your ‘.app’ -> Show in finder.
    • Right click on your ‘.app’ -> Show package contents.
    • Now copy Assets.car and package with AIR application.

    If you want to include a launch storyboard see here.

    Method 3 Online tool

    This is the simplest way if you are a Windows developer.

    Simply go to the following url:

    http://applicationloader.net/appuploader/icontool.php

    and upload a 1024x1024 image of your icon. You will get a zip download containing the Assets.car file and all the icon sizes needed to embed in your iOS application.

    Using this method you will not be able to add the LaunchImage so you will have to add a story board manually.

    Packaging Asset Catalog

    The Assets.car file must be placed at the root of your application, this means alongside your swf and other application content.

    You do this by ensuring that it is in the root of your applications source and selected as a single file in your application package.

    Simple Launch Screen

    To simplify migration to launch storyboards we have created a simple storyboard that pulls an image from your Assets.car and aspect fills it to the screen. You will add a single image to your Assets.car alongside your application icons. (If you followed the instructions above this will be the LaunchImage.png you added.)

    Download this zip file and extract the LaunchScreen.storyboardc. Add it to your application and ensure it is packaged at the root level of your application alongside your Assets.car.

    LaunchScreen.storyboardc is a directory but will appear as a "file" (package) on macOS

    Add the following to the InfoAdditions node in your application descriptor:

    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>

    That is all, you have now implemented a launch storyboard.

    Supporting previous versions of iOS

    You must also make sure that you include the icons in your application using the icon tags in the application descriptor xml. This ensures that older versions of iOS still have the correct icons packaged and that other platforms still have the appropriate app icons.

    Launch images

    Recently Apple changed the supported names of the files for the default / launch images. Make sure you have correctly added the default images according to the Adobe docs:

    http://blogs.adobe.com/airodynamics/2015/03/09/launch-images-on-ios-with-adobe-air/

    - + \ No newline at end of file diff --git a/docs/tutorials/ios-launchscreens/index.html b/docs/tutorials/ios-launchscreens/index.html index d1b1de44b56..1ab312f94cb 100644 --- a/docs/tutorials/ios-launchscreens/index.html +++ b/docs/tutorials/ios-launchscreens/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Launchscreen

    From iOS 13 Apple now requires a new process of adding launch / splash screens to your application, you can no longer simply package the "default.png" images in your application you have done with previous versions of iOS and AIR.

    Note: Apple will soon enforce launch screens with the iOS 13 requirement so this will be a prerequisite for publishing in the AppStore

    This guide shows how to create the launch storyboard directly in Xcode.

    Contents:

    Method 1

    This simple method uses a prebuilt storyboard which pulls an image from your Assets.car and fill the screen keeping the aspect ratio (your image may be cropped on some devices depending on the resolution).

    We have included these instructions as part of the Icons, Launch Storyboards and the Assets Catalog guide.

    Method 2

    Using Xcode

    Note: You will need a macOS machine with Xcode 9+ for this method to generate the Assets.car file

    As this process is tightly integrated with generating the Assets.car (asset catalog) containing your application icons, we will go through adding the icons first.

    Firstly you will need to open Xcode and create a new application

    • Start a new project and select the "Single View App" under the iOS section (or tvOS section if you are creating this file for a tvOS application).

    • Fill Product Name, Organization Name and Organization Identifier (no specific names required).

    • Save the project
    • In the left hand panel select the Assets.xcassets file

    • Select the AppIcon

    • Add all the required versions of the AppIcon

    Now you have added the application icons we move onto adding the launch storyboard. For this we have included 2 guides:

    • A fullscreen image, which scales to fill the screen;
    • A centered image (such as the application icon);

    Centered Icon

    Firstly we need to add the image resource to your asset catalog.

    • In the left hand panel select the Assets.xcassets file
    • Right click below the AppIcon and select New Image Set:

    |

    • Name the image set something like LaunchIcon
    • Populate the set with your image, here we have just used the distriqt app icon:

    • Select the LaunchScreen.storyboard in the left hand panel:

    • Bring up the Library, either by selecting it in the menu or pressing cmd - shift - L, then find the Image View and add it to your view:

    • In the right hand panel select the attributes tab and select your image set you added previously as the "Image":

    • Your image should appear in the image view:

    • Lastly, we need to add some constraints to align the image to the center. Select the constraints icon in the bottom right of the main view and select "Horizontally in Container", "Vertically in Container", then click "Add Constraints" to add these constraints.

    Full Screen Image

    Reference:

    https://medium.com/flawless-app-stories/change-splash-screen-in-ios-app-for-dummies-the-better-way-e385327219e

    Build

    • Build the project ( Product -> Build).
    • Right-click on your ‘.app’ -> Show in finder.
    • Right click on your ‘.app’ -> Show package contents.
    • Locate the following:
      • Assets.car
      • LaunchScreen.storyboardc

    LaunchScreen.storyboardc is a directory but will appear as a "file" (package) on macOS

    Adding to AIR

    Once you have completed your storyboard and added the application icons you can add these to your AIR applicaiton.

    • Copy Assets.car and LaunchScreen.storyboardc and package with AIR application at the root level of your application.

    • Add the following to your info additions in your application descriptor:

    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>

    i.e.:

    <iPhone>
    <InfoAdditions><![CDATA[
    <!-- ... -->
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    ]]></InfoAdditions>
    </iPhone>
    - + \ No newline at end of file diff --git a/docs/tutorials/ios-sdk-custom/index.html b/docs/tutorials/ios-sdk-custom/index.html index 7623bc9a89c..b1c7baf3670 100644 --- a/docs/tutorials/ios-sdk-custom/index.html +++ b/docs/tutorials/ios-sdk-custom/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    iOS SDK

    In the particular case of developing for iOS it is quite often a requirement that you have access to the iOS SDK to access the most recent features of the SDK.

    The AIR SDK does contain a subset of the iOS SDK however our ANEs often access parts of the SDK that aren't packaged with AIR hence you will have to provide a reference to a version of the iOS SDK in order to successfully package your application.

    If you don't do this you will encounter errors when packaging such as:

    Undefined symbols for architecture ... 

    Or

    ld: framework not found ...

    Acquire the SDK

    The first step in using the iOS SDK with your application is to acquire a version of the SDK.

    Official Method

    The official method uses Xcode on a macOS machine to download the latest version of the SDK

    You will need your Apple user ID, this is the same login you use when you access the iOS developer portal but you can sign up for a free one such as the one you use to access iTunes. The SDK is obtained through Apple’s XCode so we need to download and install that.

    Note: You’ll need an OSX machine to do this, but you can quite easily do this on windows by installing an OSX virtual machine. You’ll need this machine to get updates to the SDK but once you’ve acquired the SDK you can use it on a windows machine.

    • Go to https://developer.apple.com/devcenter/ios/index.action
    • Enter your Apple login ID information and login
    • Once you are logged in, find the “Downloads” link to “Download the latest build of iOS SDK”, it is bundled with Xcode and will be labeled something like “Xcode 4.6.1?, the combined download size of the iPhone SDK and Xcode is quite large, several gigabytes so be prepared for a wait.
    • Once Xcode is downloaded, launch the installer and follow the instructions.

    You will now have the latest version of the SDK installed on your machine. You’ll need to locate the directory, earlier version of Xcode will place the SDK here:

    /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk

    However more recent versions will place it here:

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk

    Unofficial Method

    The unofficial method involves downloading one of the zips we have packaged of the iOS SDK. Just download the compressed SDK from our site:

    Add to your Project

    Adding the SDK to your project again depends on your development tool so we will go through each individually below.

    Note: If you’re on windows you’ll need to copy the SDK directory completely to your windows machine and use that path in the following.

    IntelliJ

    In IntelliJ simply open up your module settings, select the iOS tab and enter the path to your iOS SDK in the "Apple iOS SDK" field:

    Flash Builder 4.6 / 4.7

    Under Flash Builder 4.6/4.7 you simply go to your project settings and select the Apple iOS section in the Build Packaging. You’ll see a place down the bottom to enter in or browse for the path to the iOS SDK.

    Flash Professional CS6

    In Flash CS6 you can simply go into

    File / AIR 3.x for iOS Settings...

    Check the box next to iOS SDK and enter in the path to the SDK.

    Flash Professional CS5.5 / Flash Builder 4.5

    These remaining environments require usage of the adt command line to include the SDK. In particular we’re going to be using the platformsdk option of adt.

    You should already have created a script or at least have a command to run on the command line from the previous sections. If you haven’t consult the section on Flash Builder 4.5 for a detailed guide. Windows developers using other environments should also do this.

    In order to add the iOS SDK all we need to do is add in the platformsdk option with the full path to the SDK. For example:

    adt -package
    -target ipa-test
    -provisioning-profile /path_to_provisioning_profile/Provisioning_Profile.mobileprovision
    -storetype pkcs12
    -keystore /path_to_certificate/certificate.p12
    -storepass xxxxx
    myApp.ipa
    application_xml_file.xml
    application_swf.swf
    -platformsdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk

    Command Line

    These remaining environments require usage of the adt command line to include the SDK. In particular we’re going to be using the platformsdk option of adt.

    You should already have created a script or at least have a command to run on the command line from the previous sections. If you haven’t consult the section on Flash Builder 4.5 for a detailed guide. Windows developers using other environments should also do this.

    In order to add the iOS SDK all we need to do is add in the platformsdk option with the full path to the SDK. For example:

    adt -package
    -target ipa-test
    -provisioning-profile /path_to_provisioning_profile/Provisioning_Profile.mobileprovision
    -storetype pkcs12
    -keystore /path_to_certificate/certificate.p12
    -storepass xxxxx
    myApp.ipa
    application_xml_file.xml
    application_swf.swf
    -platformsdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk

    Note: you’ll need a more recent version of AIR to use this platformsdk option. Version prior to 3.2 do not have this ability and you won’t be able to include the iOS SDK.

    - + \ No newline at end of file diff --git a/docs/tutorials/ios-sdk-versions/index.html b/docs/tutorials/ios-sdk-versions/index.html index b1f6293e633..68f8dc9b804 100644 --- a/docs/tutorials/ios-sdk-versions/index.html +++ b/docs/tutorials/ios-sdk-versions/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ This is normally required during the phase where AIR support for a platform has not yet been released.

    iOS 11

    12th September 2017

    Here we detail the usage of the iOS 11 SDK with AIR 27 beta. Using this SDK is required to use any iOS 11 features such as InAppBilling Promotions.

    This is experimental and we provide no guarantee on the following process but it has worked for our needs

    iOS 11 SDK

    Download

    Firstly you will need to download the iOS 11 SDK and slightly modify it to suit AIR.

    This can be done by downloading Xcode (GM seed at time of publishing) and installing as per the normal process.

    Copy the libgcc_s.1 library from 10.3. This library seems to be removed from 11 and is used by AIR currently.

    cp iPhoneOS10.3.sdk/usr/lib/libgcc_s.1.tbd iPhoneOS11.0.sdk/usr/lib/.

    We have logged a bug for this issue here: https://tracker.adobe.com/#/view/AIR-4198461 Please vote to have the issue resolved.

    We also have a direct download of the SDK with the above modifications available here

    AIR SDK

    Download the AIR 27 beta SDK

    Update: This appears to have been resolved in the latest AIR SDK beta for macOS

    You will need to update the linker to use the latest linker from Xcode:

    cp /Applications/Xcode-beta.app/Contents/Developer/usr/bin/ld AIRSDK/lib/aot/bin/ld64/ld64

    This is currently only possible for macOS builds

    Usage

    Once you have performed the above you can use the iOS 11 SDK to package your applications. Ensure you are:

    - + \ No newline at end of file diff --git a/docs/tutorials/windows-appx-packaging-method1/index.html b/docs/tutorials/windows-appx-packaging-method1/index.html index 40cb09c5aba..81eacde8281 100644 --- a/docs/tutorials/windows-appx-packaging-method1/index.html +++ b/docs/tutorials/windows-appx-packaging-method1/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Windows Store Packaging - Method 1

    This method gives the most versatility in editing the final package you create, giving you the ability to make changes to the AppxManifest. Additionally it simplifies testing as you only need to install a single test certificate on your machine.

    This method involves the following steps:

    Converting AIR to APPX package

    This is the first step of the packaging process across all the methods and is the most important thing the DesktopAppConverter does. It involves taking the application and converting it into the correct structure for a Windows package.

    The result we are looking for here is a directory called PackagedFiles that contains the eventual content of your appx package.

    DesktopAppConverter.exe 
    -Installer [PATH\TO\YOUR\AIR\OUTPUT]
    -AppExecutable YourApplication`.exe
    -Destination [PATH\TO\OUTPUT]
    -PackageName "[Package/Identity/Name]"
    -PackageDisplayName "[DISPLAYNAME]"
    -Publisher "CN=[Package/Identity/Publisher]"
    -PackagePublisherDisplayName "[Package/Properties/PublisherDisplayName]"
    -AppDisplayName "[DISPLAYNAME]"
    -Version [VERSION]

    This is very similar to the command used in method 2, except we are removing the -MakeAppx and -Sign options.

    Update Content

    At this point you can modify the content of the package before packaging it into the appx package.

    Most commonly you may need to add items into the AppxManifest.xml.

    We normally copy the first version of this file to another location and edit it as we require, then copy this file back into the PackagedFiles directory in our build script.

    Package into APPX

    Now that you have your package structure to convert this into an appx file we use the MakeAppx tool.

    This is the equivalent of the -MakeAppx option in the DesktopAppConverter tool

    https://docs.microsoft.com/en-us/windows/msix/package/create-app-package-with-makeappx-tool

    This tool creates application packages.

    "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\makeappx.exe" pack ^
    /d [PATH\TO\PackageFiles\] ^
    /p YourApplication.appx

    eg:

    "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\makeappx.exe" pack ^
    /d C:\build\distriqt.airnativeextensions\PackageFiles\ ^
    /p distriqt.airnativeextensions.appx

    Sign

    You will need a pfx certificate file in order to sign your appx file.

    Create a certificate

    You will need to create a certificate

    For testing we suggest creating a self-signed certificate which you can use for testing your application locally.

    https://docs.microsoft.com/en-us/windows/msix/package/create-certificate-package-signing

    For example. to create a test certificate:

    New-SelfSignedCertificate -Type Custom `
    -Subject "CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" `
    -KeyUsage DigitalSignature `
    -FriendlyName "distriqt Pty Ltd" `
    -CertStoreLocation "Cert:\CurrentUser\My" `
    -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")

    Note: It is important that the CN (common name) matches the one used in the conversion of your AIR app to APPX.

    This will output a thumbprint which you use to export the certificate:

    $password = ConvertTo-SecureString -String YOUR_CERT_PASSWORD -Force -AsPlainText
    Export-PfxCertificate -cert "Cert:\CurrentUser\My\YOUR_CERT_THUMBPRINT" -FilePath certificate.pfx -Password $password

    For store release you will need to use the certificate setup for store distribution.

    At the end of this process you should have a pfx certifcate file which you will use to sign your app.

    If you are using a test certificate, at this point you need to install the certificate onto your machine.

    To install the certificate:

    - Double click the `pfx` file
    - Select "Local Machine" for the store location
    - Check the certificate path
    - Enter your certificates password
    - Select "Place all certificates in the following store"
    - "Browse"
    - "Trusted Root Certification Authorities"

    If you don't install the certificate you will get an error about the signature when attempting to install your appx.

    Sign APPX

    In order to sign the appx file generated earlier you will use the SignTool.

    This is the equivalent of the -Sign option in the DesktopAppConverter tool

    https://docs.microsoft.com/en-us/windows/msix/package/sign-app-package-using-signtool

    For example:

    SignTool sign /fd SHA256 /a /f certificate.pfx /p <Your Password> <File path>.appx

    You will now have a signed appx application package that you can use for test installation or store release (depending on the certificate used).

    Example BAT

    The following is just some pseudo commands demonstrating how you could automate the above process into a batch file.

    @ECHO OFF
    SET BASEDIR=C:\path\to\project
    SET AIR_OUTDIR=%BASEDIR%\out\air\build
    SET UWP_OUTDIR=%BASEDIR%\out\uwp\build


    ECHO ===========================================================
    ECHO Converting to UWP application

    MKDIR %UWP_BUILDDIR%

    DesktopAppConverter.exe -Installer %AIR_BUILDDIR%\ ^
    -AppExecutable AirApplication.exe ^
    -InstallerArguments "/quiet" ^
    -Destination %UWP_OUTDIR% ^
    -PackageName "distriqt.airnativeextensions" ^
    -PackagePublisherDisplayName "distriqt" ^
    -Publisher "CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ^
    -Version 1.0.0.0


    ECHO ===========================================================
    ECHO Updating Manifest

    copy AppxManifest.xml %UWP_OUTDIR%\distriqt.airnativeextensions\PackageFiles\AppxManifest.xml


    ECHO ===========================================================
    ECHO Creating Appx

    del distriqt.airnativeextensions.appx

    "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\makeappx.exe" pack ^
    /d %UWP_OUTDIR%\distriqt.airnativeextensions\PackageFiles\ ^
    /p distriqt.airnativeextensions.appx


    ECHO ===========================================================
    ECHO Signing Appx

    "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /fd SHA256 ^
    /a /f distriqt_selfsigned.pfx /p "p4ssword" ^
    distriqt.airnativeextensions.appx

    Note: it is possible to automate the removal and install of the appx package for testing as well.

    Have a look at the Remove-AppxPackage and Add-AppxPackage powershell commands.

    - + \ No newline at end of file diff --git a/docs/tutorials/windows-appx-packaging-method2/index.html b/docs/tutorials/windows-appx-packaging-method2/index.html index cdac622543d..11a8127f409 100644 --- a/docs/tutorials/windows-appx-packaging-method2/index.html +++ b/docs/tutorials/windows-appx-packaging-method2/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Windows Store Packaging - Method 2

    Create appx from your AIR executable

    This method involves running the DesktopAppConverter directly on the exe output from your AIR build.

    This is probably the simplest method and produces an appx and self-signed certificate.

    You will have to install the certificate after each build to install the newly generated appx.

    Method

    The output from your AIR application will be a directory, containing your swf, the exe, along with the AIR runtime, ANEs, DLLs, and all the other files packaged with your application.

    This is the simplest method as you can use the output from the AIR SDK directly to create your Windows Store application (appx).

    It is important that you only have files related to your project in the directory with your executable as anything in this directory will be copied to the final application.

    Here we use the Installer parameter to point to the root folder of your packaged app files. This is the folder containing the AIRApp.exe file generated by AIR.

    DesktopAppConverter.exe 
    -Installer [PATH\TO\YOUR\AIR\OUTPUT]
    -AppExecutable AIRApp.exe
    -Destination [PATH\TO\OUTPUT]
    -PackageName "[Package/Identity/Name]"
    -PackageDisplayName "[DISPLAYNAME]"
    -Publisher "CN=[Package/Identity/Publisher]"
    -PackagePublisherDisplayName "[Package/Properties/PublisherDisplayName]"
    -AppDisplayName "[DISPLAYNAME]"
    -Version [VERSION]
    -MakeAppx
    -Sign
    -Verbose
    • -Installer points to the root folder of your packaged AIR app files.
    • -AppExecutable is the filename of your AIR application eg AIRApp.exe
    • -Destination is where the DAC should produce the output of the command.
    • -MakeAppx creates an .appx file that is the installation format of a Windows Store application.
    • PackageDisplayName: Display package name for the application
    • AppDisplayName: Display name for the application
    • -Sign generates a certificate that you can install on your computer to test the generated package. When the final package is submitted to the Store, it is automatically signed by a trusted certificate during the process, so there is no need to do it later when you are ready to publish your application.
    • -Verbose gives you better information while the conversion is happening.

    Your app has a unique identity, assigned by the Store. In order to submit your application you will need to add some parameters setting information about your application from the developer dashboard. Identity details that can be found in the App identity section of your application in the developer dashboard. This information is required to correctly package your application for store submission however can be dummy values for local testing:

    • PackageName: Package/Identity/Name
    • Publisher: Package/Identity/Publisher
    • PackagePublisherDisplayName: Package/Properties/PublisherDisplayName

    For example:

    DesktopAppConverter.exe 
    -Installer C:\work\windowsstore\example\starling\out\TestWindowsStore
    -AppExecutable TestWindowsStore.exe
    -Destination C:\work\windowsstore\example\starling\final
    -PackageName "distriqt.airnativeextensions"
    -Publisher "CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    -PackagePublisherDisplayName "distriqt"
    -PackageDisplayName "airnativeextensions"
    -AppDisplayName "airnativeextensions"
    -Version 1.0.0.0
    -MakeAppx
    -Sign
    -Verbose

    Testing the conversion

    You can now install the appx application on your local machine. In order to do this you will need to install the certificate that was used to sign the application. This will called auto-generated.cer and be located in the output path alongside your appx application file.

    To install the certificate:

    - Double click cer file
    - Select "Install Certificate..."
    - Select "Local Machine"
    - Select "Place all certificates in the following store"
    - "Browse"
    - "Trusted Root Certification Authorities"

    You can now install the application by double clicking the appx to launch the installer. This will install your application locally and have access to the UWP platform.

    - + \ No newline at end of file diff --git a/docs/tutorials/windows-appx-packaging-method3/index.html b/docs/tutorials/windows-appx-packaging-method3/index.html index 376ed5c1617..a084c0e65a4 100644 --- a/docs/tutorials/windows-appx-packaging-method3/index.html +++ b/docs/tutorials/windows-appx-packaging-method3/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Windows Store Packaging - Method 3

    Using an Installer for your AIR application

    This method involves running the DesktopAppConverter using an installer application.

    You may already have an installer for your AIR application and wish to use this to create your Windows Store application (appx) or you can generate an installer using one of the many tools available.

    You will have to install the certificate after each build to install the newly generated appx.

    Method

    The output from your AIR application will be a directory, containing your swf, the exe, along with the AIR runtime, any ANEs, and all the other files packaged with your application.

    You will then need to create an installer from this directory using one of the many windows installer tools, eg:

    Tutorials:

    You now convert your AIR application installer to a Windows Store application (appx). It is important that you only have files related to your project in the directory with your installer (i.e. C:\dac\installer below) as anything in this directory will be copied to the virtual file system to run the conversion.

    To run the conversion, use the following command, replacing the [] items to match your setup:

    DesktopAppConverter.exe 
    -Installer [PATH\TO\YOUR\AIR\INSTALLER]
    -InstallerArguments "[INSTALLEROPTIONS]"
    -Destination [PATH\TO\OUTPUT]
    -PackageName "[Package/Identity/Name]"
    -Publisher "CN=[Package/Identity/Publisher]"
    -PackagePublisherDisplayName "[Package/Properties/PublisherDisplayName]"
    -PackageDisplayName "[DISPLAYNAME]"
    -AppDisplayName "[DISPLAYNAME]"
    -Version [VERSION]
    -MakeAppx
    -Sign
    -Verbose
    • -Installer points to the installer that you want to use.
    • -InstallerArguments is where you must specify the parameter that triggers the unattended setup procedure because DAC can only work with silent installers.
    • -Destination is where the DAC should produce the output of the command.
    • -MakeAppx creates an .appx file that is the installation format of a Windows Store application.
    • PackageDisplayName: Display package name for the application
    • AppDisplayName: Display name for the application
    • -Sign generates a certificate that you can install on your computer to test the generated package. When the final package is submitted to the Store, it is automatically signed by a trusted certificate during the process, so there is no need to do it later when you are ready to publish your application.
    • -Verbose gives you better information while the conversion is happening.

    Your app has a unique identity, assigned by the Store. In order to submit your application you will need to add some parameters setting information about your application from the developer dashboard. Identity details that can be found in the App identity section of your application in the developer dashboard. This information is required to correctly package your application for store submission however can be dummy values for local testing:

    • PackageName: Package/Identity/Name
    • Publisher: Package/Identity/Publisher
    • PackagePublisherDisplayName: Package/Properties/PublisherDisplayName

    For example with our msi generated using Wix:

    DesktopAppConverter.exe 
    -Installer C:\dac\installer\TestDistriqt.msi
    -InstallerArguments "/quiet"
    -Destination C:\dac\final
    -PackageName "distriqt.airnativeextensions"
    -Publisher "CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    -PackagePublisherDisplayName "distriqt"
    -PackageDisplayName "airnativeextensions"
    -AppDisplayName "airnativeextensions"
    -Version 1.0.0.0
    -MakeAppx
    -Sign
    -Verbose

    Testing the conversion

    You can now install the appx application on your local machine. In order to do this you will need to install the certificate that was used to sign the application. This will called auto-generated.cer and be located in the output path alongside your appx application file.

    To install the certificate:

    - Double click cer file
    - Select "Install Certificate..."
    - Select "Local Machine"
    - Select "Place all certificates in the following store"
    - "Browse"
    - "Trusted Root Certification Authorities"

    You can now install the application by double clicking the appx to launch the installer. This will install your application locally and have access to the UWP platform.

    - + \ No newline at end of file diff --git a/docs/tutorials/windows-appx-packaging/index.html b/docs/tutorials/windows-appx-packaging/index.html index 9032d8c7f5e..1a5c2091c11 100644 --- a/docs/tutorials/windows-appx-packaging/index.html +++ b/docs/tutorials/windows-appx-packaging/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Windows Store Packaging

    The Desktop App Converter can be used to turn your AIR application into an appx installer for the Windows Store. This is an important process to be able to convert your AIR app into a UWP application.

    A brief article on the process can be found here

    More information on the Desktop App Converter can be found here.

    Setup the Desktop App Converter

    To set up the Desktop App Converter (DAC):

    1. Download the Desktop App Converter app from the Windows Store.

    NOTE: If you are not using the installer for you don't need the wim file and you can skip to the next step once you have the converter installed

    1. Based on your Windows build version (which you can check by opening the Start menu and typing winver), download an appropriate .wim file from the Microsoft Store.
    2. Run the Desktop App Converter as an administrator on your computer.
    3. In the prompt that appears, run this command: Set-ExecutionPolicy bypass
    4. Set up the Desktop App Converter by running this command: DesktopAppConverter.exe -Setup -BaseImage .\BaseImage-1XXXX.wim -Verbose

    TIP: Don’t put the .wim file in a folder that contains other files, such as .iso or .exe files or any other installation files, because it will get copied to your C:\ drive.

    Converting your AIR application

    This process has several approaches which vary slightly. They all start with installation of the desktop app converter (above) and then vary in the usage of the tool.

    The method we suggest involves separating out some of the automated process in order to speed up testing. In involves a few extra steps to get started but is much easier to work with once setup.

    We have listed the various approaches we have found here:

    IMPORTANT: For this process to be successful you will need to package your AIR application with the captive runtime using the -target bundle. Shared runtime is not supported!

    Submission

    You should now be able to use the appx file to submit to the store.

    You must have acquired permission to submit Desktop Bridge applications before this step. If you haven't you will see the following error:

    Package acceptance validation error: Your developer account doesn't have permission to submit apps converted with the Desktop Bridge at this time. https://aka.ms/desktopbridgeforwindowsstore

    External Docs

    Acknowledgements

    This documentation is based on the e-pity case study

    - + \ No newline at end of file diff --git a/docs/unityads/add-the-extension/index.html b/docs/unityads/add-the-extension/index.html index d7890db77c2..d8dd535cab1 100644 --- a/docs/unityads/add-the-extension/index.html +++ b/docs/unityads/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ and you need to ensure they are packaged with your application.

    You can access the Google Play Services client library extensions here: https://github.com/distriqt/ANE-GooglePlayServices.

    Note: The Google Play Services and Android Support ANEs are only required on Android devices. There are no issues packaging these extensions with all platforms as there are default implementations available which will allow your code to package without errors however if you are only building an iOS application feel free to remove the Google Play Services and Android Support ANEs from your application.

    Square Libs

    Due to several of our extensionss using the Square open source libraries the libraries have been separated into separate extensions allowing you to avoid conflicts and duplicate definitions. This means that you need to include the some of the square native extensions in your application along with this extension.

    You will add these extensions as you do with any other extension, and you need to ensure it is packaged with your application.

    This extension requires the following Square extensions:

    You can access these extensions here: https://github.com/distriqt/ANE-SquareLibs.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (UnityAds.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/unityads/changelog/index.html b/docs/unityads/changelog/index.html index 6886a54b0c5..872539fb3bb 100644 --- a/docs/unityads/changelog/index.html +++ b/docs/unityads/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.09.11 [v4.8.0]

    feat(docs): update main readme

    2023.09.11 [v4.8.0]

    initial release 

    - unity ads sdk v4.8.0

    supports initialisation and interstitial load and display
    - + \ No newline at end of file diff --git a/docs/unityads/index.html b/docs/unityads/index.html index 9da9dfa7495..c1ef4b4753e 100644 --- a/docs/unityads/index.html +++ b/docs/unityads/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    UnityAds

    The UnityAds extension gives you access to Unity Ads in your AIR application.

    We provide complete guides to get you up and running with sharing quickly and easily.

    Features

    • Unity Ads integration
    • Interstitials
    • Single API interface - your code works across iOS and Android with no modifications
    • Sample project code and ASDocs reference

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    AIR
    UnityAds.instance.initialise( GAME_ID );

    More information here:

    com.distriqt.UnityAds

    License

    You can purchase a license for using this extension:

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/unityads/initialise/index.html b/docs/unityads/initialise/index.html index d8b9b883d2c..ce63ae34fec 100644 --- a/docs/unityads/initialise/index.html +++ b/docs/unityads/initialise/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Initialising the SDK

    To initialize the SDK, you must reference your Project’s Game ID for the appropriate platform. You can locate the ID on the Monetization dashboard by selecting CURRENT PROJECT > Project Settings from the secondary navigation menu.

    In your script, you need to listen for two events that are dispatched when initialisation completes:

    • UnityAdsEvent.INITIALISE_SUCCESS: dispatched when initialisation is successful and the sdk is ready to use;
    • UnityAdsEvent.INITIALISE_ERROR: dispatched when initialisation fails due to an error;

    Initialise the SDK early in your project’s run-time life cycle before you need to load an ad. For example:

    UnityAds.instance.addEventListener( UnityAdsEvent.INITIALISE_SUCCESS, initialise_successHandler );
    UnityAds.instance.addEventListener( UnityAdsEvent.INITIALISE_ERROR, initialise_errorHandler );


    UnityAds.instance.initialise( UNITY_GAME_ID );


    function initialise_successHandler( event:UnityAdsEvent ):void
    {
    // SDK ready to use
    }

    function initialise_errorHandler( event:UnityAdsEvent ):void
    {
    trace( "initialise_errorHandler: " + event.errorType + "::" + event.message );
    }

    When an error occurs, errorType can be one of:

    • ErrorType.AD_BLOCKER_DETECTED
    • ErrorType.INTERNAL_ERROR
    • ErrorType.INVALID_ARGUMENT
    - + \ No newline at end of file diff --git a/docs/unityads/interstitials/index.html b/docs/unityads/interstitials/index.html index 400c52167db..a6c15e3ff93 100644 --- a/docs/unityads/interstitials/index.html +++ b/docs/unityads/interstitials/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Interstitials

    note

    You must initialise the SDK before attempting to load and display ads.

    To display a full-screen interstitial ad using the UnityAds API:

    1. Initialise the SDK.
    2. Use the load API to load an ad for the specified Ad Unit.
    3. After the ad loads, you can then display it using the show API.

    Load

    To load an interstitial call the load() method on the interstitials interface passing the identifier of the ad you wish to load:

    UnityAds.instance.interstitials.load( AD_UNIT_ID );

    This process will dispatch one of the following events:

    • UnityAdsInterstitialEvent.LOADED: if an ad was loaded and is ready for display;
    • UnityAdsInterstitialEvent.LOAD_ERROR: if an error occurred.

    For example:

    UnityAds.instance.interstitials.addEventListener( UnityAdsInterstitialEvent.LOADED, interstitial_loadedHandler );
    UnityAds.instance.interstitials.addEventListener( UnityAdsInterstitialEvent.LOAD_ERROR, interstitial_loadErrorHandler );

    UnityAds.instance.interstitials.load( AD_UNIT_ID );

    function interstitial_loadedHandler( event:UnityAdsInterstitialEvent ):void
    {
    // Interstitial loaded and ready to display
    }

    function interstitial_loadErrorHandler( event:UnityAdsInterstitialEvent ):void
    {
    trace( "error: " + event.errorType + "::" + event.message );
    }

    When an error occurs, errorType can be one of:

    • ErrorType.NOT_INITIALISED
    • ErrorType.INTERNAL_ERROR
    • ErrorType.INVALID_ARGUMENT
    • ErrorType.NO_FILL
    • ErrorType.TIMEOUT

    Display

    To display a loaded interstitial call the show() method on the interstitials interface passing the identifier of the ad you wish to show:

    UnityAds.instance.interstitials.show( AD_UNIT_ID );

    This process may dispatch the following events:

    • UnityAdsInterstitialEvent.START: when the ad is shown to the user;
    • UnityAdsInterstitialEvent.COMPLETE: when the ad display was completed and focus returned to your app;
    • UnityAdsInterstitialEvent.CLICK: if the user clicked the advert;
    • UnityAdsInterstitialEvent.ERROR: if an error occurred.
    UnityAds.instance.interstitials.addEventListener( UnityAdsInterstitialEvent.START, interstitial_showHandler );
    UnityAds.instance.interstitials.addEventListener( UnityAdsInterstitialEvent.CLICK, interstitial_showHandler );
    UnityAds.instance.interstitials.addEventListener( UnityAdsInterstitialEvent.ERROR, interstitial_showErrorHandler );
    UnityAds.instance.interstitials.addEventListener( UnityAdsInterstitialEvent.COMPLETE, interstitial_completeHandler );

    UnityAds.instance.interstitials.show( AD_UNIT_ID );

    function interstitial_showHandler( event:UnityAdsInterstitialEvent ):void
    {
    trace( event.type );
    }

    function interstitial_showErrorHandler( event:UnityAdsInterstitialEvent ):void
    {
    trace( "error: " + event.errorType + "::" + event.message );
    }

    function interstitial_completeHandler( event:UnityAdsInterstitialEvent ):void
    {
    // Ad completed and focus returned to your app
    }

    When an error occurs, errorType can be one of:

    • ErrorType.NOT_INITIALISED
    • ErrorType.ALREADY_SHOWING
    • ErrorType.INTERNAL_ERROR
    • ErrorType.INVALID_ARGUMENT
    • ErrorType.NOT_READY
    • ErrorType.NO_CONNECTION
    • ErrorType.VIDEO_PLAYER_ERROR
    • ErrorType.TIMEOUT
    - + \ No newline at end of file diff --git a/docs/vibration/add-the-extension/index.html b/docs/vibration/add-the-extension/index.html index fc66fcae5af..3bd34fa59e8 100644 --- a/docs/vibration/add-the-extension/index.html +++ b/docs/vibration/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Vibration

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Vibration.ane # Vibration extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Vibration.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/vibration/add-the-plugin/index.html b/docs/vibration/add-the-plugin/index.html index f22edc407fb..84cf36fb669 100644 --- a/docs/vibration/add-the-plugin/index.html +++ b/docs/vibration/add-the-plugin/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Add the Plugin

    First step is always to add the plugin to your development environment.

    Asset Store

    Open the Asset Store in your browser and add the plugin to your assets.

    Open the Package Manager (Window > Package Manager) in the Unity Editor and select the "My Assets" section. Select the plugin, and click Import in the bottom right.

    Manual Installation

    In unity you import the package by selecting Assets / Import Package / Custom Package ... and then browsing to the unity plugin package file: com.distriqt.Vibration.unitypackage.

    You can manually download the extension from our repository:

    Import the Plugin

    This will present the import dialog and display all the files for the plugin, make sure all the files are selected.

    The plugin will be added to your project and you can now use the plugins functionality in your application.

    Proguard

    If you are using a custom proguard configuration you may need to add the following line to ensure the interface class for the plugin is accessible to unity at runtime.

    -keep class com.distriqt.extension.vibration.VibrationUnityPlugin {*;}

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Vibration.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/vibration/changelog/index.html b/docs/vibration/changelog/index.html index ffcc9c02631..2adc7aa08ed 100644 --- a/docs/vibration/changelog/index.html +++ b/docs/vibration/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.25 [v5.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag (resolves #23)
    feat(feedbackgenerator): add ability to set style on an ios impact feedback generator

    2022.03.09 [v5.0.74]

    Updates for Android 31
    Update documentation for Android 31 and using apm

    2021.10.12 [v5.0.73]

    Add air package

    2021.03.23 [v5.0.072]

    Unity Plugin release
    Added Haptic Engine functionality for iOS

    2021.03.23 [v5.0.070]

    Unity Plugin release
    Added Haptic Engine functionality for iOS

    2020.03.20 [v4.0.023]

    Android X migration (resolves #18)

    2019.08.15 [v3.0.021]

    Android: Updated to VibrationEffect on API v26+ 
    Android 64bit update (resolves #17)
    Updated minimum iOS version to 9.0

    2019.03.11 [v2.1.017]

    Updated minimum iOS version to 8.0 (resolves #13)
    Embedded iOS bitcode
    Removed application keys

    2018.07.30 [v2.0.011]

    Added haptic feedback

    2018.07.21 [v1.6.005]

    Updated build to latest Android and iOS versions, removed application key requirement

    2017.07.10 [v1.6.003]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.30 [v1.6.002]

    Update documentation

    2016.12.30 [v1.6.002]

    Updated SDKs + new documentation

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.04.13

    Android: Removed potentially conflicting resources (#5)

    2015.04.13

    Android x86 Support
    Moved to new structure to support FlashBuilder 4.6 (resolves #4)

    2015.02.03

    Added check for .debug suffix in application id

    2014.12.22

    iOS: Included arm64 support (resolves #1)
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.08

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.02

    New application based key check, removing server checks

    2014.11.19

    Android isSupported 
    - Android: Fixed the isSupported flag to correctly check the hasVibrator function (Fixes #289)
    - + \ No newline at end of file diff --git a/docs/vibration/feedback-generators/index.html b/docs/vibration/feedback-generators/index.html index 034fee33dcd..4008642e65f 100644 --- a/docs/vibration/feedback-generators/index.html +++ b/docs/vibration/feedback-generators/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Feedback Generators

    Haptic feedback provides a tactile response, such as a tap, that draws attention and reinforces both actions and events. While many system-provided interface elements (for example, pickers, switches, and sliders) automatically provide haptic feedback, you can use feedback generators to add your own feedback to custom views and controls.

    When providing feedback:

    • Always use feedback for its intended purpose. Don’t select a haptic because of the way it feels.
    • The source of the feedback must be clear to the user. For example, the feedback must match a visual change in the user interface, or must be in response to a user action. Feedback should never come as a surprise.
    • Don’t overuse feedback. Overuse can cause confusion and diminish the feedback’s significance.

    Create a Feedback Generator

    To create a feedback generator you call the createFeedbackGenerator() function and specify the type of the feedback this generator will be used for. This function will return an instance of a FeedbackGenerator which you can then use to perform feedback.

    For example, to create an impact feedback generator:

    var generator:FeedbackGenerator = Vibration.service.createFeedbackGenerator( FeedbackGeneratorType.IMPACT );

    Perform Feedback

    Once you have created your generator, performing feedback is a simple matter of calling the performFeedback function:

    generator.performFeedback();
    info

    Calling these methods does not play haptics directly. Instead, it informs the system of the event. The system then determines whether to play the haptics based on the device, the application’s state, the amount of battery power remaining, and other factors.

    On Android this will additionally depend on whether the user has disabled haptic feedback in the device settings.

    Prepare

    If you are attempting to time the feedback more precisely, for example, to align with sounds, you should use the prepare function a short time before requiring feedback to ensure the hardware is in a state ready to provide feedback.

    This is currently mainly required on iOS, however it is intended to perform the same operation on Android so you should use it in the same places on all platfroms.

    iOS Documentation

    When you call this method, the generator is placed into a prepared state for a short period of time. While the generator is prepared, you can trigger feedback with lower latency.

    Think about when you can best prepare your generators. Call prepare() before the event that triggers feedback. The system needs time to prepare the Taptic Engine for minimal latency. Calling prepare() and then immediately triggering feedback (without any time in between) does not improve latency.

    To conserve power, the Taptic Engine returns to an idle state after any of the following events:

    • You trigger feedback on the generator.
    • A short period of time passes (typically seconds).
    • The generator is deallocated.

    After feedback is triggered, the Taptic Engine returns to its idle state. If you might trigger additional feedback within the next few seconds, immediately call prepare() to keep the Taptic Engine in the prepared state.

    You can also extend the prepared state by repeatedly calling the prepare() method. However, if you continue calling prepare() without ever triggering feedback, the system may eventually place the Taptic Engine back in an idle state and ignore any further prepare() calls until after you trigger feedback at least once.

    To prepare your generator simply call the prepare() function:

    generator.prepare();
    - + \ No newline at end of file diff --git a/docs/vibration/haptic-engine/index.html b/docs/vibration/haptic-engine/index.html index fc96a5c52b9..621f39bf271 100644 --- a/docs/vibration/haptic-engine/index.html +++ b/docs/vibration/haptic-engine/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Haptic Engine

    Compose and play haptic patterns to customize your app’s feedback.

    Use haptics to engage users physically, with tactile feedback that gets attention and reinforces actions.

    Your app can play custom haptic patterns crafted from basic building blocks called haptic events (HapticEvent). Events can be transient, like the feedback you get from toggling a switch, or continuous, like the vibration or sound from a ringtone. You can use transient and continuous patterns independently, or build your pattern from precise combinations of the two.

    Support

    You should check whether the current device supports the haptic engine by checking the isSupported property on the HapticEngine instance.

    if (Vibration.service.hapticEngine.isSupported)
    {
    // Haptic Engine is supported
    }

    If it is not supported you should fall back to other feedback methods, such as simple vibrations.

    danger

    Haptic Engine is only supported on iOS currently

    Create a player

    To create a player call the createAdvancedPlayer() method passing in your pattern and initial params.

    caution

    Currently the parameters to this method including the pattern are ignored. A haptic player with a single continuous pattern containing intensity and sharpness parameters will be created.

    var pattern:HapticPattern = new HapticPattern(); 

    var player:HapticAdvancedPlayer
    = Vibration.service.hapticEngine.createAdvancedPlayer( pattern );

    Control

    To start the haptic call the start() method on the HapticAdvancedPlayer instance.

    player.start();

    To stop the player, call the stop() method.

    player.stop();

    Updating

    To update a continuous haptic pattern with new dynamic parameters, call the sendParameters() method passing in the new dynamic paramaters.

    player.sendParameters(
    new HapticDynamicParams()
    .setParameter( HapticDynamicParams.INTENSITY, 0.4 )
    .setParameter( HapticDynamicParams.SHARPNESS, 0.2 )
    );

    Events

    The haptic engine may be stopped at any time due to external factors such as an incoming phone call or the application being minimised.

    When this occurs any of your players will become invalid and you should dispose them and recreate them before responding to user feedback again.

    Vibration.service.hapticEngine.addEventListener(
    HapticEngineEvent.STOPPED,
    hapticEngineStoppedHandler
    );

    function hapticEngineStoppedHandler( event:HapticEngineEvent ):void
    {
    // This indicates the engine has stopped and all players must be recreated
    if (player != null) player.dispose();
    player = null;

    // You should not recreate until needed again as this may be in the background now.
    }

    Additionally each individual player will complete it's pattern playback after an amount of time. When this occurs the complete event will be dispatched allowing you to start the player again if you wish to continue haptic feedback.

    _player.addEventListener( HapticPlayerEvent.COMPLETE, playerCompleteHandler );
    _player.start();

    function playerCompleteHandler( event:HapticPlayerEvent ):void
    {
    _player.start();
    }

    Constructing a Pattern

    Not available yet

    - + \ No newline at end of file diff --git a/docs/vibration/index.html b/docs/vibration/index.html index 3096c84402e..33f8699b7fd 100644 --- a/docs/vibration/index.html +++ b/docs/vibration/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Vibration

    The Vibration extension provides access to a device's native vibration capabilities. It also gives you the ability to provide haptic feedback to your users using the native haptic feedback process, and access to the haptic engine on iOS to provide highly customised feedback.

    Features

    • Vibrate: Provides access to native vibration functionality;
    • Provide haptic feedback using the native haptic feedback process;
    • Access the advanced haptic engine to create customised haptic feedback;
    • Single API: Works across iOS and Android with the same code;
    • Sample project code and ASDocs reference;

    The simple API allows you to quickly integrate vibration in your AIR or Unity application. Identical code base can be used across supported platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with the extension quickly and easily.

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    if (Vibration.isSupported)
    {
    Vibration.service.vibrate();
    }
    if (Vibration.isSupported)
    {
    Vibration.Instance.Vibrate();
    }

    More information here:

    com.distriqt.Vibration

    License

    You can purchase a license for using this extension:

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/vibration/unity/index.html b/docs/vibration/unity/index.html index f7c58be7782..5da395e663a 100644 --- a/docs/vibration/unity/index.html +++ b/docs/vibration/unity/index.html @@ -13,7 +13,7 @@ - + @@ -28,7 +28,7 @@ The system then determines whether to play the haptics based on the device, the application’s state, the amount of battery power remaining, and other factors.

    On Android this will additionally depend on whether the user has disabled haptic feedback in the device settings.

    Prepare

    If you are attempting to time the feedback more precisely, for example, to align with sounds, you should use the prepare function a short time before requiring feedback to ensure the hardware is in a state ready to provide feedback.

    This is currently mainly required on iOS, however it is intended to perform the same operation on Android so you should use it in the same places on all platfroms.

    iOS Documentation

    When you call this method, the generator is placed into a prepared state for a short period of time. While the generator is prepared, you can trigger feedback with lower latency.

    Think about when you can best prepare your generators. Call prepare() before the event that triggers feedback. The system needs time to prepare the Taptic Engine for minimal latency. Calling prepare() and then immediately triggering feedback (without any time in between) does not improve latency.

    To conserve power, the Taptic Engine returns to an idle state after any of the following events:

    After feedback is triggered, the Taptic Engine returns to its idle state. If you might trigger additional feedback within the next few seconds, immediately call prepare() to keep the Taptic Engine in the prepared state.

    You can also extend the prepared state by repeatedly calling the prepare() method. However, if you continue calling prepare() without ever triggering feedback, the system may eventually place the Taptic Engine back in an idle state and ignore any further prepare() calls until after you trigger feedback at least once.

    To prepare your generator simply call the prepare() function:

    generator.Prepare();

    Haptic Engine

    Compose and play haptic patterns to customize your app’s feedback.

    Use haptics to engage users physically, with tactile feedback that gets attention and reinforces actions.

    Your app can play custom haptic patterns crafted from basic building blocks called haptic events (HapticEvent). Events can be transient, like the feedback you get from toggling a switch, or continuous, like the vibration or sound from a ringtone. You can use transient and continuous patterns independently, or build your pattern from precise combinations of the two.

    Support

    You should check whether the current device supports the haptic engine by checking the isSupported property on the HapticEngine instance.

    if (Vibration.Instance.HapticEngine.IsSupported)
    {
    // Haptic Engine is supported
    }

    If it is not supported you should fall back to other feedback methods, such as simple vibrations.

    Haptic Engine is only supported on iOS currently

    Create a player

    To create a player call the createAdvancedPlayer() method passing in your pattern and initial params.

    Currently the parameters to this method including the pattern are ignored. A haptic player with a single continuous pattern containing intensity and sharpness parameters will be created.

    HapticPattern pattern = new HapticPattern();

    HapticAdvancedPlayer player
    = Vibration.Instance.HapticEngine.createAdvancedPlayer(pattern);

    Control

    To start the haptic call the start() method on the HapticAdvancedPlayer instance.

    player.Start();

    To stop the player, call the stop() method.

    player.Stop();

    Updating

    To update a continuous haptic pattern with new dynamic parameters, call the sendParameters() method passing in the new dynamic paramaters.

    player?.SendParameters(
    new HapticDynamicParams()
    .SetParameter(HapticDynamicParams.INTENSITY, 0.4)
    .SetParameter(HapticDynamicParams.SHARPNESS, 0.2)
    );

    Events

    The haptic engine may be stopped at any time due to external factors such as an incoming phone call or the application being minimised.

    When this occurs any of your players will become invalid and you should dispose them and recreate them before responding to user feedback again.

    Vibration.Instance.HapticEngine.OnStopped += HapticEngine_OnStopped;

    void HapticEngine_OnStopped(HapticEngineEvent e)
    {
    // This indicates the engine has stopped and all players must be recreated
    _player?.Dispose();
    _player = null;

    // You should not recreate until needed again as this may be in the background now.
    }

    Additionally each individual player will complete it's pattern playback after an amount of time. When this occurs the complete event will be dispatched allowing you to start the player again if you wish to continue haptic feedback.

    _player.OnComplete += player_OnComplete;
    _player.Start();

    void player_OnComplete(HapticPlayerEvent e)
    {
    _player?.Start();
    }

    Constructing a Pattern

    Not available yet

    Support

    If you need further support integrating or using this extension please feel free to contact us.

    We have been supporting developers for over 10 years and always happy to help.





    - + \ No newline at end of file diff --git a/docs/vibration/vibrate/index.html b/docs/vibration/vibrate/index.html index ff5d4f8cfda..9dab3f5ac13 100644 --- a/docs/vibration/vibrate/index.html +++ b/docs/vibration/vibrate/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ vibrate function. This parameter specifies the length of the vibration in milliseconds.

    For example, vibrate for 1 second:

    Vibration.service.vibrate( 1000 );

    You can set vibration patterns to control the length and gap between vibrations. For example, the following sets a vibrate pattern on for 200 milliseconds then off for 500 twice:

    Vibration.service.vibrate( 0, [0, 200, 500, 200, 500] );

    The last parameter allows you to repeat the pattern. The value is the index into the pattern array at which to repeat. The default -1 will not repeat the pattern, and 0 will repeat the complete pattern.

    The following example will vibrate with the pattern, repeating the entire pattern:

    Vibration.service.vibrate( 0, [0, 200, 500, 200, 500], 0 );

    If you are repeating the pattern you must call cancel() to stop the vibration.

    Cancel

    You can cancel an active vibration by calling cancel:

    Vibration.service.cancel();

    iOS

    On iOS all the parameters to vibrate are ignored and the function will produce exactly 0.4 seconds of vibration and 0.1 seconds of silence.

    - + \ No newline at end of file diff --git a/docs/volume/add-the-extension/index.html b/docs/volume/add-the-extension/index.html index 7c3bf51becc..30176594023 100644 --- a/docs/volume/add-the-extension/index.html +++ b/docs/volume/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.Volume

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.Volume.ane # Volume extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    • You will need to set the usage description strings for use in the authorisation dialogs. Call the following to step through the configuration values for this extension:
    apm project config set com.distriqt.Location

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (Volume.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/volume/changelog/index.html b/docs/volume/changelog/index.html index 748c1e58c6e..036f6790c18 100644 --- a/docs/volume/changelog/index.html +++ b/docs/volume/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.25 [v3.2.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2022.02.13 [v3.1.16]

    Update docs to use apm

    2021.10.12 [v3.1.15]

    Add air package
    Remove ios minimum version flag

    2020.04.27 [v3.1.011]

    Added isOtherAudioPlaying flag to check if background audio is playing (#24)

    2020.03.20 [v3.0.005]

    Android X migration (resolves #23)

    2019.08.15 [v2.0.002]

    Android 64bit update (resolves #22)
    Updated minimum iOS version to 9.0

    2019.06.13 [v1.11.016]

    Updated minimum iOS version to 8.0 (resolves #21)
    Embedded iOS bitcode
    Removed application keys

    2018.07.23 [v1.10.010]

    Fixed issue with setting volume on iOS 11.4 (resolves #19)

    2017.07.10 [v1.6.003]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.30 [v1.6.002]

    New documentation

    2016.12.08 [v1.6.002]

    Corrected key verification with non java package application ids (resolves #11)

    2016.10.25 [v1.5.004]

    Corrected issues with repeating sound when monitoring mute status (#9 #10)

    2016.03.24

    iOS: Corrected issue with monitorMuteState (resolves #8)

    2016.03.09

    Disabled automatic start of mute status monitoring (#7)

    2016.02.17

    Documentation update

    2016.02.17

    iOS: Included missing file for mute detection (#3)

    2016.02.17

    Implemented the isMuted function to check if the device mute switch is enabled (resolves #3)
    Android: Android: Added STREAM_VOICE_CALL to control the voice stream volume (resolves #5)

    2015.10.31

    Documentation update

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.02.16

    Minor iOS cleanup

    2015.02.16

    Updated documentation

    2015.02.16

    First release of the volume extension
    - + \ No newline at end of file diff --git a/docs/volume/index.html b/docs/volume/index.html index 2d8c38f9c6f..fe7f2abfb9f 100644 --- a/docs/volume/index.html +++ b/docs/volume/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ gives you access to the native volume, including the ability to set and retrieve the volume level, listen for volume level change events and set the volume control on Android.

    The simple API allows you to quickly integrate volume control in your AIR application in just a few lines of code. Identical code base can be used across all platforms allowing you to concentrate on your application and not device specifics.

    We provide complete guides to get you up and running with image capture quickly and easily.

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    var volume:Number = Volume.service.getVolume();

    More information here:

    com.distriqt.Volume

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/volume/silent-switch/index.html b/docs/volume/silent-switch/index.html index f1a9d7de229..0ab4ab0d825 100644 --- a/docs/volume/silent-switch/index.html +++ b/docs/volume/silent-switch/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@ whether mute has been enabled on the device.

    Volume.service.monitorMuteState( true );

    You can stop this at any time:

    Volume.service.monitorMuteState( false );

    Most Recent Mute state

    The most recently detected mute state can be retrieved using the isMuted() function.

    var isMuted:Boolean = Volume.service.isMuted();

    Listening for changes

    Once you are monitoring the mute state, change events will be dispatched. You can react in your event handlers as you see fit. There are two events, MUTED and UNMUTED representing the change to mute and unmuted respectively.

    Volume.service.addEventListener( VolumeEvent.MUTED, mutedHandler );
    Volume.service.addEventListener( VolumeEvent.UNMUTED, unmutedHandler );
    - + \ No newline at end of file diff --git a/docs/volume/streams/index.html b/docs/volume/streams/index.html index 24699a23f92..2c1776912f3 100644 --- a/docs/volume/streams/index.html +++ b/docs/volume/streams/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ the default music stream.

    Android gives access to all the streams in the VolumeStream class.

    On iOS there is only the music stream available to developers.

    if (Volume.isSupported)
    {
    var volume:Number = Volume.service.getVolume( VolumeStream.STREAM_MUSIC );
    }

    On Android you can set the default stream that will get controlled by the volume keys. The default is generally the ring volume so you can call this function to change the default to be one of the other supported streams.

    if (Volume.isSupported)
    {
    Volume.service.setVolumeControlStream( VolumeStream.STREAM_MUSIC );
    }
    - + \ No newline at end of file diff --git a/docs/volume/volume-control/index.html b/docs/volume/volume-control/index.html index 689e4280d22..7121dff7506 100644 --- a/docs/volume/volume-control/index.html +++ b/docs/volume/volume-control/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ Volume events are dispatched when either the user changes the volume using the native controls, or by pressing the volume buttons, or when you change the volume using the setVolume function.

    if (Volume.isSupported)
    {
    Volume.service.addEventListener( VolumeEvent.CHANGED, volumeChangedHandler );
    Volume.service.register();
    }

    function volumeChangedHandler( event:VolumeEvent ):void
    {
    trace( event.type + "::" +event.volume + " [" + event.stream + "]" );
    }

    You should make sure you call unregister when you are done listening to cleanup and remove any volume listening functions.

    - + \ No newline at end of file diff --git a/docs/webp/add-the-extension/index.html b/docs/webp/add-the-extension/index.html index 1384e3169eb..4d3a4fd61c2 100644 --- a/docs/webp/add-the-extension/index.html +++ b/docs/webp/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    AIR SDK

    This ANE currently requires at least AIR 33+. This is required in order to support versions of Android > 9.0 (API 28). We always recommend using the most recent build with AIR especially for mobile development where the OS changes rapidly.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.WebP

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.WebP.ane # WebP extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (WebP.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/webp/changelog/index.html b/docs/webp/changelog/index.html index 030e74017ac..37181d15772 100644 --- a/docs/webp/changelog/index.html +++ b/docs/webp/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v4.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag

    2022.02.14 [v4.0.9]

    Update docs to use apm

    2021.10.12 [v4.0.8]

    Add air package
    Remove ios minimum version flag

    2020.03.19 [v4.0.005]

    Android X migration (resolves #6)

    2019.08.15 [v3.0.002]

    Android 64bit support (resolves #5)
    Updated to webp v1.0.2
    Updated minimumiOS version to 9.0

    2019.03.26 [v2.1.032]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode
    Removed application keys

    2017.07.10 [v2.0.027]

    Updated for compatibility with new Core library (for Notifications/PushNotifications fix)

    2016.12.30 [v2.0.026]

    New documentation

    2016.09.07 [v2.0.024]

    Added the WebPLoader for asynchronous loading of WebP files (resolves #2)

    2015.06.16

    Removed debug code from AS lib
    iOS: Updated to latest common lib
    Android: Windows: Fix for bug in AIR packager resulting in missing resources
    Android: x86 Support

    2015.05.12

    Release verion

    2015.02.03

    Added check for .debug suffix in application id

    2014.12.22

    iOS: Included arm64 support (resolves #1)
    Android: Corrected application id check when doesn't contain air prefix

    2014.12.08

    Corrected missing EventDispatcher functions from base class
    iOS: Implemented autoreleasepools for all C function calls

    2014.12.02

    New application based key check, removing server checks
    - + \ No newline at end of file diff --git a/docs/webp/index.html b/docs/webp/index.html index a71b12468a8..fed64758881 100644 --- a/docs/webp/index.html +++ b/docs/webp/index.html @@ -13,7 +13,7 @@ - + @@ -27,7 +27,7 @@ compared to PNG when lossy compression is acceptable for the red/green/blue color channels.

    For more on information on the format see the following page on Google Developers: WebP

    Features

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    Quick Example:

    if (WebP.isSupported)
    {
    var bd:BitmapData = WebP.service.loadWebPBitmapData( path );
    }

    More information here:

    com.distriqt.WebP

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/webp/load-a-webp-file/index.html b/docs/webp/load-a-webp-file/index.html index cbef73dc70c..aefe76b9658 100644 --- a/docs/webp/load-a-webp-file/index.html +++ b/docs/webp/load-a-webp-file/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Load a WebP File

    If you have access to a WebP file you can use the loadWebPBitmapData function to read the file and use the BitmapData to display the image.

    // Find a file packaged with the application
    var file:File = File.applicationDirectory.resolvePath( "image.webp" );
    var bd:BitmapData = WebP.service.loadWebPBitmapData( path.url );
    - + \ No newline at end of file diff --git a/docs/webp/parse-webp-data/index.html b/docs/webp/parse-webp-data/index.html index 80d6c1e1c8b..3808a8a1f52 100644 --- a/docs/webp/parse-webp-data/index.html +++ b/docs/webp/parse-webp-data/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Parse WebP Data

    If you load data from a URL or other data source you can use the parseWebP function to decode the WebP data into useable bitmap pixel data.

    // For this example load data from a file into a ByteArray
    var file:File = File.applicationDirectory.resolvePath( "image.webp" );
    var fs:FileStream = new FileStream();
    fs.open( file, FileMode.READ );
    var data:ByteArray = new ByteArray();
    fs.readBytes( data, 0, fs.bytesAvailable );
    fs.close();

    var decodedData:ByteArray = new ByteArray();

    //
    // Use WebP to decode the data
    var success:Boolean = WebP.service.parseWebP( data, decodedData );

    if (success)
    {
    var rect:Rectangle = new Rectangle( 0, 0, WebP.service.width, WebP.service.height );
    var bd:BitmapData = new BitmapData( WebP.service.width, WebP.service.height, true );
    bd.setPixels( rect, decodedData );

    // Use the BitmapData as required
    }
    - + \ No newline at end of file diff --git a/docs/webp/webploader/index.html b/docs/webp/webploader/index.html index b4cb7885951..4a4424107c6 100644 --- a/docs/webp/webploader/index.html +++ b/docs/webp/webploader/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ This gives you access to a WebPLoader instance which you can then attach event listeners for

    To start the load simply call load on the loader and wait for one of the above events to fire.

    Example

    var loader:WebPLoader = WebP.service.createLoader();

    loader.addEventListener( WebPLoaderEvent.COMPLETE, loader_completeHandler );
    loader.addEventListener( WebPErrorEvent.ERROR, loader_errorHandler );

    var success:Boolean = loader.load( file.url );

    trace( "loader.load( " + file.url + " ) = " + success );

    Then in your event handlers:

    private function loader_completeHandler( event:WebPLoaderEvent ):void
    {
    trace( "loader complete" );
    displayBitmapData( event.data.convertToBitmapData() );

    var loader:WebPLoader = WebPLoader(event.currentTarget);
    loader.removeEventListener( WebPLoaderEvent.COMPLETE, loader_completeHandler );
    loader.removeEventListener( WebPErrorEvent.ERROR, loader_errorHandler );
    loader.dispose();
    }

    private function loader_errorHandler( event:WebPErrorEvent ):void
    {
    trace( "loader error ::["+event.code+"] "+event.error );

    var loader:WebPLoader = WebPLoader(event.currentTarget);
    loader.removeEventListener( WebPLoaderEvent.COMPLETE, loader_completeHandler );
    loader.removeEventListener( WebPErrorEvent.ERROR, loader_errorHandler );
    loader.dispose();
    }
    - + \ No newline at end of file diff --git a/docs/windowsstore/add-the-extension/index.html b/docs/windowsstore/add-the-extension/index.html index e331bfe48f4..7156d4687fa 100644 --- a/docs/windowsstore/add-the-extension/index.html +++ b/docs/windowsstore/add-the-extension/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    AIR SDK

    This ANE currently requires at least AIR 33+. This is required in order to support versions of Android > 9.0 (API 28). We always recommend using the most recent build with AIR especially for mobile development where the OS changes rapidly.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.WindowsStore

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.WindowsStore.ane # WindowsStore extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Windows

    .Net Framework

    This extension requires v4.6 or higher of the .Net framework. This should come preinstalled on any Windows 10 or higher machine so if you are targetting those you should not have to do anything. If however you are targetting older versions of Windows you must ensure .Net v4.6 or higher is installed either manually or as part of an installer.

    C++ Redistributable

    The native code has a dependency on the Visual C++ 2017 Redistributable package. This package contains code that is required to run code developed using C++ in Visual Studio and is very common amongst Windows applications.

    There are two ways to ensure this is available to your application:

    • Create an installer that includes the redistributable installer;
    • Package the required DLL files from the redistributable with your application;

    The first is the suggested method. Installing the redistributable via an installer allows it to be put into the windows update process, allowing bug fixes and security updates to be handled automatically.

    The second method is only advised if you need a complete standalone application, where you don't (or cannot) use an installation process. This requires you to package DLLs from the redistributable with your application.

    NOTE: If you have previously packaged DLLs from the windows_dll directory, these are no longer required. We have packaged these internally to the extension and access them directly from there. You should remove these DLLs from your application.

    i.e. the DLLs in the image below are no longer required:

    Creating an Installer

    There are many methods to create application installers and many tutorials available. We suggest you find a method suitable to your environment and application and utilise the tutorials online.

    Some methods include:

    Tutorials:

    You need to include the x86 c++ 2017 redistributable in the installer, there are many examples and documentation online to achieve this.

    Packaging DLLs

    Packaging the DLLs into your application involves copying the DLLs specified below into your application root and including in your application package.

    The best option is to install Visual Studio 2017 and locate the Program Files[ (x86)]\Microsoft Visual Studio\2017\edition\VC\Redist\MSVC\lib-version folder, eg: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Redist\MSVC\14.16.27012\x86\Microsoft.VC141.CRT

    Alternatively, download and install the x86 redistributable from the Microsoft website. This should install the DLLs into C:\Windows\System32 folder.

    Open the folder and copy the following DLLs to your application:

    • msvcp140.dll
    • vcruntime140.dll

    If you are having issues locating these files, feel free to contact us for help.

    You should ensure you are allowed to package these files as per the Microsoft Software License terms but generally these are safe to redistribute subject to the license terms. More information here: Redistributing Visual C++ Files

    You should get legal advice if you are unsure.

    - + \ No newline at end of file diff --git a/docs/windowsstore/changelog/index.html b/docs/windowsstore/changelog/index.html index 815a9d5d6d7..f92613e5f1e 100644 --- a/docs/windowsstore/changelog/index.html +++ b/docs/windowsstore/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.02.01 [v1.4.0]

    feat(airpackage): update to support latest Core extension with major Android / iOS updates

    2022.02.14 [v1.3.2]

    Update docs to use apm

    2021.11.22 [v1.3.1]

    Fix for bug with Purchase.toString function (resolves #7)

    2021.10.12 [v1.3.0]

    Add air package
    Add windows 64 bit support

    2020.03.20 [v1.2.115]

    Android X compatibility (resolves #2)
    Updated to latest dependencies

    2020.01.17 [v1.1.109]

    Updated docs

    2020.01.17 [v1.1.109]

    Added checks for early initialisation of window handle (resolves #1)
    Internally packaged DLLs to simplify integration
    Updated documentation with C++ redist requirements / alternatives
    Addition of subscription related information

    2019.11.01 [v1.0.080]

    Updated docs

    2019.11.01 [v1.0.080]

    Updated docs

    2019.11.01 [v1.0.080]

    Updated docs

    2019.11.01 [v1.0.080]

    Initial release
    - + \ No newline at end of file diff --git a/docs/windowsstore/consumables/index.html b/docs/windowsstore/consumables/index.html index 7602a8bca58..6ab237cabab 100644 --- a/docs/windowsstore/consumables/index.html +++ b/docs/windowsstore/consumables/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Consumables

    Consumable products can be consumed by the user and purchased again.

    Once purchased the user will receive an "Already Purchased" message until you inform the store of the consumption of the purchase.

    For example, if your user can buy in game currency, then once the currency has been spent in your game you need to inform the store that the user can purchase currency again.

    To consume a purchase call the consumePurchase function and pass the product id you wish to consume.

    WindowsStore.service.consumePurchase( "XXXXXXXXXXXX" );

    The consumePurchase call will dispatch one of the following events:

    • WindowsStoreEvent.CONSUME_PURCHASE_COMPLETE: Dispatched when the consume purchase completed successfully;
    • WindowsStoreEvent.CONSUME_PURCHASE_ERROR: Dispatched when an error occurred.
    WindowsStore.service.addEventListener( WindowsStoreEvent.CONSUME_PURCHASE_COMPLETE, consumePurchase_completeHandler );
    WindowsStore.service.addEventListener( WindowsStoreEvent.CONSUME_PURCHASE_ERROR, consumePurchase_errorHandler );

    WindowsStore.service.consumePurchase( "XXXXXXXXXXXX" );


    function consumePurchase_completeHandler( event:WindowsStoreEvent ):void
    {
    // purchase was consumed - your user can now purchase the product again
    }

    function consumePurchase_errorHandler( event:WindowsStoreEvent ):void
    {
    trace( "ERROR: ["+event.errorCode + "] :"+event.errorMessage );
    }
    - + \ No newline at end of file diff --git a/docs/windowsstore/index.html b/docs/windowsstore/index.html index 006971d0098..861f784fd86 100644 --- a/docs/windowsstore/index.html +++ b/docs/windowsstore/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    WindowsStore

    The WindowsStore extension gives your UWP packaged AIR application the ability to make purchases of application add-ons through the Windows Store.

    Features

    • Query product information from the Windows Store
    • Retrieve user's purchases
    • Make a purchase of a product

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    - + \ No newline at end of file diff --git a/docs/windowsstore/initialise-the-extension/index.html b/docs/windowsstore/initialise-the-extension/index.html index df7ca19e0bf..d24d428ce75 100644 --- a/docs/windowsstore/initialise-the-extension/index.html +++ b/docs/windowsstore/initialise-the-extension/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Initialise the Extension

    You should perform this once in your application by calling the setup() method. This initialises the extension and internally sets up the native extension implementation.

    Note you should always check whether the extension is supported before making calls. This allows you to react to whether the functionality is available on the device.

    try
    {
    if (WindowsStore.isSupported)
    {
    WindowsStore.service.setup();

    // Functionality here

    }
    }
    catch (e:Error)
    {
    trace( e );
    }
    - + \ No newline at end of file diff --git a/docs/windowsstore/make-purchase/index.html b/docs/windowsstore/make-purchase/index.html index f1dcff9ea93..c27c1220dd6 100644 --- a/docs/windowsstore/make-purchase/index.html +++ b/docs/windowsstore/make-purchase/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Make Purchase

    In order to purchase a product you will construct a PurchaseRequest object and pass it to the makePurchase function.

    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( "XXXXXXXXXXXX" );

    WindowsStore.service.makePurchase( request );

    The makePurchase call will dispatch one of the following events:

    • PurchaseEvent.MAKE_PURCHASE_COMPLETE: Dispatched when the purchase completed successfully;
    • PurchaseEvent.MAKE_PURCHASE_ERROR: Dispatched when an error occurred.
    var request:PurchaseRequest = new PurchaseRequest()
    .setProductId( "XXXXXXXXXXXX" );

    WindowsStore.service.addEventListener( PurchaseEvent.MAKE_PURCHASE_COMPLETE, makePurchase_completeHandler );
    WindowsStore.service.addEventListener( PurchaseEvent.MAKE_PURCHASE_ERROR, makePurchase_errorHandler );

    WindowsStore.service.makePurchase( request );

    function makePurchase_completeHandler( event:PurchaseEvent ):void
    {
    // event.purchases should contain one Purchase object with the product info
    for each (var purchase:Purchase in event.purchases)
    {
    trace( purchase.toString() );
    }
    }

    function makePurchase_errorHandler( event:PurchaseEvent ):void
    {
    trace( "ERROR: ["+event.errorCode + "] :"+event.errorMessage );
    }

    The PurchaseEvent.MAKE_PURCHASE_COMPLETE event should contain one Purchase object with the product information of the product purchased. At this point there will be no extended information so you can query getPurchases if you need additional information on store managed purchases.

    - + \ No newline at end of file diff --git a/docs/windowsstore/products/index.html b/docs/windowsstore/products/index.html index ed20d9b6c00..5e155f512c2 100644 --- a/docs/windowsstore/products/index.html +++ b/docs/windowsstore/products/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Products

    Query product information

    To query information about your known products you call the getProducts function with an array of store product ids.

    WindowsStore.service.getProducts( [ "XXXXXXXXXXXX", "XXXXXXXXXXXX" ] );

    These id's will be set by the store and available in the dashboard when you create your products.

    This call will result in one of two possible events:

    • ProductEvent.GET_PRODUCTS_COMPLETE: Dispatched if product information retrieval was successful;
    • ProductEvent.GET_PRODUCTS_ERROR: Dispatched if an error occurred.
    WindowsStore.service.addEventListener( ProductEvent.GET_PRODUCTS_COMPLETE, getProducts_completeHandler );
    WindowsStore.service.addEventListener( ProductEvent.GET_PRODUCTS_ERROR, getProducts_errorHandler );

    WindowsStore.service.getProducts( [ "XXXXXXXXXXXX", "XXXXXXXXXXXX" ] );


    function getProducts_completeHandler( event:ProductEvent ):void
    {
    for each (var product:Product in event.products)
    {
    trace( "product: [" + product.id + "]:: "+product.priceString+" "+product.description );
    }
    }

    function getProducts_errorHandler( event:ProductEvent ):void
    {
    trace( "ERROR: ["+event.errorCode+"] : "+ event.errorMessage );
    }

    Product Types

    There are several types of product as indicated by the type property of the Product object. It will be one of the following:

    • Consumable: A store managed consumable product that can be purchased, used, and purchased again. The store keeps a track of the user's balance for these types of products.
    • UnmanagedConsumable: A developer managed consumable product that can be purchased, used, and purchased again. The store does not track the user's total for these types.
    • Durable: A product that persists for the lifetime specified in the dashboard. Subscription products will have this type.

    Skus

    Each product may have multiple product skus associated with it, indicating price changes or variations of the product.

    Importantly this SKU information contains whether the product is a subscription and billing information about the subscription (eg billing period and whether it has a trial period).

    This information is contained in the skus array of a Product:

    for each (var sku:ProductSku in product.skus)
    {

    if (sku.isSubscription)
    {
    // Product is a subscription
    if (sku.subscriptionInfo.hasTrialPeriod)
    {
    // Subscription has a trial
    }
    }

    }

    In our tests it seems there are sometimes an odd "non-subscription" SKU created for a subscription product. We aren't sure as to the source or reason for this SKU, so always ensure you check all the SKUs for the subscription information.

    - + \ No newline at end of file diff --git a/docs/windowsstore/purchases/index.html b/docs/windowsstore/purchases/index.html index 05bc4e0a7c3..c6b1d35a8da 100644 --- a/docs/windowsstore/purchases/index.html +++ b/docs/windowsstore/purchases/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Purchases

    Get Purchases

    In order to retrieve a list of purchases the user has made use the getPurchases function. This call will query the store for any purchases the user has made and any valid license information.

    This call will return a complete or an error event:

    • PurchaseEvent.GET_PURCHASES_COMPLETE: Dispatched when successfully retrieve the purchases, the event will contain an array of Purchase objects each describing a user's purchase;
    • PurchaseEvent.GET_PURCHASES_ERROR: Dispatched when an error occurred.

    For example:

    WindowsStore.service.addEventListener( PurchaseEvent.GET_PURCHASES_COMPLETE, getPurchases_completeHandler );
    WindowsStore.service.addEventListener( PurchaseEvent.GET_PURCHASES_ERROR, getPurchases_errorHandler );

    WindowsStore.service.getPurchases();


    function getPurchases_completeHandler( event:PurchaseEvent ):void
    {
    for each (var purchase:Purchase in event.purchases)
    {
    trace( purchase.toString() );
    }
    }

    function getPurchases_errorHandler( event:PurchaseEvent ):void
    {
    trace("ERROR: [" + event.errorCode + "] "+event.errorMessage );
    }

    This appears to only return store managed purchases, such as durable products. Developer managed consumables may not be returned through the getPurchases call.

    Subscriptions

    Purchases that relate to a subscription product will have additional information in the Purchase object.

    The active flag will indicate whether the subscription is currently active. This should always be true for purchases queried through the getPurchases() functionality as this only retrieves active purchases.

    Additionally for subscription purchases there will be a valid expirationDate property on the object, indicating when the current billing period for the subscription will end.

    - + \ No newline at end of file diff --git a/docs/windowsstore/windows-desktop-app-converter/index.html b/docs/windowsstore/windows-desktop-app-converter/index.html index eb72d673be0..0adce834cbe 100644 --- a/docs/windowsstore/windows-desktop-app-converter/index.html +++ b/docs/windowsstore/windows-desktop-app-converter/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ along with the AIR runtime, ANEs, DLLs, and all the other files packaged with your application.

    This is the simplest method as you can use the output from the AIR SDK directly to create your Windows Store application (appx).

    It is important that you only have files related to your project in the directory with your executable as anything in this directory will be copied to the final application.

    Here we use the Installer parameter to point to the root folder of your packaged app files. This is the folder containing the AIRApp.exe file generated by AIR.

    DesktopAppConverter.exe 
    -Installer [PATH\TO\YOUR\AIR\OUTPUT]
    -AppExecutable AIRApp.exe
    -Destination [PATH\TO\OUTPUT]
    -PackageName "[Package/Identity/Name]"
    -PackageDisplayName "[DISPLAYNAME]"
    -Publisher "CN=[Package/Identity/Publisher]"
    -PackagePublisherDisplayName "[Package/Properties/PublisherDisplayName]"
    -AppDisplayName "[DISPLAYNAME]"
    -Version [VERSION]
    -MakeAppx
    -Sign
    -Verbose

    Your app has a unique identity, assigned by the Store. In order to submit your application you will need to add some parameters setting information about your application from the developer dashboard. Identity details that can be found in the App identity section of your application in the developer dashboard. This information is required to correctly package your application for store submission however can be dummy values for local testing:

    For example:

    DesktopAppConverter.exe 
    -Installer C:\work\windowsstore\example\starling\out\TestWindowsStore
    -AppExecutable TestWindowsStore.exe
    -Destination C:\work\windowsstore\example\starling\final
    -PackageName "distriqt.airnativeextensions"
    -Publisher "CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    -PackagePublisherDisplayName "distriqt"
    -PackageDisplayName "airnativeextensions"
    -AppDisplayName "airnativeextensions"
    -Version 1.0.0.0
    -MakeAppx
    -Sign
    -Verbose

    Method 2

    Using an Installer for your AIR application

    You may already have an installer for your AIR application and wish to use this to create your Windows Store application (appx).

    The output from your AIR application will be a directory, containing your swf, the exe, along with the AIR runtime, any ANEs, and all the other files packaged with your application.

    You will then need to create an installer from this directory using one of the many windows installer tools, eg:

    Tutorials:

    You now convert your AIR application installer to a Windows Store application (appx). It is important that you only have files related to your project in the directory with your installer (i.e. C:\dac\installer below) as anything in this directory will be copied to the virtual file system to run the conversion.

    To run the conversion, use the following command, replacing the [] items to match your setup:

    DesktopAppConverter.exe 
    -Installer [PATH\TO\YOUR\AIR\INSTALLER]
    -InstallerArguments "[INSTALLEROPTIONS]"
    -Destination [PATH\TO\OUTPUT]
    -PackageName "[Package/Identity/Name]"
    -Publisher "CN=[Package/Identity/Publisher]"
    -PackagePublisherDisplayName "[Package/Properties/PublisherDisplayName]"
    -PackageDisplayName "[DISPLAYNAME]"
    -AppDisplayName "[DISPLAYNAME]"
    -Version [VERSION]
    -MakeAppx
    -Sign
    -Verbose

    Your app has a unique identity, assigned by the Store. In order to submit your application you will need to add some parameters setting information about your application from the developer dashboard. Identity details that can be found in the App identity section of your application in the developer dashboard. This information is required to correctly package your application for store submission however can be dummy values for local testing:

    For example with our msi generated using Wix:

    DesktopAppConverter.exe 
    -Installer C:\dac\installer\TestDistriqt.msi
    -InstallerArguments "/quiet"
    -Destination C:\dac\final
    -PackageName "distriqt.airnativeextensions"
    -Publisher "CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    -PackagePublisherDisplayName "distriqt"
    -PackageDisplayName "airnativeextensions"
    -AppDisplayName "airnativeextensions"
    -Version 1.0.0.0
    -MakeAppx
    -Sign
    -Verbose

    Step 3 Testing the conversion

    You can now install the appx application on your local machine. In order to do this you will need to install the certificate that was used to sign the application. This will called auto-generated.cer and be located in the output path alongside your appx application file.

    To install the certificate:

    - Double click cer file
    - Select "Install Certificate..."
    - Select "Local Machine"
    - Select "Place all certificates in the following store"
    - "Browse"
    - "Trusted Root Certification Authorities"

    You can now install the application by double clicking the appx to launch the installer. This will install your application locally and have access to the UWP platform.

    Step 4 Submission

    You should now be able to use the appx file to submit to the store.

    You must have acquired permission to submit Desktop Bridge applications before this step. If you haven't you will see the following error:

    Package acceptance validation error: Your developer account doesn't have permission to submit apps converted with the Desktop Bridge at this time. https://aka.ms/desktopbridgeforwindowsstore

    External Docs

    Acknowledgements

    This documentation is based on the e-pity case study

    - + \ No newline at end of file diff --git a/docs/windowsstore/windows-developer-account/index.html b/docs/windowsstore/windows-developer-account/index.html index e37be382867..7cd38b37d4f 100644 --- a/docs/windowsstore/windows-developer-account/index.html +++ b/docs/windowsstore/windows-developer-account/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Windows-Developer Account

    The first step is to sign up for a Windows Developer account. You must have an account in order to submit applications to the Windows Store.

    Apply for permission

    In addition to your account you need to get permission for your developer account to submit apps converted with the Desktop Bridge. The Desktop Bridge or Desktop App Converter allows you to convert your desktop AIR application to a UWP application which can be distributed through the Windows Store.

    You apply for permission by using the form at the following url:

    https://aka.ms/desktopbridgeforwindowsstore

    This process can take some time. We suggest having a working version of your AIR application ready to submit to the store in order to aid this process. It doesn't have to exhibit complete functionality but needs to be at a reasonable stage that they can approve the application quickly. Be prepared to work with the Microsoft representative to get your application approved for using the Desktop Bridge.

    - + \ No newline at end of file diff --git a/docs/windowsstore/windows-overview/index.html b/docs/windowsstore/windows-overview/index.html index 70a1bf4235b..91eb45a43ad 100644 --- a/docs/windowsstore/windows-overview/index.html +++ b/docs/windowsstore/windows-overview/index.html @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ some specific conversions to convert the AIR package into an UWP app which can be submitted to the Store.

    This process involves several steps, creating an installer from your AIR captive runtime bundle and using the Desktop App Converter to convert for the store.

    @rewb0rn has written a great walkthrough on the entire process with much more detail than we have currently in this guide:

    - + \ No newline at end of file diff --git a/docs/ziputils/add-the-extension/index.html b/docs/ziputils/add-the-extension/index.html index 61d183ef153..86cf469daaf 100644 --- a/docs/ziputils/add-the-extension/index.html +++ b/docs/ziputils/add-the-extension/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Add the Extension

    The simplest way to install and manage your AIR native extensions and libraries is to use the AIR Package Manager (apm). We highly recommend using apm, as it will handle downloading all required dependencies and manage your application descriptor (Android manifest additions, iOS info additions etc).

    However you can choose to install it manually, as you would have done in the past.

    Install

    info

    Note: All of the commands below should be run in a terminal / command prompt in the root directory of your application, generally the level above your source directory.

    If you don't have an APM project setup, expand the guide below to setup an APM project before installing the extension.

    Setup APM

    Install APM

    If you haven't installed apm follow the install guide on airsdk.dev.

    Setup an APM project

    You will need an APM project for your application.

    There are many ways to do this and for more options see the APM documentation. Here we will just initialise a new empty project:

    apm init

    Check your github token

    We use github to secure our extensions so you must have created a github personal access token and configured apm to use it.

    To do this create a token using this guide from github and then set it in your apm config using:

    apm config set github_token ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX

    If you don't do this correctly you may find the install will fail.

    Install the extension

    Install the extension by running:

    apm install com.distriqt.ZipUtils

    This will download and install the extension, required assets, and all dependencies.

    Once complete apm will have created something like the following file structure:

    .
    |____ ane
    | |____ com.distriqt.ZipUtils.ane # ZipUtils extension
    | |____ [dependencies]
    |____ apm_packages # cache directory - ignore
    |____ project.apm # apm project file
    • Add the ane directory to your IDE. See the tutorials located here on adding an extension to your IDE.
    info

    We suggest you use the locations directly in your builds rather than copying the files elsewhere. The reason for this is if you ever go to update the extensions using apm that these updates will be pulled into your build automatically.

    Application Descriptor

    Updating your application descriptor will insert the required extensionID's and generate the manifest and info additions for your application.

    You update your application descriptor by running:

    apm generate app-descriptor src/MyApp-app.xml

    Change the path (src/MyApp-app.xml) to point to your application descriptor.

    caution

    This will modify your application descriptor replacing the manifest additions and info additions with the ones generated from apm.

    You should backup your application descriptor before running this command to ensure you don't lose any information.

    If you need to insert custom data into these sections see the guides for Android and iOS

    Checking for Support

    You can use the isSupported flag to determine if this extension is supported on the current platform and device.

    This allows you to react to whether the functionality is available on the device and provide an alternative solution if not.

    if (ZipUtils.isSupported)
    {
    // Functionality here
    }
    - + \ No newline at end of file diff --git a/docs/ziputils/changelog/index.html b/docs/ziputils/changelog/index.html index d9d526f8a48..003aa9b8938 100644 --- a/docs/ziputils/changelog/index.html +++ b/docs/ziputils/changelog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    changelog

    2023.01.27 [v3.1.0]

    feat(ios): Xcode 14 update, remove bitcode and add no-objc-msgsend-selector-stubs compiler flag 

    2022.02.14 [v3.0.32]

    Update docs to use apm

    2021.10.12 [v3.0.31]

    Add air package

    2020.03.20 [v3.0.029]

    Android X migration (resolves #11)

    2020.03.04 [v2.1.027]

    Added the ability to create a zip file from a folder of files

    2019.08.15 [v2.0.002]

    Android 64bit update (resolves #9)
    Updated minimum iOS version to 9.0

    2019.03.12 [v1.4.009]

    Updated minimum iOS version to 8.0
    Embedded iOS bitcode
    Removed application keys

    2016.12.30 [v1.3.002]

    Updated SDKs + new documentation

    2016.06.19

    Default: Changed overwrite operation to overlay files rather than delete (resolves #6)

    2016.04.12

    Updated iOS Simulator build (#4)

    2016.04.06

    Added progress events (resolves #4)

    2016.02.05

    Fix for default lib on Windows not correctly creating directories (resolves #2)

    2016.02.02

    Added zip filename information to ZipUtilsEvent (resolves #3)

    2016.02.01

    iOS: Fix for unzip not correctly being run in a separate thread (resolves #1)

    2015.09.17

    First release
    - + \ No newline at end of file diff --git a/docs/ziputils/index.html b/docs/ziputils/index.html index 8cc9e96528c..22b65da62c8 100644 --- a/docs/ziputils/index.html +++ b/docs/ziputils/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@
    Skip to main content

    Zip Utils

    The ZipUtils extension provides access to high performance zip utilities.

    ZipUtils gives you access to zip functionality with native performance.

    • Unzip a zip file to device storage
    • Compress a folder or file into a zip file

    We provide complete guides to get you up and running with the extension quickly and easily.

    As with all our extensions you get access to a year of support and updates as we are continually improving and updating the extensions for OS updates and feature requests.

    Features

    • Compress a folder or file into a zip file;
    • Unzip a zip file to device storage;
    • Default implementation using as3commons zip library;
    • Single API interface - your code works across iOS and Android with no modifications;
    • Sample project code and ASDocs reference

    Documentation

    The documentation site forms the best source of detailed documentation for the extension along with the asdocs.

    More information here:

    com.distriqt.ZipUtils

    License

    You can purchase a license for using this extension:

    airnativeextensions.com

    distriqt retains all copyright.

    - + \ No newline at end of file diff --git a/docs/ziputils/unzipping-a-file/index.html b/docs/ziputils/unzipping-a-file/index.html index f63ee47f641..0ae0938d414 100644 --- a/docs/ziputils/unzipping-a-file/index.html +++ b/docs/ziputils/unzipping-a-file/index.html @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ with the files from the zip file, otherwise files that already exist will be ignored and not extracted from the zip.

    The extension will dispatch one of two events to determine the result of the unzip:

    There is also a progress event that will be dispatched at intervals. Depending on the operating system but generally after each file is extracted.

    Example

    ZipUtils.service.addEventListener( ZipUtilsEvent.UNZIP_COMPLETE, zipUtils_completeHandler );
    ZipUtils.service.addEventListener( ZipUtilsEvent.UNZIP_ERROR, zipUtils_errorHandler );

    var zipFile:File = File.applicationStorageDirectory.resolvePath( "example.zip" );
    var destinationDir:File = ...; // Output location

    ZipUtils.service.unzip( zipFile.nativePath, destination.nativePath, true );

    Event handlers:

    private function zipUtils_completeHandler( event:ZipUtilsEvent ):void
    {
    trace( "unzip complete" );
    }

    private function zipUtils_errorHandler( event:ZipUtilsEvent ):void
    {
    trace( "unzip error" );
    }
    - + \ No newline at end of file diff --git a/docs/ziputils/zipping/index.html b/docs/ziputils/zipping/index.html index 5cb17c858e5..5391d56b038 100644 --- a/docs/ziputils/zipping/index.html +++ b/docs/ziputils/zipping/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    Zipping

    To compress an entire directory into a zip file you use the zip() function.

    The extension will dispatch one of two events to determine the result of the unzip:

    • ZipUtilsEvent.ZIP_COMPLETE: Indicates the zip is complete and the zip file is available
    • ZipUtilsEvent.ZIP_ERROR: Indicates there was an error zipping the file

    There is also a progress event that will be dispatched at intervals. Depending on the operating system but generally after each file is added to the zip.

    Example

    ZipUtils.service.addEventListener( ZipUtilsEvent.ZIP_COMPLETE, zipCompleteHandler );
    ZipUtils.service.addEventListener( ZipUtilsEvent.ZIP_ERROR, zipErrorHandler );
    ZipUtils.service.addEventListener( ZipUtilsProgressEvent.PROGRESS, progressHandler );

    var zipFile:File = File.applicationStorageDirectory.resolvePath( "example.zip" );
    var sourceDir:File = ...; // Some directory to zip

    ZipUtils.service.zip(
    zipFile.nativePath,
    sourceDir.nativePath
    );

    Event handlers:

    private function zipCompleteHandler( event:ZipUtilsEvent ):void
    {
    trace( "zip complete" );
    }

    private function zipErrorHandler( event:ZipUtilsEvent ):void
    {
    trace( "zip error" );
    }

    private function progressHandler( event:ZipUtilsProgressEvent ):void
    {
    trace( "progress: " + event.bytesLoaded +" / "+event.bytesTotal );
    }
    - + \ No newline at end of file diff --git a/index.html b/index.html index 4897141506c..161cc69509a 100644 --- a/index.html +++ b/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Native Extensions

    Create world class applications quickly and confidently with Native Extensions for Adobe AIR, Unity and Haxe.


    This site contains the best source of documentation for the extensions, including detailed guides on adding the extensions, tutorials on getting started, and API documentation on the usage of the extensions in your applications.

    Looking for our extensions?

    Our extensions are provided through a variety of sources all of which are linked through our main site. With over 60 extensions available, we are the largest provider of native extensions for AIR developers and one of the only providers of Universal Extensions.

    Our mobile solutions allow developers to fast-forward development and focus on building great games and apps.

    Simple & Powerful

    Simple & Powerful

    Single cross-platform APIs for iOS, tvOS, Android, Windows and macOS make integration and development fast and painless for developers.

    Support & Updates

    Support & Updates

    We continually update our extensions to stay up to date with platform and SDK updates so you can focus on building apps and games without worrying about compatibilty.

    Cost Effective

    Cost Effective

    Our extensions are the most cost effective on the market. We don't limit developers with restrictive licenses - no profit shares, no limitations on your apps.

    - + \ No newline at end of file diff --git a/news/2020-11/index.html b/news/2020-11/index.html index c2126ccf517..415596b4f96 100644 --- a/news/2020-11/index.html +++ b/news/2020-11/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    November 2020

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    Facebook

    The Facebook extension has had a complete rewrite and API redesign over the past few months. The extension was becoming cumbersome to update, mainly due to the continuous changes that Facebook makes to their SDK. These often breaking updates meant that the ANE had a lot of legacy references and deprecated features still included.

    With a complete rewrite the extension is now broken into the Facebook SDK components and much simpler to integrate the essential components such as analytics and login. Additionally you only need to include the functionality you require which will reduce the additional size of your application due to the Facebook SDK.

    Check out the updated documentation here.

    Migrating user’s have a look at the migration documentation here.

    Flash EOL

    You may be worried about the Flash End of Life which will be occurring next year. We wrote a bit of a break down of what’s going to happen earlier this month here. If you need any help managing or converting existing web applications please feel free to get in touch with us. We have helped many clients this year prepare for the removal of the player from browsers.

    Native Web View

    A range of fixes and small features have been added to the extension this month, most notably better handling of target="_blank" links which you can now control how the webview handles these types of links. They can be opened directly in the system browser, opened in the same webview or blocked so your application can handle them directly.

    We have added in some view controls allowing you to scroll/page through the loaded page through code. Additionally we have given you more control over the Windows implementation allowing direct passing of options to the Cef browser.

    Check out the Native Web View extension here.

    Adverts

    The Adverts ANE has been updated with support for AdMob Open Bidding. This feature changes the initialisation process slightly to allow feedback on the available mediation providers supported by your integration and through open bidding.

    Adverts.service.addEventListener( AdvertsEvent.INITIALISED, initialisedHandler );

    Adverts.service.initialise();

    function initialisedHandler( event:AdvertsEvent ):void
    {
    for each (var adapterStatus:AdapterStatus in e.adapterStatus)
    {
    trace( "adapter: " + adapterStatus.name + " : " + adapterStatus.state + " [" + adapterStatus.latency + "] - " + adapterStatus.description );
    }
    }
    // com.distriqt.Adverts

    Additionally this month we have updated the available AdMob mediators to the latest supported SDKs.

    Check out the extension here.

    ironSource

    We have finally added some of the core functionality from the ironSource SDK that you have been asking for. This includes Banner Ads and the Offerwall. Both features are now available through our ANE along with the latest version of the ironSource SDK!

    The ironSource ANE is free and available to all AIR developers!

    Get it here


    Stay safe!

    - + \ No newline at end of file diff --git a/news/2020-12/index.html b/news/2020-12/index.html index 05a8cb68460..08f39e4f111 100644 --- a/news/2020-12/index.html +++ b/news/2020-12/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    December 2020

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    Firebase

    With the latest version of AIR (33.1.1.345) we have now been able to update the iOS version of Crashlytics to support Firebase Crashlytics (from the older Fabric version). Anyone using the older version may have noticed that you are no longer getting crash reports in the console. This is due to Firebase deprecating the older SDK and no longer supporting reports from it.

    Adverts

    Huawei Ads Kit is now available as part of the Adverts ANE alongside the Google AdMob implementation. The API remains the same so you can easily support Huawei devices in your AIR application with minimal configuration changes.

    Get the Adverts ANE here.

    Application

    We have added some additional utilities to the Application ANE around controlling the keyboard. You can now use the extension to manually show the keyboard.

    - + \ No newline at end of file diff --git a/news/2021-01/index.html b/news/2021-01/index.html index 229087c3b70..72aaab6a4aa 100644 --- a/news/2021-01/index.html +++ b/news/2021-01/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    January 2021

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    Facebook Gaming Services

    We have released a new extension in the Facebook group that provides access to the Gaming Services SDK. The Gaming Services SDK allows applications configured as games through Facebook to access certain game specific functionality, including a simpler login process and additional native dialogs.

    This new extension includes access to the Game Request dialog and Friend Finder dialog.

    This release also includes an update of the Facebook SDK to version 8.2.0.

    Available now in the Facebook API extension.

    Firebase

    A large update for Google services and Firebase has been released this month with the SDK going to versions:

    • Android v26.3.0
    • iOS v7.4.0

    This update contains some API changes in Remote Config and some changes to the manifest additions for certain services. Check out the migration guide.

    Additionally if you are using FCM or OneSignal (with the Push Notifications extension) there have been some changes to the Firebase components there. See the push notifications migration guide.

    Application Rater

    The application rater ANE has been updated to include support for Huawei App Gallery, so your application will correctly open the App Gallery store if specified.

    Adverts

    AdMob SDK has been updated to the latest release including:

    • Android v19.6.0
    • iOS v7.69.0

    This update includes some changes to the dependencies and manifest additions so make sure you check out the migration guide.

    IronSource

    IronSource SDK has been updated to the latest v7.1.0 release including all the mediation adapters. This contains support for the latest iOS 14 changes.

    Game Services

    Updated to the latest Google Play Games to v21.0.0. As part of this release Google’s deprecated multiplayer functionality and has been completely disabled. So we have removed all this functionality from the extension and correctly report it not being supported on Google Play Games.

    Turn based multiplayer is still available in Game Center.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-02/index.html b/news/2021-02/index.html index 9b0658905cd..fd52bc1b161 100644 --- a/news/2021-02/index.html +++ b/news/2021-02/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    February 2021

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    InAppBilling

    InAppBilling now includes support for the Samsung Galaxy Store In-App Purchases. This builds upon the existing support for Google Play, Apple, Amazon and Huawei, so you have access to all the majors stores through one API.

    We have added support for Apple AppStore purchases from macOS. So you can now support macOS, iOS and tvOS all through this extension.

    Additionally Google Play Billing has been updated to the latest release (v3.0.2).

    Get the best in-app monetisation extension here.

    Push Notifications

    OneSignal has been updated to the latest SDK which brings a raft of improvements to the platform under the hood. This update includes the following versions:

    • iOS v3.1.1
    • Android v4.1.0

    Check out the extension here.

    Facebook

    Facebook has released a major update to their SDK (v9.0.0). You probably have received a message along the following lines:

    Your current SDK is deprecated and will no longer be supported by Facebook. We will continue to allow API calls from your SDK for a transition period of two years. Starting January 20, 2023 we will fail all calls from deprecated SDKs. We encourage you to upgrade to v9.0 as soon as possible to avoid disruption to your application and to access all the benefits of our newest SDK.

    This is a change as all previous versions of the SDK will stop working after the specified date.

    As part of this update Facebook has introduced the concept of a “limited login” that allows developers to signal that a login is limited in terms of tracking users.

    Unity Plugins

    Several of our extensions are now available as Unity Plugins in the Unity Asset Store. This makes them extremely easy to integrate into your Unity project.

    Currently we have the following plugins available:

    Check them out in the store. If there are any you think would be useful to your Unity project please let us know.

    Note: If you already have a subscription to the AIR version of these plugins then you have access to the Unity Plugin for free.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-03/index.html b/news/2021-03/index.html index 521007876ca..13c349c6e85 100644 --- a/news/2021-03/index.html +++ b/news/2021-03/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    March 2021

    · 3 min read

    Game Services, Vibration (Haptics), Scanning and more Unity.

    Hope everyone is keeping safe out there. This month has seen some much requested updates to several of our extensions, including the Game Center access point, scanning within a viewport and haptic engine (vibrations) functionality.

    Additionally we have released some more Unity plugins available now for our subscribers and in the Unity Asset Store.

    We are also working towards some Flutter extensions and investing time in the platform. If anyone has any requests we are currently looking for a good initial project to expand our services, please feel free to get in touch.

    Game Services

    We have updated the Game Services extension to support the latest features in Game Center on iOS. This includes the "Access Point" functionality that shows a common Game Center UI element in your application.

    Additionally we have added functionality to open generic UI elements directly allowing you to easily direct your users to the game service "dashboard".

    Get the best game services extension here.

    Vibration

    Our Vibration native extension now supports the iOS Haptic Engine which you can use to engage users physically, with tactile feedback that gets attention and reinforces actions! Control the sharpness and intensity of vibrations to give highly engaging physical feedback from your application.

    Check out the extension here.

    Scanner

    You can now use the Scanner extension to scan bitmap data for symbols (barcodes, qrcodes etc) directly or to position a camera preview for scanning within your AIR UI.

    Additionally we have improved the camera compatibility on Android resolving some issues with less common device configurations.

    The Scanner extension is available here.

    Unity Plugins

    We have released two more plugins to the Unity Asset Store this month:

    Check them out in the store. If there are any you think would be useful to your Unity project please let us know.

    Note: If you already have a subscription to the AIR version of these plugins then you have access to the Unity Plugin for free.

    AIR Package Manager

    If you have any interest in supporting the development of APM we are still looking for sponsorship to be able to get this project started.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-04/index.html b/news/2021-04/index.html index c90261f3eda..14baa871dc0 100644 --- a/news/2021-04/index.html +++ b/news/2021-04/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    April 2021

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    In Development

    We have a major update for Adverts in testing to bring the latest build of AdMob to you. This update involves some refactoring and updates to reflect the latest SDK changes. So you may want to plan some development time to integrate the next release.

    We are going through and removing duplicate iOS/tvOS linker options in our extensions and specifying common ones in the Core extension. This should help with developers who encounter the "input line too long" error message when packaging for iOS on Windows. Additionally we are removing any minimum iOS version specifications in the extensions, this will now be up to the developer to specify. These changes will be rolled out with other updates for the extensions.

    AIR Package Manager

    This month we have invested some time in the development of APM. We believe this is such an important missing component of the AIR eco-system that we are pushing ahead with the development.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    Initially we have just been scoping the components and planning the development but will be moving into development in May.

    Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    Game Controller

    We have had a few requests around improving the game controller support in AIR on mobile.

    This will allow us to create a new "Game Controller" ANE to provide advanced features and events from controllers on iOS and Android. Features would include: connected / disconnected events, input buttons / axis events, and retrieving controller information such as such as type / provider / vendor.

    You can read the discussion here

    Sponsoring helps us to fund the initial development work for a new extension and is the simplest way we can continue further development of the AIR platform. We have had a large contribution to the development but are still looking for additional funding to get this extension started. If you are interested you can sponsor the development on github.

    Unity Plugins

    We have released another plugin to the Unity Asset Store this month:

    Scan NFC tags and launch your application to engage users physically with the real world!

    Check all our Unity plugins out in the store. If there are any you think would be useful to your Unity project please let us know.

    Note: If you already have a subscription to the AIR version of these plugins then you have access to the Unity Plugin for free.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-05/index.html b/news/2021-05/index.html index baeb2e24f2f..3e6abcaa79e 100644 --- a/news/2021-05/index.html +++ b/news/2021-05/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    May 2021

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    AIR Package Manager

    Work on APM has been progressing and we now have a prototype command line utility written in AS3 alongside the latest AIR SDK which is working really well. We currently have the framework completed and the ability to create a project definition file (apm init) and edit configuration params (apm project config set).

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    I'll be looking into options for the repository next month and implementing the search and install functionality.

    We have also been in discussions to allow this tool to download and update the AIR SDK which will make keeping on top of the latest SDK changes easier.

    Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    Adverts

    AdMob SDK has been updated to the latest release including:

    • Android v20.0.0
    • iOS v8.4.0

    As mentioned last month, this update is a major restructure to some of the processes

    App Open Ads have been added with this release.

    This update includes some breaking changes to the API including:

    • removal of the "left application" event;
    • move to a common FullScreenContentEvent for interstitial and rewarded video events;
    • and change of ad request configuration options to a global RequestConfiguration interface;

    Make sure you check out the migration guide.

    Google Play Services

    Updated to latest Google Play Services and Firebase SDKs including the dependency libraries for AdMob v20.0.0.

    We have also added the Provider Installer functionality. This allows your application to update the device's security provider ensuring your application is running on a device that has the latest updates to protect against known exploits.

    Lastly there have been some updates for Games, correcting an issue with a dependency.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-06/index.html b/news/2021-06/index.html index a0265749e2d..2b8f0f40d26 100644 --- a/news/2021-06/index.html +++ b/news/2021-06/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    June 2021

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    AIR Package Manager

    We are very excited to be working on APM. We have made a lot of progress in the past month and are hoping for some alpha releases in July.

    We have the base package repository working now and APM will search, view, and install packages along with initial conflict management.

    We have also added in some preliminary tools to download and install the AIR SDK, including the ability to list available sdks and their release notes.

    If you are at all interested in testing out the client we suggest you watch the repository for some releases in July. And make sure to check out the wiki to see the direction we are taking with the tool.

    If you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    Adverts

    If you use the Adverts extension for AdMob you may have had some issues with passing review due to the inclusion of the legacy consent SDK. This has now been removed so make sure you update to the new User Messaging Platform for your consent with AdMob before your next release.

    See the documentation on the User Messaging Platform.

    Please note, if you are using Huawei Ads you will still use the consent SDK API in our extension.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-07/index.html b/news/2021-07/index.html index 5a6bbb0837c..db73665ab13 100644 --- a/news/2021-07/index.html +++ b/news/2021-07/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    July 2021

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    AIR Package Manager

    We are very excited to release the first beta of APM! It's available now in the repository for Windows and macOS (though it should work anywhere that supports adl).

    We have made a lot of progress in the past month and are really happy with the progress. The project setup and configuration has been completed to allow you to create a project definition and configuration parameters.

    We also have a complete package repository setup and APM will search, view, install, uninstall and update packages along with our initial take on conflict management.

    You can also start creating your own packages, though currently you'll need to reach out to us to be given permission to publish to the repository. We are really excited that the latest release of starling is already available in the repository!

    AIR SDK

    The preliminary tools to list, view and install the AIR SDK are available, which includes the ability to see the change log and readme associated with each release.

    $ apm airsdk view 33.1.1.554 
    ✓ Retrieved AIR SDK information : 33.1.1.554
    AIR SDK v33.1.1.554
    Release Date: 2021-07-13
    Release Notes:
    [Github-516] : Updating guava library used by ActionScript compiler to remove illegal reflection
    [Github-835] : Signing on mac using codesign without using Sun Java private classes
    [Github-894] : Updating avmplus to allow coercion between Vectors of related types
    [Github-934] : Supporting ANEs with multiple packages containing the same resource folder
    [Github-934] : Ensuring Android TV apps can be built with the right manifest for a bundle
    [Github-934] : Adding multidex library support into Android App Bundle generation
    [Github-936] : Updating code-signing and dependencies in iOSBin
    [Github-938] : Ensuring Android SDK detection copes with spurious folders under build-tools
    [Github-939] : Fixing crash with Android external storage directory call
    [Github-947] : Ensuring developers can use -resdir for Android App Bundles
    [Github-951] : Fixing Gradle issue when using non-ascii characters in an app 'name' field
    [Github-957] : Ensure we ignore manually added multidex-*.jar files
    [Github-957] : Support vector drawables support library for Android SDK below 21
    [Github-958] : Cleaning up temp folders created during AAB packaging
    [Github-968] : Fixing Android-x64 platform string for ANEs

    Get Involved

    This tool is for the community, so we really want your feedback. It is opensource and publicly available now. If you are at all interested in testing out the client we are looking for any and all feedback! Check out the wiki for installation details.

    If you have any thoughts and feel you could help please reach out, either by sponsoring or contributing directly through the repository.

    Dialog

    New iOS 14 date / time dialogs are now available in the Dialog extension. This feature brings the Android and iOS implementations closer in functionality with the new iOS style for date selection closely matching the existing Android calendar selection style.

    Additionally we added some new features to text input dialogs, including "auto-capitalisation" and "auto-correct" options.

    Check out the extension here.

    IronSource

    Our free IronSource extension has gotten another update to support the latest ironSource SDK, including updates for all the available mediation network extensions.

    This update brings the extension to version:

    • Android v7.1.7
    • iOS v7.1.7

    We also added some API functions to handle the new requirements for using Facebook Audience Network on iOS.

    If you are using this extension, we welcome any support in keeping it updated via sponsoring us on github.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-08/index.html b/news/2021-08/index.html index 3375053ec78..b812a1f9a47 100644 --- a/news/2021-08/index.html +++ b/news/2021-08/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    August 2021

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    AIR SDK Configuration

    While working with apm we have been investigating options to make development using the AIR SDK easier and have come across some concerns around configuration of the SDK.

    Basically I'm concerned about the configuration options for a project being placed inside the SDK. I believe this is a really bad practice and that we need to have a more consistent approach for configuration settings. I have raised our concerns on the AIR discussion forum and I think it's important as a community that we push a direction for Harman here, before they take the SDK down a bad path.

    Please take the time to have a read and let Harman know about where you think the configuration options should be placed.

    You can find the discussion here: https://github.com/airsdk/Adobe-Runtime-Support/discussions/1112

    AIR Package Manager

    We have rolled out several more iterations of the apm tool and we have made amazing progress around generation of the application descriptor, most importantly the automatic generation of the manifest additions for Android.

    I seriously cannot emphasise enough how much this will change integrating packages in AIR applications.

    It makes adding a new package (extension) to your application as easy as:

    apm install com.distriqt.CameraUI
    apm generate app-descriptor

    And your application descriptor will automatically have the manifest additions and extension id's inserted, not only for the CameraUI extension but all the dependencies!

    This is still a work in progress (eg we haven't completed iOS merging yet) and we are working hard on getting all our extensions available as packages, but we would really welcome any feedback.

    For example, a basic app descriptor after running the above:

    <application xmlns="http://ns.adobe.com/air/application/33.1">
    <id>com.my.app</id>
    <versionNumber>1.0.0</versionNumber>
    <filename>MyApplication</filename>
    <name>My Application</name>
    <initialWindow>
    <content>[]</content>
    <visible>true</visible>
    <fullScreen>false</fullScreen>
    <autoOrients>false</autoOrients>
    <renderMode>direct</renderMode>
    </initialWindow>
    <android>
    <manifestAdditions><![CDATA[<manifest android:installLocation="auto" >
    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:hardwareAccelerated="true">
    <provider android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer" android:authorities="air.com.my.app.lifecycle-process" android:exported="false" android:multiprocess="true"/>
    <provider android:name="androidx.startup.InitializationProvider" android:authorities="air.com.my.app.androidx-startup" android:exported="false"/>
    <provider android:name="com.distriqt.extension.cameraui.content.FileProvider" android:authorities="air.com.my.app.camerauifileprovider" android:exported="false" android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/distriqt_cameraui_paths"/>
    </provider>
    <activity android:name="com.distriqt.extension.cameraui.permissions.AuthorisationActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    </application>
    </manifest>
    ]]></manifestAdditions>
    <containsVideo>true</containsVideo>
    </android>
    <extensions>
    <extensionID>androidx.core</extensionID>
    <extensionID>com.distriqt.CameraUI</extensionID>
    <extensionID>com.distriqt.Core</extensionID>
    </extensions>
    </application>

    Currently we have the following air packages available:

    • All the Google Play Services
    • All the androidx and android dependencies
    • Square libs
    • Camera UI
    • Flurry
    • Adverts (including mediators)

    Get Involved

    This tool is for the community, so we really want your feedback. It is opensource and publicly available now. If you are at all interested in testing out the client we are looking for any and all feedback! Check out the wiki for installation details.

    If you have any thoughts and feel you could help please reach out, either by sponsoring or contributing directly through the repository.

    Adverts

    The Adverts extension has been updated to the latest SDK releases and we have added support for the new "Rewarded Interstitials" ad type.

    The extension now contains AdMob version 20.2.0 on Android and version 8.9.0 on iOS. Additionally the UMP SDK has been updated to version 2.0.0.

    Excitingly this extension has been released as an airpackage. This means you can use apm to install and generate the manifest additions for you.

    apm install com.distriqt.Adverts
    apm project config set adMobAndroidApplicationId XXXXXXX
    apm project config set adMobIOSApplicationId YYYYYYY

    Android 30

    Now that the AIR SDK supports Android 30 we have been updating all our extensions to support this latest iteration of the Android platform. There are several major changes around opening and querying other installed packages and changes around file access that have affected some of our extensions, such as the CameraUI.

    If you run into any issues, please let us know and we will make sure any issues are addressed promptly!


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-09/index.html b/news/2021-09/index.html index e2e0d99642b..7594a28c46e 100644 --- a/news/2021-09/index.html +++ b/news/2021-09/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    September 2021

    · 3 min read
    Michael

    airsdk.dev, extension updates, and more on APM

    I am hope you aren't sick of hearing about APM, we are really excited for this tool so may feel like that is all we are talking about recently. We have been pushing out all our extensions as air packages and have over 70 packages in the repository now and are hoping to complete all our extensions early in October.

    AIR SDK Developer Site

    Now that a lot of the existing documentation has been marked as deprecated by Adobe we believe it is very important for a modern site to be available for AIR. AIR is in no way "deprecated" so it's important that this information is available.

    To this end we have been working with Harman on putting together a modern documentation site for the AIR SDK. We hope this can become the new home of AIR. Check out the site here:

    https://airsdk.dev

    The site is still needs a lot of content. We have been working on porting as much as we can but if you have any interest in contributing check out the site in github. All the documentation is in simple markdown so it should be easy for anyone to contribute.

    APM

    It is great to see some involvement from the community with APM, but we really would love to have more feedback on the tool. AIR can be used in a myriad of ways so it's important to us to get as much feedback as possible while designing this tool.

    We have started a series of guides to help you get started using the tool and to highlight the advantages of using it. The first one was published last week and we plan to have another guide each week during October.

    Over the last month we have fixed a range of bugs and are getting a final list of features together for a release candidate.

    Facebook

    The Facebook extensions have all had SDK updates to:

    • Android v9.1.1
    • iOS v9.3.0

    Additionally there have been some fixes around gaming services callbacks and some additions for iOS 14 (ad tracking features).

    IronSource

    The ironSource extension has been updated to v7.1.10 of the ironSource SDK and all associated mediation adapters have also been updated to their latest releases.

    InAppBilling

    There have been some functional fixes for the Amazon implementation correcting the consume process and some of the function return values.

    If you are using Amazon In-App Purchases we suggest updating to the latest release.

    Push Notifications

    The push extension has had the OneSignal SDK support updated to:

    • Android v4.6.0
    • iOS v3.7.0

    There were also some minor bug fixes around error events that were incorrectly being dispatched.

    Firebase

    The Firebase extensions have been updated with some fixes around the handling of large data responses particularly in the Firestore and Realtime Database extensions where large JSON responses were being handled inefficiently. You should see a decent performance increase if you are dealing with large data queries.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-10/index.html b/news/2021-10/index.html index b59a51b2a9e..2435bee61dc 100644 --- a/news/2021-10/index.html +++ b/news/2021-10/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    October 2021

    · 3 min read
    Michael

    AIR Packages, APM v1.0.0

    Again this month has seen a large focus on APM. Porting our extensions over to the new AIR package has taking up much of this month.

    Notable ANE updates include:

    AIR Packages

    This month we have gone through all our extensions and created AIR Packages for each of them. You can now install all of our extensions using APM!

    This has been another very large piece of work and has taken a lot of this month to produce these packages so we are very excited that this has been completed. All updates to our extensions in the future will be made available through packages (and we will continue to publish to the repositories).

    Over the coming months we will be changing all our documentation to reflect using APM as the preferred installation method.

    APM

    This month has seen a lot of polish and cleanup of the APM tool and we have finally released v1.0.0. We believe this tool is ready for usage and encourage you to start using it to manage your AIR projects.

    Continuing with our series of guides we published two more this last month:

    Hopefully these guides will encourage you to start using apm.


    Image Scripts

    You may be aware that in the past we made a script available to help create your application icons and launch images. This was created out of the need to start providing an asset catalogue version of icons for iOS (Assets.car).

    The script takes an icon image and a launch image and generates a series of icons, the Assets.car and a LaunchScreen.storyboard for your application. You can simply drop these files into your application and have all the correctly sized icons for your application. We have recently updated this script as it was failing in some circumstances. The new version is available in github now:

    https://github.com/distriqt/AIR-ImageScripts


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2021-11/index.html b/news/2021-11/index.html index 283007c8bfc..1fed1f77792 100644 --- a/news/2021-11/index.html +++ b/news/2021-11/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    November 2021

    · 2 min read
    Michael

    Camera Roll Extended, and APM

    It has been a quieter month here at distriqt. The team took some time early in the month to have a much needed break especially before the end of year rush.

    Work continues on the AIR package manager. If you are using the tool we’d really love to hear any feedback you may have. We are currently looking to v2.0 and what features the community will need in this utility going forward.

    Camera Roll Extended

    We have updated the iOS implementation to utilise the latest iOS image selection view controller. iOS 14 introduced a new set of UI views to make image selection much more consistent across iOS and you now have access to this new view in AIR. Our custom implementation will still be used on iOS 13 and earlier.

    Additionally there have been some changes for image loading in iOS 15, particularly around image resizing and scaling. These updates have been integrated into the latest release of the extension.

    AIR Package Manager

    After we saw the first release of APM last month we have just been doing a series of minor updates and polish around the utility. We will be shortly releasing several new features in the tool including:

    • build configurations to easily switch between development & production;
    • more control over the project configuration including package parameter walk-throughs where we guide you through setting the parameters for a package;
    • install performance improvements and introduction of a “lock” file to ensure consistent configuration across build environments;

    All this will be coming in v1.1 in the first week in December.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-01/index.html b/news/2022-01/index.html index 62172430fef..638e854b650 100644 --- a/news/2022-01/index.html +++ b/news/2022-01/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    January 2022

    · 3 min read
    Michael

    Android 31, Google Play Services, AndroidX, APM Documentation

    The start to the year has been a disrupted one, with our team having to deal with several COVID cases in our families. Fortunately we weren’t too badly affected and are all back on deck now. But this has meant our schedule for native extension work has been delayed.

    Android 12, Google Play Services and AndroidX

    We have been working on a major update for Google Play Services and AndroidX libraries to bring them up to date with the latest releases and simultaneously updating all our extensions with Android 12 (API 31) support. This was due to be released during January but will now be released towards the end of February.

    You should currently be targeting API 30 as a maximum while we work through these latest changes.

    <uses-sdk android:targetSdkVersion="30" />

    Android 12 support mainly involves an update to the manifest additions to support the new requirement that all services/activities etc require an exported flag. Previously these have had default values applied by the SDK but with Android 12 Google now requires us to define a specific value for this flag. If you are using APM then this should be a simple update call, otherwise we are updating all our documentation with the new manifest additions which you can apply when you move to targeting API 31.

    Updating Google Play Services always is a big job for us. They reach into many of our extensions and all of them must be updated simultaneously to ensure they all work together. We have completed the Google Play Services updates internally and are working through our extensions to ensure compatibility and updating documentation as required.

    Now is a great time to consider moving to apm before these updates arrive, in order to simplify your update process! Get started with apm here.

    Documentation

    We have been updating our documentation on using our extensions to show how to use apm to install them. Check out the following example:

    https://docs.airnativeextensions.com/docs/application/add-the-extension

    Using apm is the simplest method to use native extensions and swc libraries so we are encouraging all our users to start using this tool. Particularly with major updates like Google Play Services and the Android 12 manifest addition changes coming this month, using apm will make the update painless.

    We are always looking for ways to improve so would love any feedback on the new documentation, and if anything would help in your migration to apm.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-02/index.html b/news/2022-02/index.html index ad964ae5fa3..9f9b818bded 100644 --- a/news/2022-02/index.html +++ b/news/2022-02/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    February 2022

    · 2 min read
    Michael

    Android 12 (API 31), apm documentation

    This month we were aiming to have released a complete upgrade of all our extensions to be compatible with Android 12 (API 31) including Google Play Services and the AndroidX libraries. Along with this comes a major update to all our documentation to use the AIR Package Manager (apm)!

    Unfortunately due to the unexpected weather event in Australia, distriqt's offices have been affected by extreme flooding and power outages and we have been delayed with this release.

    We are currently aiming to start release of these updates over the next fortnight, as soon as our office is operating again.

    Android 31

    Android 12 (API 31) contains a range of security and performance changes that have affected nearly all our extensions. Previously many Android developers relied on default values for certain things from the Android OS but we are now being required to explicitly state these values. 

    With these updates come a series of changes to the manifest additions, particularly around the addition of android:exported attributes. We highly recommend using apm to make the migration as easy as possible, apm will handle the update of the manifest automatically for you.

    Over the coming weeks we will progressively be releasing the updates to our extensions and air packages to support Android 12. In addition, all our documentation is being updated to show how to use apm to install and configure the extensions. There's never been a better time to start using the AIR package manager. 

    If you are interested in some detailed information on the changes in Android 12 have a look here.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-03/index.html b/news/2022-03/index.html index 76b0a05ea29..da8337bccab 100644 --- a/news/2022-03/index.html +++ b/news/2022-03/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    March 2022

    · 2 min read
    Michael

    Android 12 (API 31)

    What a hectic month! But the great news is that all of our extensions have been updated to the latest Google Play Services and androidx libraries including all the air packages for use in apm!

    Android 31

    All of our changes for the latest Android release are now available.

    There are a lot of changes related to new dependencies and manifest additions. We know this is can be a daunting migration when dealing with major changes to the manifest so make sure you check the documentation in detail for the extensions you are using.

    The most common issue we are seeing is the change in the androidx.core lib that has changed the main lifecycle listener that a lot of libraries use. If you previously had the androidx.lifecycle.ProcessLifecycleOwnerInitializer provider in your manifest it needs to be removed and replaced with the following androidx.startup.InitializationProvider:

    <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="APPLICATION_PACKAGE.androidx-startup"
    android:exported="false" >
    <meta-data
    android:name="androidx.lifecycle.ProcessLifecycleInitializer"
    android:value="androidx.startup" />
    </provider>

    Note if you already have an instance of this provider you need to merge the meta-data into the one instance.

    apm

    We have been working few a couple of small teething issues with apm but it’s great to see so many of you using this new tool to simplify your AIR development and integration of extensions. Please let us know if you run into any issues and we will keep improving this tool over time.

    For anyone having issues with caching, it can be useful to delete the apm_packages directory and run apm install again. This will use the version of the extensions identified in your lock file and download the latest versions again.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-06/index.html b/news/2022-06/index.html index c3e994602d1..6b7baa9567a 100644 --- a/news/2022-06/index.html +++ b/news/2022-06/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    June 2022

    · 4 min read
    Michael

    Extension Updates

    This month has been full of update releases. We have been working on a series of updates for some of our major extensions over the past few months and many of them have been released this month.

    • Facebook
    • Firebase
    • PushNotifications (FCM + OneSignal)
    • Adverts
    • IronSource

    Facebook

    This latest update brings an update to the iOS SDK. Recent AIR SDK updates has meant we can finally bring a much more recent version of the Facebook SDK to AIR developers on iOS which should be a welcome update to anyone who uses Facebook social or login features in their application. The API has remained unchanged but internally it will be using a much more recent version of the SDK.

    Additionally some critical fixes were released including fixing an issue with session not persisting across launches on iOS.


    Firebase

    This update brings an update to the iOS SDK. Similar to the Facebook extension, recent updates to the AIR SDK has meant we can now bring a more recent version of the Firebase SDK to iOS developers. This should bring a range of bug fixes and improvements to the underlying Firebase SDK.

    Firebase Storage extension now provides the ability to list files that you have stored in your storage bucket:

    var ref:StorageReference = FirebaseStorage.service.getReference();
    ref.addEventListener( StorageReferenceListEvent.SUCCESS, listSuccessHandler );
    ref.addEventListener( StorageReferenceListEvent.ERROR, listErrorHandler );
    ref.listAll();

    function listSuccessHandler( event:StorageReferenceListEvent ):void
    {
    // Contains a list of "items" - each represents a storage item
    for each (var item:String in event.items)
    {
    var ref:StorageReference
    = FirebaseStorage.service.getReference( item );
    }
    }

    Push Notifications

    The FCM implementation has been brought inline with the latest Firebase extension bringing a recent version iOS and Android Firebase SDK. This should bring some bug fixes and improvements from the underlying Firebase Messaging SDK:

    • Android v23.0.0
    • iOS v8.15.0

    The OneSignal SDK has also been updated and now includes v4.7.3 on Android.

    This update also brings a range of bug fixes.


    Adverts

    Version 13.6 brings version 9+ of the AdMob iOS SDK which includes some significant changes to the SDK. Most of the changes have been handled internal to the extension however there is one important piece of information that you must be aware of:

    Ads stop serving on iOS 10

    The minimum iOS version the Google Mobile Ads SDK version 9.0.0 supports is iOS 11.

    Upgrading to Google Mobile Ads SDK version 9.0.0 will not break your app on iOS 10 devices, however, no ads will be served on those devices.

    Additionally mediator adapters have been updated to bring inline with this version of the AdMob SDKs.

    Life Time Value (LTV)

    This update also includes the preview implementation of the life time value events.

    Most of the adverts will now dispatch a PaidEvent.PAID event with information on the revenue obtained for presenting an advert. By implementing this event handler, you can use the data to calculate a user's life time value, or forward the data downstream to other relevant systems.

    More information in the Life Time Value section.


    IronSource

    The free ironSource extension has been updated to the latest version of the ironSource SDK:

    • Android v7.2.2
    • iOS v7.2.2.1

    Additionally all supported mediation adapters have been updated to be inline with this release of the ironSource SDK.

    Sponsoring

    If you use this extension regularly we do ask that you consider sponsoring the development to allow us to continue updating the extension. You can find details on sponsoring the extension here.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-07/index.html b/news/2022-07/index.html index 5126fe53531..f505a53ad40 100644 --- a/news/2022-07/index.html +++ b/news/2022-07/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    July 2022

    · 3 min read
    Michael

    SWC Build issues, InApp Billing changes, iOS Simulator

    There is a lot of work in progress at the moment with some major changes coming up later this year, particularly for Android and the Google Play store.

    SWC Compilation

    AIR 33.1.1.889 was released with some changes to the way SWC's are packaged and this affected our ANEs. Several of our updates went out with this version and caused issues in certain circumstances with errors such as circular references or duplicate definitions.

    We found that SWC's that relied on other SWC's also had runtime errors such as "ABC data is corrupt, attempt to read out of bounds".

    We have updated the extensions we believe were affected but if you find any issues like this with any of our ANEs please let us know as we likely will need to rebuild them with a different AIR SDK.


    InAppBilling

    info

    Reminder: Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer. Learn more.

    Currently our extension uses version 3 of the billing library and we are in progress of a major update to bring it to the latest version 5 (released in May). This is requiring some restructuring of the calls (particularly as some of the previously synchronous calls are now asynchronous) which we are endeavouring to manage internally to the extension however we may have to introduce some API changes here.

    We are hoping to have this ready for developers by the end of August, well before the November deadline for all applications.


    AIR Package Manager

    We are working through further development on the apm tool at the moment, mainly around cleaning up some of the processes. If you have been using the tool and have any suggestions as to improvements we would love to hear from you on the discussion forum.


    iOS Simulator

    We have recently let the iOS simulator implementations of some of our extensions slip and this month we have updated all our build processes to ensure the iOS simulator builds are kept inline with the main build.

    Previously this was difficult when dynamic frameworks were involved but we have devised a new system to handle these and correctly include them in both the repository and the airpackage's for all our extensions.

    These updates will roll out with the next release of our extensions, starting with the Facebook extensions in July. If there are any that you are concerned about let us know and we will get them updated immediately.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-08/index.html b/news/2022-08/index.html index 8bccb0fc76c..a6799b6e753 100644 --- a/news/2022-08/index.html +++ b/news/2022-08/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    August 2022

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    APM

    The AIR Package Manager has had an update this month with v1.2.0 being released. This update includes some better management of the data files keeping the order of the contents in the files more consistent which should improve their usage in version control systems such as git.

    Additionally several updates and fixes were included, particularly around an issue with a failed update where the installed extensions were lost.

    See the full release notes here.

    If you are looking to get started with APM we recommend checking out the migration guide which goes through a case study of an application we migrated to APM.


    InAppBilling

    Our InAppBilling extension is in final testing before the release containing the update to the latest version of the Google billing library (version 5).

    We have had to make some changes to the API particularly around subscriptions and discounts. If you have the capability to help us test, we are looking for people to test the beta release before we finalise the API and changes to the extension. Just drop a note on this issue and we'll get you the latest beta version as soon as it's available: https://github.com/distriqt/ANE-InAppBilling/issues/482


    IronSource

    Our IronSource extension has been updated to the latest release including all mediators.

    There were some issues with the previous release with some of the mediators conflicting with the version of playservices in use. This has now been resolved and all the mediators should be working again.


    DynamicIcon

    Our DynamicIcon extension has been updated to use icons from the ios asset catalogue with the latest xcode 13 tools. You now can package your alternative icons in your asset catalogue along with your main application icon and launch images.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-09/index.html b/news/2022-09/index.html index 2ec1a7aeb7e..daf903934f2 100644 --- a/news/2022-09/index.html +++ b/news/2022-09/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    September 2022

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.


    Application

    The Application extension has had some small updates to improve the cutout information available. On Android you now can not only retrieve information on the safe area (i.e. the area of the stage that is safe to draw content) but also get "bounding box" information for each cutout/notch on the current device. This allows you to better render content outside the safe area but still avoid the cutouts.

    This update also brings some additional integration for use with alarms on Android 12+ where more restrictions have been placed on exact alarms.


    InAppBilling

    Our InAppBilling extension has been released to beta and is in final testing before the release. This major update contains the update to the latest version of the Google billing library (version 5).

    If you have the capability to help us test, we are looking for people to test the beta release before we finalise the API and changes to the extension. You will find a link to the latest beta build in this issue: https://github.com/distriqt/ANE-InAppBilling/issues/482


    Adverts

    We added some additional information for reward video and interstitials, allowing you to retrieve the reward amount for an advert before displaying it. This allows you to correctly show the reward amount for a video when presenting it to a user.

    Some minor bug fixes including:

    • native ads which were reappearing after having been removed from the view
    • some minor fixes for the documentation

    Permissions

    The Permissions extension has been updated to include the ability to request permissions for managing all files on a storage device. This is a separate authorisation process from the normal android runtime permissions and requires a specific activity to be integrated. This is now available in the latest release.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-10/index.html b/news/2022-10/index.html index cd4042cdf6f..dac275f4a9e 100644 --- a/news/2022-10/index.html +++ b/news/2022-10/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    October 2022

    · 2 min read
    Michael

    Play Billing v5 release, IronSource updates

    This last month has seen the release of the major update for our InAppBilling extension to support the latest version of the play billing library from Google for the Play Store. This update brings a major change to the way subscriptions are handled and is critical for any updates or new applications released to the Play Store.

    Additionally we have released several updates and new mediation networks for the ironSource extension.


    InAppBilling

    Many of you will have received the following notice from Google over the previous months:

    Reminder

    Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer.

    We are excited to announce that version 14 of the InAppBilling extension brings v5.0.0 of the Billing library so you will be able to update your applications to satisfy the latest Play Store requirements.

    Version 5.0.0 brings some major changes to subscriptions and some breaking API changes that you will need to update your application to manage. These changes are mainly focused around subscriptions and generally developers who only use consumable / non-consumable products shouldn't see any change in functionality.

    For more information on migrating, follow the migration guide.


    IronSource

    Last month we released updates to the mediation adapters for several of the networks, including:

    • AdColony
    • AppLovin
    • AdMob
    • UnityAds

    We have also added several new mediation adapters for the following networks:

    • Vungle
    • Digital Turbine (Fyber)

    Additionally some minor functionality updates to the IronSource extension included the addition of the setMetaData function to help set meta data for mediation networks and other non-specific configuration values.

    info

    Please note this extension is provided for free, so if you do find it useful, please consider sponsoring the developers involved.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022-11/index.html b/news/2022-11/index.html index ab84ac137ee..44cbf25c7b1 100644 --- a/news/2022-11/index.html +++ b/news/2022-11/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    November 2022

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.


    AIR SDK Manager

    This is an application you can use to manage your AIR SDK installations and update them as new releases are available. Additionally you can configure your SDKs without having to manually edit the adt.cfg file and import a license file. This looks to be a great tool and we are excited to see how you find it.

    From Andrew at Harman

    We would value any feedback/comments/ideas of how to improve this. The idea is that you can update SDK versions where there are bug fixes but then each feature-based update can be managed separately. It also allows you to sort out the configuration settings, hopefully meaning you no longer need to bother with adt.cfg files.

    We'd be particularly interested in hearing how you would integrate tools like this into your development process and how tools like apm could work alongside the AIR SDK Manager and your IDEs.

    For more information and giving feedback, see the github discussion.


    Adverts

    We have released a few small fixes for the Adverts extension. Firstly resolving a long standing issue with server side verification options on rewarded video ads. Secondly some documentation updates reflecting Google's change from "funding choices" to "privacy and messaging" for the UMP consent dialog setup. And lastly an update to support the new App Set library, removing the usage of the advertising identifier which can cause privacy concerns particularly in family and children targetted applications.

    If you wish to continue using UMP and the advertising identifiers we suggest you also install the IDFA extension. This will give you access to the tools to request access to the advertising identifier and install the required dependencies for it's usage.


    Application Rater

    The Application Rater extension has been updated to support the Samsung Galaxy store.

    This means that it will now detect if your application was installed through the Galaxy store and correctly redirect to the rating page in the Galaxy store from the rating dialog.

    You can find more information about handling ratings from the different stores in the documentation on Handling Stores


    InAppBilling

    With the latest update to v5 of the play billing library, several developers have noted that certain devices don't return a product list from the getProducts() call and instead get an error dispatched.

    The latest Play Billing library requires an updated version of the Play Store application to be installed on the device so you may want to check for the availability of this before attempting to retrieve the product list.

    We have added some helpers to check for the availability of the billing service on the current device and included a response that indicates if the store application needs updating:

    InAppBilling.service.checkAvailability(
    function ( availability:String ):void
    {
    if (availability == InAppBillingAvailability.STORE_UPGRADE_REQUIRED)
    {
    // An update for the play store application is required
    }
    }
    );

    For more information on the availabilty see the documentation.


    Permissions

    The permissions extension has had some updates to improve the openDirectory() functionality including returning an event on result (PermissionsEvent.OPEN_DOCUMENT) which contains the path the user selected.

    You can read more about this change here.


    NativeWebView

    Lastly this month we released a small update for the Native WebView extension to fix some focus issues on Android with the web view and the latest AIR SDK releases.

    If you are using this extension it is worth updating just to ensure the focus works correctly particularly if you are managing key inputs and overriding the back key operation on Android.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2022/06/15/accessing-gdpr-settings/index.html b/news/2022/06/15/accessing-gdpr-settings/index.html index 1013e9618e8..4b6c2ee0b87 100644 --- a/news/2022/06/15/accessing-gdpr-settings/index.html +++ b/news/2022/06/15/accessing-gdpr-settings/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Accessing GDPR Settings

    · 2 min read
    Michael

    At some point in your application development when you start to store and share data you will need to handle user GDPR settings.

    GDPR

    The General Data Protection Regulation (GDPR) is a European Union (EU) regulation that mandates how an organisation should handle personal data.

    If you use personalised advertising or store user related data on your server then you will need to address GDPR concerns in your application.

    On mobile devices the GDPR settings are stored through the IAB Europe Transparency & Consent Framework. This framework ensures settings are stored in consistent places for developers to access and determine their appropriate behaviour for the user.

    These values are stored in NSUserDefaults on iOS and in SharedPreferences on Android.

    With the AIR SDK we can access these values easily through the Application extension. The Application extension allows access to the NSUserDefaults and the SharedPreferences through the defaults functionality.

    Firstly, we set the useSharedDefaults flag to ensure we use the application's shared values.

    Application.service.defaults.useSharedDefaults = true;

    If we don't set this flag, then the values retrieved through the defaults functionality will be isolated from values set via other methods and you won't retrieve the correct TC data values.

    Once you have set this flag you can retrieve any of the TC data from the framework by using the appropriate key.

    For example:

    var value:String = 
    Application.service.defaults.
    getString( "IABTCF_TCString" );

    You can then use this value as required for your implementation of GDPR in your application.

    For a full list of the available keys and a description of the values and types see the documentation here.

    - + \ No newline at end of file diff --git a/news/2022/10/07/inappbilling-v14-update/index.html b/news/2022/10/07/inappbilling-v14-update/index.html index c6dd8cca61c..a32b71b1690 100644 --- a/news/2022/10/07/inappbilling-v14-update/index.html +++ b/news/2022/10/07/inappbilling-v14-update/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    InAppBilling v14

    · 2 min read
    Michael

    Many of you will have received the following notice from Google over the previous months:

    Reminder

    Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer.

    We are excited to announce that version 14 of the InAppBilling extension brings v5.0.0 of the Billing library so you will be able to update your applications before the November deadline for updates.


    As announced at Google I/O in 2019 and the Meet Google Play Billing Library Version 3 blog post, all versions of Play Billing Library will follow a two year deprecation cycle.

    Version 5.0.0 brings some major changes to subscriptions and some breaking API changes that you will need to update your application to manage. These changes are mainly focused around subscriptions and generally developers who only use consumable / non-consumable products shouldn't see any change in functionality.

    The changes center around the move from product "discounts" to the newer concept of "offers" to represent the different ways of purchasing a subscription. Offers allow much more flexibility in the ways you can allow your customers to purchase your subscriptions.

    Every subscription product now has at least one subscription offer associated with it. Each offer sets out different pricing phases for a subscription. Eg there may be one offer with a free introductory trial period followed by a recurring monthly subscription. The offer contains one or more subscription phases that has the cost and period information for different phases of the subscription.

    When purchasing as subscription you must now provide the subscription offer you wish to present to the user.

    For more information on migrating, follow the migration guide.

    - + \ No newline at end of file diff --git a/news/2023-01/index.html b/news/2023-01/index.html index 5441b7a70fd..47a35960eaf 100644 --- a/news/2023-01/index.html +++ b/news/2023-01/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    January 2023

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.


    AIR SDK Manager

    This is an application you can use to manage your AIR SDK installations and update them as new releases are available. Additionally you can configure your SDKs without having to manually edit the adt.cfg file and import a license file. This looks to be a great tool and we are excited to see how you find it.

    From Andrew at Harman

    We would value any feedback/comments/ideas of how to improve this. The idea is that you can update SDK versions where there are bug fixes but then each feature-based update can be managed separately. It also allows you to sort out the configuration settings, hopefully meaning you no longer need to bother with adt.cfg files.

    We'd be particularly interested in hearing how you would integrate tools like this into your development process and how tools like apm could work alongside the AIR SDK Manager and your IDEs.

    For more information and giving feedback, see the github discussion.


    Adverts

    We have released a few small fixes for the Adverts extension. Firstly resolving a long standing issue with server side verification options on rewarded video ads. Secondly some documentation updates reflecting Google's change from "funding choices" to "privacy and messaging" for the UMP consent dialog setup. And lastly an update to support the new App Set library, removing the usage of the advertising identifier which can cause privacy concerns particularly in family and children targetted applications.

    If you wish to continue using UMP and the advertising identifiers we suggest you also install the IDFA extension. This will give you access to the tools to request access to the advertising identifier and install the required dependencies for it's usage.


    Application Rater

    The Application Rater extension has been updated to support the Samsung Galaxy store.

    This means that it will now detect if your application was installed through the Galaxy store and correctly redirect to the rating page in the Galaxy store from the rating dialog.

    You can find more information about handling ratings from the different stores in the documentation on Handling Stores


    InAppBilling

    With the latest update to v5 of the play billing library, several developers have noted that certain devices don't return a product list from the getProducts() call and instead get an error dispatched.

    The latest Play Billing library requires an updated version of the Play Store application to be installed on the device so you may want to check for the availability of this before attempting to retrieve the product list.

    We have added some helpers to check for the availability of the billing service on the current device and included a response that indicates if the store application needs updating:

    InAppBilling.service.checkAvailability(
    function ( availability:String ):void
    {
    if (availability == InAppBillingAvailability.STORE_UPGRADE_REQUIRED)
    {
    // An update for the play store application is required
    }
    }
    );

    For more information on the availabilty see the documentation.


    Permissions

    The permissions extension has had some updates to improve the openDirectory() functionality including returning an event on result (PermissionsEvent.OPEN_DOCUMENT) which contains the path the user selected.

    You can read more about this change here.


    NativeWebView

    Lastly this month we released a small update for the Native WebView extension to fix some focus issues on Android with the web view and the latest AIR SDK releases.

    If you are using this extension it is worth updating just to ensure the focus works correctly particularly if you are managing key inputs and overriding the back key operation on Android.


    As always, if you have any native development needs for AIR, Unity, Flutter or Haxe, please feel free to contact us at airnativeextensions@distriqt.com.

    - + \ No newline at end of file diff --git a/news/2023/08/25/game-center-entitlement/index.html b/news/2023/08/25/game-center-entitlement/index.html index 0d5828b9862..37b97ef1f5d 100644 --- a/news/2023/08/25/game-center-entitlement/index.html +++ b/news/2023/08/25/game-center-entitlement/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Game Center requirements

    · 2 min read
    Michael

    If you are publishing games to the AppStore for iOS you may have recently received an notification along the following lines:

    Upcoming Game Center entitlement requirement

    Starting August 16, 2023, new apps and app updates that offer Game Center features need to include the Game Center entitlement and have Game Center features configured in App Store Connect before you can submit them to the App Store. Existing apps on the App Store are not affected by this new requirement.

    We noticed that although the apps listed below have Game Center features configured in App Store Connect, their latest binary delivery doesn’t include the Game Center entitlement. In your next app update, please update your binary to include the entitlement.

    There are two important things you need to do to your application in order to meet this new requirement.

    Firstly, make sure the capability is enabled in "Certificates, Identifiers & Profiles" for your application in the developer portal. Then update and download your provisioning profiles to ensure they are updated with the new capability.

    Then in your application descriptor you will need to add the entitlement. If you are using apm just ensure you are using the latest version and then generate your app descriiptor, apm will ensure the entitlement is correctly added.

    If you are manually managing your app descriptor additions then you will need to add the following to the Entitlements node under iPhone:

    <iPhone>
    <Entitlements><![CDATA[

    <key>com.apple.developer.game-center</key>
    <true/>

    ]]></Entitlements>
    </iPhone>

    Once you have followed these steps your application will support this new requirement and you will be able to submit your application to the AppStore.

    - + \ No newline at end of file diff --git a/news/archive/index.html b/news/archive/index.html index ecbc8ca48e4..69dd8b8a86d 100644 --- a/news/archive/index.html +++ b/news/archive/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content
    - + \ No newline at end of file diff --git a/news/index.html b/news/index.html index cb113d14502..0025efa24f8 100644 --- a/news/index.html +++ b/news/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    · 2 min read
    Michael

    If you are publishing games to the AppStore for iOS you may have recently received an notification along the following lines:

    Upcoming Game Center entitlement requirement

    Starting August 16, 2023, new apps and app updates that offer Game Center features need to include the Game Center entitlement and have Game Center features configured in App Store Connect before you can submit them to the App Store. Existing apps on the App Store are not affected by this new requirement.

    We noticed that although the apps listed below have Game Center features configured in App Store Connect, their latest binary delivery doesn’t include the Game Center entitlement. In your next app update, please update your binary to include the entitlement.

    There are two important things you need to do to your application in order to meet this new requirement.

    Firstly, make sure the capability is enabled in "Certificates, Identifiers & Profiles" for your application in the developer portal. Then update and download your provisioning profiles to ensure they are updated with the new capability.

    Then in your application descriptor you will need to add the entitlement. If you are using apm just ensure you are using the latest version and then generate your app descriiptor, apm will ensure the entitlement is correctly added.

    If you are manually managing your app descriptor additions then you will need to add the following to the Entitlements node under iPhone:

    <iPhone>
    <Entitlements><![CDATA[

    <key>com.apple.developer.game-center</key>
    <true/>

    ]]></Entitlements>
    </iPhone>

    Once you have followed these steps your application will support this new requirement and you will be able to submit your application to the AppStore.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 2 min read
    Michael

    Play Billing v5 release, IronSource updates

    This last month has seen the release of the major update for our InAppBilling extension to support the latest version of the play billing library from Google for the Play Store. This update brings a major change to the way subscriptions are handled and is critical for any updates or new applications released to the Play Store.

    Additionally we have released several updates and new mediation networks for the ironSource extension.

    · 2 min read
    Michael

    Many of you will have received the following notice from Google over the previous months:

    Reminder

    Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer.

    We are excited to announce that version 14 of the InAppBilling extension brings v5.0.0 of the Billing library so you will be able to update your applications before the November deadline for updates.

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    · 2 min read
    Michael

    At some point in your application development when you start to store and share data you will need to handle user GDPR settings.

    GDPR

    The General Data Protection Regulation (GDPR) is a European Union (EU) regulation that mandates how an organisation should handle personal data.

    If you use personalised advertising or store user related data on your server then you will need to address GDPR concerns in your application.

    - + \ No newline at end of file diff --git a/news/page/2/index.html b/news/page/2/index.html index 05f1ea94119..7d660fa8813 100644 --- a/news/page/2/index.html +++ b/news/page/2/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    · 2 min read
    Michael

    Android 12 (API 31)

    What a hectic month! But the great news is that all of our extensions have been updated to the latest Google Play Services and androidx libraries including all the air packages for use in apm!

    · 2 min read
    Michael

    Android 12 (API 31), apm documentation

    This month we were aiming to have released a complete upgrade of all our extensions to be compatible with Android 12 (API 31) including Google Play Services and the AndroidX libraries. Along with this comes a major update to all our documentation to use the AIR Package Manager (apm)!

    Unfortunately due to the unexpected weather event in Australia, distriqt's offices have been affected by extreme flooding and power outages and we have been delayed with this release.

    We are currently aiming to start release of these updates over the next fortnight, as soon as our office is operating again.

    · 3 min read
    Michael

    Android 31, Google Play Services, AndroidX, APM Documentation

    The start to the year has been a disrupted one, with our team having to deal with several COVID cases in our families. Fortunately we weren’t too badly affected and are all back on deck now. But this has meant our schedule for native extension work has been delayed.

    · 2 min read
    Michael

    Camera Roll Extended, and APM

    It has been a quieter month here at distriqt. The team took some time early in the month to have a much needed break especially before the end of year rush.

    Work continues on the AIR package manager. If you are using the tool we’d really love to hear any feedback you may have. We are currently looking to v2.0 and what features the community will need in this utility going forward.

    · 3 min read
    Michael

    AIR Packages, APM v1.0.0

    Again this month has seen a large focus on APM. Porting our extensions over to the new AIR package has taking up much of this month.

    Notable ANE updates include:

    · 3 min read
    Michael

    airsdk.dev, extension updates, and more on APM

    I am hope you aren't sick of hearing about APM, we are really excited for this tool so may feel like that is all we are talking about recently. We have been pushing out all our extensions as air packages and have over 70 packages in the repository now and are hoping to complete all our extensions early in October.

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    - + \ No newline at end of file diff --git a/news/page/3/index.html b/news/page/3/index.html index 58cc86f9088..7226165c107 100644 --- a/news/page/3/index.html +++ b/news/page/3/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    · 3 min read

    Game Services, Vibration (Haptics), Scanning and more Unity.

    Hope everyone is keeping safe out there. This month has seen some much requested updates to several of our extensions, including the Game Center access point, scanning within a viewport and haptic engine (vibrations) functionality.

    Additionally we have released some more Unity plugins available now for our subscribers and in the Unity Asset Store.

    We are also working towards some Flutter extensions and investing time in the platform. If anyone has any requests we are currently looking for a good initial project to expand our services, please feel free to get in touch.

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    · One min read
    Michael

    Welcome to the new documentation site for the distriqt // air native extensions!

    This site forms the home of all documentation for the distriqt's native extensions.

    - + \ No newline at end of file diff --git a/news/tags/admob/index.html b/news/tags/admob/index.html index 098ddcdb6d8..1185cac90ae 100644 --- a/news/tags/admob/index.html +++ b/news/tags/admob/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    2 posts tagged with "admob"

    View All Tags

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    - + \ No newline at end of file diff --git a/news/tags/adskit/index.html b/news/tags/adskit/index.html index 93d26d27072..ee45a497c87 100644 --- a/news/tags/adskit/index.html +++ b/news/tags/adskit/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "adskit"

    View All Tags

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    - + \ No newline at end of file diff --git a/news/tags/advertising/index.html b/news/tags/advertising/index.html index e5be740087f..242e707e9e8 100644 --- a/news/tags/advertising/index.html +++ b/news/tags/advertising/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "advertising"

    View All Tags

    · 2 min read
    Michael

    At some point in your application development when you start to store and share data you will need to handle user GDPR settings.

    GDPR

    The General Data Protection Regulation (GDPR) is a European Union (EU) regulation that mandates how an organisation should handle personal data.

    If you use personalised advertising or store user related data on your server then you will need to address GDPR concerns in your application.

    - + \ No newline at end of file diff --git a/news/tags/adverts/index.html b/news/tags/adverts/index.html index 2f21253dcff..c3b8bc8641e 100644 --- a/news/tags/adverts/index.html +++ b/news/tags/adverts/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    10 posts tagged with "adverts"

    View All Tags

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    - + \ No newline at end of file diff --git a/news/tags/air/index.html b/news/tags/air/index.html index bfb5f021d19..dd7678f1b83 100644 --- a/news/tags/air/index.html +++ b/news/tags/air/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    16 posts tagged with "air"

    View All Tags

    · 2 min read
    Michael

    Android 12 (API 31)

    What a hectic month! But the great news is that all of our extensions have been updated to the latest Google Play Services and androidx libraries including all the air packages for use in apm!

    · 2 min read
    Michael

    Android 12 (API 31), apm documentation

    This month we were aiming to have released a complete upgrade of all our extensions to be compatible with Android 12 (API 31) including Google Play Services and the AndroidX libraries. Along with this comes a major update to all our documentation to use the AIR Package Manager (apm)!

    Unfortunately due to the unexpected weather event in Australia, distriqt's offices have been affected by extreme flooding and power outages and we have been delayed with this release.

    We are currently aiming to start release of these updates over the next fortnight, as soon as our office is operating again.

    · 3 min read
    Michael

    Android 31, Google Play Services, AndroidX, APM Documentation

    The start to the year has been a disrupted one, with our team having to deal with several COVID cases in our families. Fortunately we weren’t too badly affected and are all back on deck now. But this has meant our schedule for native extension work has been delayed.

    · 2 min read
    Michael

    Camera Roll Extended, and APM

    It has been a quieter month here at distriqt. The team took some time early in the month to have a much needed break especially before the end of year rush.

    Work continues on the AIR package manager. If you are using the tool we’d really love to hear any feedback you may have. We are currently looking to v2.0 and what features the community will need in this utility going forward.

    · 3 min read
    Michael

    AIR Packages, APM v1.0.0

    Again this month has seen a large focus on APM. Porting our extensions over to the new AIR package has taking up much of this month.

    Notable ANE updates include:

    · 3 min read
    Michael

    airsdk.dev, extension updates, and more on APM

    I am hope you aren't sick of hearing about APM, we are really excited for this tool so may feel like that is all we are talking about recently. We have been pushing out all our extensions as air packages and have over 70 packages in the repository now and are hoping to complete all our extensions early in October.

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    - + \ No newline at end of file diff --git a/news/tags/air/page/2/index.html b/news/tags/air/page/2/index.html index dace7b4d720..71b67e599b3 100644 --- a/news/tags/air/page/2/index.html +++ b/news/tags/air/page/2/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    16 posts tagged with "air"

    View All Tags

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    · 3 min read

    Game Services, Vibration (Haptics), Scanning and more Unity.

    Hope everyone is keeping safe out there. This month has seen some much requested updates to several of our extensions, including the Game Center access point, scanning within a viewport and haptic engine (vibrations) functionality.

    Additionally we have released some more Unity plugins available now for our subscribers and in the Unity Asset Store.

    We are also working towards some Flutter extensions and investing time in the platform. If anyone has any requests we are currently looking for a good initial project to expand our services, please feel free to get in touch.

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    - + \ No newline at end of file diff --git a/news/tags/airsdk-dev/index.html b/news/tags/airsdk-dev/index.html index 035de1407a8..9c0053bd752 100644 --- a/news/tags/airsdk-dev/index.html +++ b/news/tags/airsdk-dev/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    5 posts tagged with "airsdk.dev"

    View All Tags

    · 2 min read
    Michael

    Android 12 (API 31)

    What a hectic month! But the great news is that all of our extensions have been updated to the latest Google Play Services and androidx libraries including all the air packages for use in apm!

    · 2 min read
    Michael

    Android 12 (API 31), apm documentation

    This month we were aiming to have released a complete upgrade of all our extensions to be compatible with Android 12 (API 31) including Google Play Services and the AndroidX libraries. Along with this comes a major update to all our documentation to use the AIR Package Manager (apm)!

    Unfortunately due to the unexpected weather event in Australia, distriqt's offices have been affected by extreme flooding and power outages and we have been delayed with this release.

    We are currently aiming to start release of these updates over the next fortnight, as soon as our office is operating again.

    · 3 min read
    Michael

    Android 31, Google Play Services, AndroidX, APM Documentation

    The start to the year has been a disrupted one, with our team having to deal with several COVID cases in our families. Fortunately we weren’t too badly affected and are all back on deck now. But this has meant our schedule for native extension work has been delayed.

    · 2 min read
    Michael

    Camera Roll Extended, and APM

    It has been a quieter month here at distriqt. The team took some time early in the month to have a much needed break especially before the end of year rush.

    Work continues on the AIR package manager. If you are using the tool we’d really love to hear any feedback you may have. We are currently looking to v2.0 and what features the community will need in this utility going forward.

    · 3 min read
    Michael

    airsdk.dev, extension updates, and more on APM

    I am hope you aren't sick of hearing about APM, we are really excited for this tool so may feel like that is all we are talking about recently. We have been pushing out all our extensions as air packages and have over 70 packages in the repository now and are hoping to complete all our extensions early in October.

    - + \ No newline at end of file diff --git a/news/tags/airsdk/index.html b/news/tags/airsdk/index.html index f49f47b7d17..96affd2c8c7 100644 --- a/news/tags/airsdk/index.html +++ b/news/tags/airsdk/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    4 posts tagged with "airsdk"

    View All Tags

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 2 min read
    Michael

    Many of you will have received the following notice from Google over the previous months:

    Reminder

    Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer.

    We are excited to announce that version 14 of the InAppBilling extension brings v5.0.0 of the Billing library so you will be able to update your applications before the November deadline for updates.

    · 2 min read
    Michael

    At some point in your application development when you start to store and share data you will need to handle user GDPR settings.

    GDPR

    The General Data Protection Regulation (GDPR) is a European Union (EU) regulation that mandates how an organisation should handle personal data.

    If you use personalised advertising or store user related data on your server then you will need to address GDPR concerns in your application.

    - + \ No newline at end of file diff --git a/news/tags/android-30/index.html b/news/tags/android-30/index.html index b4b37178cd9..8f75aa8472e 100644 --- a/news/tags/android-30/index.html +++ b/news/tags/android-30/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "android-30"

    View All Tags

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    - + \ No newline at end of file diff --git a/news/tags/ane/index.html b/news/tags/ane/index.html index 808f2acf1d8..7c5e5c82359 100644 --- a/news/tags/ane/index.html +++ b/news/tags/ane/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "ane"

    View All Tags

    · 2 min read
    Michael

    At some point in your application development when you start to store and share data you will need to handle user GDPR settings.

    GDPR

    The General Data Protection Regulation (GDPR) is a European Union (EU) regulation that mandates how an organisation should handle personal data.

    If you use personalised advertising or store user related data on your server then you will need to address GDPR concerns in your application.

    - + \ No newline at end of file diff --git a/news/tags/apm/index.html b/news/tags/apm/index.html index 98bf81204a1..894fafd4c4f 100644 --- a/news/tags/apm/index.html +++ b/news/tags/apm/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    13 posts tagged with "apm"

    View All Tags

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    · 2 min read
    Michael

    Android 12 (API 31)

    What a hectic month! But the great news is that all of our extensions have been updated to the latest Google Play Services and androidx libraries including all the air packages for use in apm!

    · 2 min read
    Michael

    Android 12 (API 31), apm documentation

    This month we were aiming to have released a complete upgrade of all our extensions to be compatible with Android 12 (API 31) including Google Play Services and the AndroidX libraries. Along with this comes a major update to all our documentation to use the AIR Package Manager (apm)!

    Unfortunately due to the unexpected weather event in Australia, distriqt's offices have been affected by extreme flooding and power outages and we have been delayed with this release.

    We are currently aiming to start release of these updates over the next fortnight, as soon as our office is operating again.

    · 3 min read
    Michael

    Android 31, Google Play Services, AndroidX, APM Documentation

    The start to the year has been a disrupted one, with our team having to deal with several COVID cases in our families. Fortunately we weren’t too badly affected and are all back on deck now. But this has meant our schedule for native extension work has been delayed.

    · 2 min read
    Michael

    Camera Roll Extended, and APM

    It has been a quieter month here at distriqt. The team took some time early in the month to have a much needed break especially before the end of year rush.

    Work continues on the AIR package manager. If you are using the tool we’d really love to hear any feedback you may have. We are currently looking to v2.0 and what features the community will need in this utility going forward.

    · 3 min read
    Michael

    AIR Packages, APM v1.0.0

    Again this month has seen a large focus on APM. Porting our extensions over to the new AIR package has taking up much of this month.

    Notable ANE updates include:

    · 3 min read
    Michael

    airsdk.dev, extension updates, and more on APM

    I am hope you aren't sick of hearing about APM, we are really excited for this tool so may feel like that is all we are talking about recently. We have been pushing out all our extensions as air packages and have over 70 packages in the repository now and are hoping to complete all our extensions early in October.

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    - + \ No newline at end of file diff --git a/news/tags/apm/page/2/index.html b/news/tags/apm/page/2/index.html index d53dd2ca74d..2832a8bcba8 100644 --- a/news/tags/apm/page/2/index.html +++ b/news/tags/apm/page/2/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    13 posts tagged with "apm"

    View All Tags

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    - + \ No newline at end of file diff --git a/news/tags/apple/index.html b/news/tags/apple/index.html index 3ea980f6e87..16f87d4e009 100644 --- a/news/tags/apple/index.html +++ b/news/tags/apple/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "apple"

    View All Tags

    · 2 min read
    Michael

    If you are publishing games to the AppStore for iOS you may have recently received an notification along the following lines:

    Upcoming Game Center entitlement requirement

    Starting August 16, 2023, new apps and app updates that offer Game Center features need to include the Game Center entitlement and have Game Center features configured in App Store Connect before you can submit them to the App Store. Existing apps on the App Store are not affected by this new requirement.

    We noticed that although the apps listed below have Game Center features configured in App Store Connect, their latest binary delivery doesn’t include the Game Center entitlement. In your next app update, please update your binary to include the entitlement.

    There are two important things you need to do to your application in order to meet this new requirement.

    Firstly, make sure the capability is enabled in "Certificates, Identifiers & Profiles" for your application in the developer portal. Then update and download your provisioning profiles to ensure they are updated with the new capability.

    Then in your application descriptor you will need to add the entitlement. If you are using apm just ensure you are using the latest version and then generate your app descriiptor, apm will ensure the entitlement is correctly added.

    If you are manually managing your app descriptor additions then you will need to add the following to the Entitlements node under iPhone:

    <iPhone>
    <Entitlements><![CDATA[

    <key>com.apple.developer.game-center</key>
    <true/>

    ]]></Entitlements>
    </iPhone>

    Once you have followed these steps your application will support this new requirement and you will be able to submit your application to the AppStore.

    - + \ No newline at end of file diff --git a/news/tags/application-rater/index.html b/news/tags/application-rater/index.html index 10f47de77aa..b75266eb3a3 100644 --- a/news/tags/application-rater/index.html +++ b/news/tags/application-rater/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    2 posts tagged with "application-rater"

    View All Tags

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    - + \ No newline at end of file diff --git a/news/tags/crashlytics/index.html b/news/tags/crashlytics/index.html index 25092602956..f303b24acf1 100644 --- a/news/tags/crashlytics/index.html +++ b/news/tags/crashlytics/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "crashlytics"

    View All Tags

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    - + \ No newline at end of file diff --git a/news/tags/cutouts/index.html b/news/tags/cutouts/index.html index 6e0ffc0a7d9..1ebc885795a 100644 --- a/news/tags/cutouts/index.html +++ b/news/tags/cutouts/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "cutouts"

    View All Tags

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    - + \ No newline at end of file diff --git a/news/tags/dialog/index.html b/news/tags/dialog/index.html index 944ba6adccd..8ad8b927d8f 100644 --- a/news/tags/dialog/index.html +++ b/news/tags/dialog/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "dialog"

    View All Tags

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    - + \ No newline at end of file diff --git a/news/tags/documentation/index.html b/news/tags/documentation/index.html index c654c776685..07e87511e4f 100644 --- a/news/tags/documentation/index.html +++ b/news/tags/documentation/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "documentation"

    View All Tags

    · One min read
    Michael

    Welcome to the new documentation site for the distriqt // air native extensions!

    This site forms the home of all documentation for the distriqt's native extensions.

    - + \ No newline at end of file diff --git a/news/tags/dynamicicon/index.html b/news/tags/dynamicicon/index.html index c8907ab6068..1774a9c82e8 100644 --- a/news/tags/dynamicicon/index.html +++ b/news/tags/dynamicicon/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "dynamicicon"

    View All Tags

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    - + \ No newline at end of file diff --git a/news/tags/facebook/index.html b/news/tags/facebook/index.html index 253f6e110ee..0926afb0628 100644 --- a/news/tags/facebook/index.html +++ b/news/tags/facebook/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    4 posts tagged with "facebook"

    View All Tags

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    - + \ No newline at end of file diff --git a/news/tags/fcm/index.html b/news/tags/fcm/index.html index cced3099fa1..35a5b417c26 100644 --- a/news/tags/fcm/index.html +++ b/news/tags/fcm/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "fcm"

    View All Tags
    - + \ No newline at end of file diff --git a/news/tags/firebase/index.html b/news/tags/firebase/index.html index 6a0f60a05f8..cec0e933c53 100644 --- a/news/tags/firebase/index.html +++ b/news/tags/firebase/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    3 posts tagged with "firebase"

    View All Tags

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    - + \ No newline at end of file diff --git a/news/tags/flash-eol/index.html b/news/tags/flash-eol/index.html index 6cf25ab49ea..08582bad19a 100644 --- a/news/tags/flash-eol/index.html +++ b/news/tags/flash-eol/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "flash-eol"

    View All Tags

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    - + \ No newline at end of file diff --git a/news/tags/game-services/index.html b/news/tags/game-services/index.html index ed82457e5fc..5e6225e04e0 100644 --- a/news/tags/game-services/index.html +++ b/news/tags/game-services/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "game-services"

    View All Tags

    · 2 min read
    Michael

    If you are publishing games to the AppStore for iOS you may have recently received an notification along the following lines:

    Upcoming Game Center entitlement requirement

    Starting August 16, 2023, new apps and app updates that offer Game Center features need to include the Game Center entitlement and have Game Center features configured in App Store Connect before you can submit them to the App Store. Existing apps on the App Store are not affected by this new requirement.

    We noticed that although the apps listed below have Game Center features configured in App Store Connect, their latest binary delivery doesn’t include the Game Center entitlement. In your next app update, please update your binary to include the entitlement.

    There are two important things you need to do to your application in order to meet this new requirement.

    Firstly, make sure the capability is enabled in "Certificates, Identifiers & Profiles" for your application in the developer portal. Then update and download your provisioning profiles to ensure they are updated with the new capability.

    Then in your application descriptor you will need to add the entitlement. If you are using apm just ensure you are using the latest version and then generate your app descriiptor, apm will ensure the entitlement is correctly added.

    If you are manually managing your app descriptor additions then you will need to add the following to the Entitlements node under iPhone:

    <iPhone>
    <Entitlements><![CDATA[

    <key>com.apple.developer.game-center</key>
    <true/>

    ]]></Entitlements>
    </iPhone>

    Once you have followed these steps your application will support this new requirement and you will be able to submit your application to the AppStore.

    - + \ No newline at end of file diff --git a/news/tags/gamecenter/index.html b/news/tags/gamecenter/index.html index d40d63a3269..a86761354c5 100644 --- a/news/tags/gamecenter/index.html +++ b/news/tags/gamecenter/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "gamecenter"

    View All Tags

    · 2 min read
    Michael

    If you are publishing games to the AppStore for iOS you may have recently received an notification along the following lines:

    Upcoming Game Center entitlement requirement

    Starting August 16, 2023, new apps and app updates that offer Game Center features need to include the Game Center entitlement and have Game Center features configured in App Store Connect before you can submit them to the App Store. Existing apps on the App Store are not affected by this new requirement.

    We noticed that although the apps listed below have Game Center features configured in App Store Connect, their latest binary delivery doesn’t include the Game Center entitlement. In your next app update, please update your binary to include the entitlement.

    There are two important things you need to do to your application in order to meet this new requirement.

    Firstly, make sure the capability is enabled in "Certificates, Identifiers & Profiles" for your application in the developer portal. Then update and download your provisioning profiles to ensure they are updated with the new capability.

    Then in your application descriptor you will need to add the entitlement. If you are using apm just ensure you are using the latest version and then generate your app descriiptor, apm will ensure the entitlement is correctly added.

    If you are manually managing your app descriptor additions then you will need to add the following to the Entitlements node under iPhone:

    <iPhone>
    <Entitlements><![CDATA[

    <key>com.apple.developer.game-center</key>
    <true/>

    ]]></Entitlements>
    </iPhone>

    Once you have followed these steps your application will support this new requirement and you will be able to submit your application to the AppStore.

    - + \ No newline at end of file diff --git a/news/tags/gamecontroller/index.html b/news/tags/gamecontroller/index.html index d9e5af7d8fb..4ebec76942f 100644 --- a/news/tags/gamecontroller/index.html +++ b/news/tags/gamecontroller/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "gamecontroller"

    View All Tags

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    - + \ No newline at end of file diff --git a/news/tags/gameservices/index.html b/news/tags/gameservices/index.html index febf0a03e0e..41b7365c48d 100644 --- a/news/tags/gameservices/index.html +++ b/news/tags/gameservices/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    2 posts tagged with "gameservices"

    View All Tags

    · 3 min read

    Game Services, Vibration (Haptics), Scanning and more Unity.

    Hope everyone is keeping safe out there. This month has seen some much requested updates to several of our extensions, including the Game Center access point, scanning within a viewport and haptic engine (vibrations) functionality.

    Additionally we have released some more Unity plugins available now for our subscribers and in the Unity Asset Store.

    We are also working towards some Flutter extensions and investing time in the platform. If anyone has any requests we are currently looking for a good initial project to expand our services, please feel free to get in touch.

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    - + \ No newline at end of file diff --git a/news/tags/gdpr/index.html b/news/tags/gdpr/index.html index d75d8245407..7763595fab4 100644 --- a/news/tags/gdpr/index.html +++ b/news/tags/gdpr/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "gdpr"

    View All Tags

    · 2 min read
    Michael

    At some point in your application development when you start to store and share data you will need to handle user GDPR settings.

    GDPR

    The General Data Protection Regulation (GDPR) is a European Union (EU) regulation that mandates how an organisation should handle personal data.

    If you use personalised advertising or store user related data on your server then you will need to address GDPR concerns in your application.

    - + \ No newline at end of file diff --git a/news/tags/google-play-billing/index.html b/news/tags/google-play-billing/index.html index cab62d90994..89bac178870 100644 --- a/news/tags/google-play-billing/index.html +++ b/news/tags/google-play-billing/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    6 posts tagged with "google-play-billing"

    View All Tags

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 2 min read
    Michael

    Play Billing v5 release, IronSource updates

    This last month has seen the release of the major update for our InAppBilling extension to support the latest version of the play billing library from Google for the Play Store. This update brings a major change to the way subscriptions are handled and is critical for any updates or new applications released to the Play Store.

    Additionally we have released several updates and new mediation networks for the ironSource extension.

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    - + \ No newline at end of file diff --git a/news/tags/google-play-services/index.html b/news/tags/google-play-services/index.html index 49d5efdb03b..ef55e8223b2 100644 --- a/news/tags/google-play-services/index.html +++ b/news/tags/google-play-services/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "google play services"

    View All Tags
    - + \ No newline at end of file diff --git a/news/tags/hello/index.html b/news/tags/hello/index.html index 3eea0bb441a..2636371d822 100644 --- a/news/tags/hello/index.html +++ b/news/tags/hello/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "hello"

    View All Tags

    · One min read
    Michael

    Welcome to the new documentation site for the distriqt // air native extensions!

    This site forms the home of all documentation for the distriqt's native extensions.

    - + \ No newline at end of file diff --git a/news/tags/huawei/index.html b/news/tags/huawei/index.html index 677932a235f..e962ca14e21 100644 --- a/news/tags/huawei/index.html +++ b/news/tags/huawei/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "huawei"

    View All Tags

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    - + \ No newline at end of file diff --git a/news/tags/inappbilling/index.html b/news/tags/inappbilling/index.html index ea6d8b6ed12..d109946a915 100644 --- a/news/tags/inappbilling/index.html +++ b/news/tags/inappbilling/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    5 posts tagged with "inappbilling"

    View All Tags

    · 2 min read
    Michael

    Play Billing v5 release, IronSource updates

    This last month has seen the release of the major update for our InAppBilling extension to support the latest version of the play billing library from Google for the Play Store. This update brings a major change to the way subscriptions are handled and is critical for any updates or new applications released to the Play Store.

    Additionally we have released several updates and new mediation networks for the ironSource extension.

    · 2 min read
    Michael

    Many of you will have received the following notice from Google over the previous months:

    Reminder

    Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer.

    We are excited to announce that version 14 of the InAppBilling extension brings v5.0.0 of the Billing library so you will be able to update your applications before the November deadline for updates.

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    - + \ No newline at end of file diff --git a/news/tags/index.html b/news/tags/index.html index 4cb8abbf0c2..144dfc74d88 100644 --- a/news/tags/index.html +++ b/news/tags/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content
    - + \ No newline at end of file diff --git a/news/tags/ios-simulator/index.html b/news/tags/ios-simulator/index.html index b2e9bdbe81b..00fdf9b7921 100644 --- a/news/tags/ios-simulator/index.html +++ b/news/tags/ios-simulator/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "ios-simulator"

    View All Tags
    - + \ No newline at end of file diff --git a/news/tags/ios/index.html b/news/tags/ios/index.html index a75d0152efc..ebe35296c75 100644 --- a/news/tags/ios/index.html +++ b/news/tags/ios/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "ios"

    View All Tags

    · 2 min read
    Michael

    If you are publishing games to the AppStore for iOS you may have recently received an notification along the following lines:

    Upcoming Game Center entitlement requirement

    Starting August 16, 2023, new apps and app updates that offer Game Center features need to include the Game Center entitlement and have Game Center features configured in App Store Connect before you can submit them to the App Store. Existing apps on the App Store are not affected by this new requirement.

    We noticed that although the apps listed below have Game Center features configured in App Store Connect, their latest binary delivery doesn’t include the Game Center entitlement. In your next app update, please update your binary to include the entitlement.

    There are two important things you need to do to your application in order to meet this new requirement.

    Firstly, make sure the capability is enabled in "Certificates, Identifiers & Profiles" for your application in the developer portal. Then update and download your provisioning profiles to ensure they are updated with the new capability.

    Then in your application descriptor you will need to add the entitlement. If you are using apm just ensure you are using the latest version and then generate your app descriiptor, apm will ensure the entitlement is correctly added.

    If you are manually managing your app descriptor additions then you will need to add the following to the Entitlements node under iPhone:

    <iPhone>
    <Entitlements><![CDATA[

    <key>com.apple.developer.game-center</key>
    <true/>

    ]]></Entitlements>
    </iPhone>

    Once you have followed these steps your application will support this new requirement and you will be able to submit your application to the AppStore.

    - + \ No newline at end of file diff --git a/news/tags/ironsource/index.html b/news/tags/ironsource/index.html index 5e52e7979e2..bb4d38f4967 100644 --- a/news/tags/ironsource/index.html +++ b/news/tags/ironsource/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    3 posts tagged with "ironsource"

    View All Tags

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    - + \ No newline at end of file diff --git a/news/tags/nativewebview/index.html b/news/tags/nativewebview/index.html index fb852fda428..316d2c8fa0d 100644 --- a/news/tags/nativewebview/index.html +++ b/news/tags/nativewebview/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "nativewebview"

    View All Tags

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    - + \ No newline at end of file diff --git a/news/tags/newsletter/index.html b/news/tags/newsletter/index.html index f8e97ed9ade..9b6d97cdf1b 100644 --- a/news/tags/newsletter/index.html +++ b/news/tags/newsletter/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    23 posts tagged with "newsletter"

    View All Tags

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 4 min read
    Michael

    AIR SDK Manager, Adverts, Application Rater

    As the end of the year approaches we have been cleaning up a lot of the work we have done this year and starting to set out development goals for the first half of next year. As we enter into the final weeks of the year if there is anything in our extensions that you believe should have priority please let us know and we will be sure to schedule it for the beginning of the year.

    Importantly this month Harman have released a beta of the new AIR SDK Manager.

    · 2 min read
    Michael

    Play Billing v5 release, IronSource updates

    This last month has seen the release of the major update for our InAppBilling extension to support the latest version of the play billing library from Google for the Play Store. This update brings a major change to the way subscriptions are handled and is critical for any updates or new applications released to the Play Store.

    Additionally we have released several updates and new mediation networks for the ironSource extension.

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    · 3 min read
    Michael

    APM Update, InAppBilling testing

    This month a series of smaller updates have been released including updates for Firebase, Adverts and Share extensions to address some minor issues that were found in the extensions.

    Importantly APM v1.2.0 has been released! If you aren't using APM to manage your extensions we highly recommend spending a small amount of time to migrate to using this tool. It will save you an enormous amount of time maintaining your application descriptor particularly for Android builds when needing to update the manifest additions.

    · 2 min read
    Michael

    Android 12 (API 31)

    What a hectic month! But the great news is that all of our extensions have been updated to the latest Google Play Services and androidx libraries including all the air packages for use in apm!

    · 2 min read
    Michael

    Android 12 (API 31), apm documentation

    This month we were aiming to have released a complete upgrade of all our extensions to be compatible with Android 12 (API 31) including Google Play Services and the AndroidX libraries. Along with this comes a major update to all our documentation to use the AIR Package Manager (apm)!

    Unfortunately due to the unexpected weather event in Australia, distriqt's offices have been affected by extreme flooding and power outages and we have been delayed with this release.

    We are currently aiming to start release of these updates over the next fortnight, as soon as our office is operating again.

    · 3 min read
    Michael

    Android 31, Google Play Services, AndroidX, APM Documentation

    The start to the year has been a disrupted one, with our team having to deal with several COVID cases in our families. Fortunately we weren’t too badly affected and are all back on deck now. But this has meant our schedule for native extension work has been delayed.

    - + \ No newline at end of file diff --git a/news/tags/newsletter/page/2/index.html b/news/tags/newsletter/page/2/index.html index f0c242e69a1..f96a46c2ade 100644 --- a/news/tags/newsletter/page/2/index.html +++ b/news/tags/newsletter/page/2/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    23 posts tagged with "newsletter"

    View All Tags

    · 2 min read
    Michael

    Camera Roll Extended, and APM

    It has been a quieter month here at distriqt. The team took some time early in the month to have a much needed break especially before the end of year rush.

    Work continues on the AIR package manager. If you are using the tool we’d really love to hear any feedback you may have. We are currently looking to v2.0 and what features the community will need in this utility going forward.

    · 3 min read
    Michael

    AIR Packages, APM v1.0.0

    Again this month has seen a large focus on APM. Porting our extensions over to the new AIR package has taking up much of this month.

    Notable ANE updates include:

    · 3 min read
    Michael

    airsdk.dev, extension updates, and more on APM

    I am hope you aren't sick of hearing about APM, we are really excited for this tool so may feel like that is all we are talking about recently. We have been pushing out all our extensions as air packages and have over 70 packages in the repository now and are hoping to complete all our extensions early in October.

    · 4 min read
    Michael

    APM, Adverts and Android 30

    Another big month, APM is moving along quickly and our first version of manifest merging has been added! We are super excited about this tool and the way it will change AIR development. I know a lot of the people we talk to emphasise the lack of quick integration being the biggest hurdle with AIR development and we believe this tool is almost ready to resolve that.

    Other updates include latest AdMob SDK and mediation networks. Flurry SDK has been updated and the new "standard events" added. CameraUI has had some major changes integrated to support Android 30, and the Scanner extension had some bug fixes released.

    · 4 min read
    Michael

    APM, Dialog, ironSource

    What an exciting month for AIR! Harman now has a feasible solution for publishing to AAB on Android and excitingly for us, we have released the first beta of the AIR Package Manager!

    I am really excited to get this tool out to developers.

    · 2 min read
    Michael

    APM, AdMob

    Here we are already at the mid point of the year! This month has been lots of internal work for us here at distriqt and not a lot of public releases, so this will be a short one this month.

    I have mainly been focussed on APM, and am really excited to get this tool out to developers.

    · 3 min read
    Michael

    APM, AdMob and Google Play Services.

    This month has seen major development work being done on APM. We are excited that some sponsorship has meant we have been able to spend some time on this tool and we are hoping to start releasing some prototypes to the community.

    AdMob had a major update last month and we have updated the Adverts extension to reflect this major change. This has been a large amount of work for us, so hopefully it's keeping your AIR applications running smoothly with monetisation through advertising!

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    · 3 min read

    Game Services, Vibration (Haptics), Scanning and more Unity.

    Hope everyone is keeping safe out there. This month has seen some much requested updates to several of our extensions, including the Game Center access point, scanning within a viewport and haptic engine (vibrations) functionality.

    Additionally we have released some more Unity plugins available now for our subscribers and in the Unity Asset Store.

    We are also working towards some Flutter extensions and investing time in the platform. If anyone has any requests we are currently looking for a good initial project to expand our services, please feel free to get in touch.

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    - + \ No newline at end of file diff --git a/news/tags/newsletter/page/3/index.html b/news/tags/newsletter/page/3/index.html index 77abc903a27..c07442bcb7e 100644 --- a/news/tags/newsletter/page/3/index.html +++ b/news/tags/newsletter/page/3/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    23 posts tagged with "newsletter"

    View All Tags

    · 3 min read
    Michael

    Firebase, Facebook, Advertising, Game Services and more…

    We are starting the year with a series of updates for some of our biggest extensions. With the privacy changes for IDFA in iOS 14 looming a lot of the advertising SDKs have been updated to get ready for this change. We have updates for AdMob and IronSource available to supposedly address these changes.

    A lot of updates to start the year, so please let us know if there are any concerns about updating the extensions. We have migration guides available where the changes are significant so look for those in the documentation.

    · One min read
    Michael

    Firebase Crashlytics and Huawei Ads Kit

    What a year 2020 has been. I’m sure we are all looking forward to a more sensible 2021 but as I write this we are entering another lockdown due to the new variant of COVID.

    Here’s to a busy and fun filled 2021! Stay safe everyone!

    · 3 min read
    Michael

    Facebook, NativeWebView, Flash EOL, and advertising updates.

    The end of the year is almost upon us, but the work never stops!

    This month has seen a major release for the Facebook extension, a complete rewrite which has been in development for 6 months. Additionally our Adverts and IronSource ANEs have had some functionality updates that may interest some developers.

    - + \ No newline at end of file diff --git a/news/tags/nfc/index.html b/news/tags/nfc/index.html index 5f00dd32c11..6b3588ea375 100644 --- a/news/tags/nfc/index.html +++ b/news/tags/nfc/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "nfc"

    View All Tags

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    - + \ No newline at end of file diff --git a/news/tags/permissions/index.html b/news/tags/permissions/index.html index eae3f8c6133..8b63495d4c9 100644 --- a/news/tags/permissions/index.html +++ b/news/tags/permissions/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "permissions"

    View All Tags

    · 3 min read
    Michael

    Cutouts/Notches, InAppBilling testing

    This month a series of smaller updates have been released including updates for Application, Adverts and Permissions extensions to address some minor issues that were found in the extensions and to add some features.

    Community announcement

    The AS3 reference has finally been updated to reflect the latest changes in the AIR SDK since harman took over development. We have been able to host it on the air sdk developer portal, so if you need access to the latest actionscript reference you will find it here: https://airsdk.dev/reference.

    Additionally if you have any tutorials or guides that may be useful for the AIR community please reach out to us and we can help you get them hosted on the airsdk.dev site.

    - + \ No newline at end of file diff --git a/news/tags/playbilling/index.html b/news/tags/playbilling/index.html index de27620060d..ed2a6024a47 100644 --- a/news/tags/playbilling/index.html +++ b/news/tags/playbilling/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "playbilling"

    View All Tags

    · 2 min read
    Michael

    Many of you will have received the following notice from Google over the previous months:

    Reminder

    Starting on August 2, 2022, all new apps must use Billing Library version 4 or newer. By November 1, 2022, all updates to existing apps must use Billing Library version 4 or newer.

    We are excited to announce that version 14 of the InAppBilling extension brings v5.0.0 of the Billing library so you will be able to update your applications before the November deadline for updates.

    - + \ No newline at end of file diff --git a/news/tags/samsung/index.html b/news/tags/samsung/index.html index 45bf65fb6a1..94fc6fb7dbd 100644 --- a/news/tags/samsung/index.html +++ b/news/tags/samsung/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    One post tagged with "samsung"

    View All Tags

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    - + \ No newline at end of file diff --git a/news/tags/scanner/index.html b/news/tags/scanner/index.html index 623f192529f..dc1658b9fdb 100644 --- a/news/tags/scanner/index.html +++ b/news/tags/scanner/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "scanner"

    View All Tags

    · 3 min read

    Game Services, Vibration (Haptics), Scanning and more Unity.

    Hope everyone is keeping safe out there. This month has seen some much requested updates to several of our extensions, including the Game Center access point, scanning within a viewport and haptic engine (vibrations) functionality.

    Additionally we have released some more Unity plugins available now for our subscribers and in the Unity Asset Store.

    We are also working towards some Flutter extensions and investing time in the platform. If anyone has any requests we are currently looking for a good initial project to expand our services, please feel free to get in touch.

    - + \ No newline at end of file diff --git a/news/tags/swc/index.html b/news/tags/swc/index.html index 9c467c32994..a757c7d73a0 100644 --- a/news/tags/swc/index.html +++ b/news/tags/swc/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    One post tagged with "swc"

    View All Tags
    - + \ No newline at end of file diff --git a/news/tags/unity/index.html b/news/tags/unity/index.html index 047dde2fc80..013706c2169 100644 --- a/news/tags/unity/index.html +++ b/news/tags/unity/index.html @@ -13,14 +13,14 @@ - +
    Skip to main content

    2 posts tagged with "unity"

    View All Tags

    · 3 min read

    General Updates, APM, Game Controller, and Unity NFC.

    This month has seen a range of smaller bug fixes and updates to the extensions, including:

    • Flurry: SDK update;
    • MediaPlayer: Fix for display issue on destroy;
    • CameraUI: Android gallery meta-data issue fix;
    • Adverts Mediation: Tap Joy resources issue;

    We are continuing towards some Flutter extensions and are still looking for suggestions. If anyone has any requests we are looking for a good initial project to expand our services, please feel free to get in touch with your ideas.

    Additionally we have released another Unity plugin for NFC available now for our subscribers in github and in the Unity Asset Store.

    · 3 min read

    APM, InAppBilling, OneSignal, Facebook and Unity

    This month we have updated some of our most important extensions, including a new service for In-App Billing (Samsung and macOS), major SDK updates for OneSignal (Push Notifications) and Facebook.

    Additionally we have released several of our extensions as Unity Plugins on the Unity Asset Store. This allows us to move into a new market while still bringing much needed tools to AIR. Any feedback is welcome.

    AIR Package Manager

    Our lead developer is working on a pet project at the moment and is looking for support to get it off the ground.

    The AIR Package Manager allows management of AIR libraries and extensions and assists in creation of the application descriptor.

    It’s a much needed missing part of the AIR ecosystem but unfortunately it’s too large a project for us to develop internally. Have a look at the repository and if you have any thoughts and feel you could help please reach out, either by sponsoring or contributing.

    - + \ No newline at end of file diff --git a/news/welcome/index.html b/news/welcome/index.html index 6567cd5c246..1451bf7869d 100644 --- a/news/welcome/index.html +++ b/news/welcome/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Welcome

    · One min read
    Michael

    Welcome to the new documentation site for the distriqt // air native extensions!

    This site forms the home of all documentation for the distriqt's native extensions.

    - + \ No newline at end of file diff --git a/search/index.html b/search/index.html index f4d2a9622d5..46b6e62e918 100644 --- a/search/index.html +++ b/search/index.html @@ -13,13 +13,13 @@ - +
    Skip to main content

    Search the documentation

    - + \ No newline at end of file