├── .github
└── workflows
│ ├── manual_minor_prerelease.yml
│ ├── manual_patch_prerelease.yml
│ ├── prerelease_github.yml
│ ├── release_pull_requests.yml
│ ├── stale_issues.yml
│ └── upgrade_sandwich.yml
├── .gitignore
├── Editor.meta
├── Editor
├── QonversionDependencies.xml
└── QonversionDependencies.xml.meta
├── README.md
├── README.md.meta
├── Runtime.meta
├── Runtime
├── Android.meta
├── Android
│ ├── AutomationsWrapperAndroid.cs
│ ├── AutomationsWrapperAndroid.cs.meta
│ ├── Plugins.meta
│ ├── Plugins
│ │ ├── com.meta
│ │ └── com
│ │ │ ├── qonversion.meta
│ │ │ └── qonversion
│ │ │ ├── unitywrapper.meta
│ │ │ └── unitywrapper
│ │ │ ├── AutomationsWrapper.java
│ │ │ ├── AutomationsWrapper.java.meta
│ │ │ ├── MessageSender.java
│ │ │ ├── MessageSender.java.meta
│ │ │ ├── QonversionWrapper.java
│ │ │ ├── QonversionWrapper.java.meta
│ │ │ ├── Utils.java
│ │ │ └── Utils.java.meta
│ ├── QonversionWrapperAndroid.cs
│ └── QonversionWrapperAndroid.cs.meta
├── Common.meta
├── Common
│ ├── MiniJSON.meta
│ ├── MiniJSON
│ │ ├── Json.cs
│ │ ├── Json.cs.meta
│ │ ├── MiniJsonExtensions.cs
│ │ └── MiniJsonExtensions.cs.meta
│ ├── MiniJson.cs
│ └── MiniJson.cs.meta
├── Qonversion.Unity.Sdk.asmdef
├── Qonversion.Unity.Sdk.asmdef.meta
├── Scripts.meta
├── Scripts
│ ├── .idea
│ │ └── .idea.Scripts.dir
│ │ │ └── .idea
│ │ │ ├── .gitignore
│ │ │ ├── encodings.xml
│ │ │ ├── indexLayout.xml
│ │ │ └── vcs.xml
│ ├── Automations.cs
│ ├── Automations.cs.meta
│ ├── Dto.meta
│ ├── Dto
│ │ ├── ActionResult.cs
│ │ ├── ActionResult.cs.meta
│ │ ├── ActionResultType.cs
│ │ ├── ActionResultType.cs.meta
│ │ ├── AttributionProvider.cs
│ │ ├── AttributionProvider.cs.meta
│ │ ├── AutomationsDelegate.cs
│ │ ├── AutomationsDelegate.cs.meta
│ │ ├── AutomationsEvent.cs
│ │ ├── AutomationsEvent.cs.meta
│ │ ├── AutomationsEventType.cs
│ │ ├── AutomationsEventType.cs.meta
│ │ ├── Eligibility.cs
│ │ ├── Eligibility.cs.meta
│ │ ├── EligibilityStatus.cs
│ │ ├── EligibilityStatus.cs.meta
│ │ ├── Entitlement.cs
│ │ ├── Entitlement.cs.meta
│ │ ├── EntitlementsCacheLifetime.cs
│ │ ├── EntitlementsCacheLifetime.cs.meta
│ │ ├── Environment.cs
│ │ ├── Environment.cs.meta
│ │ ├── Experiment.cs
│ │ ├── Experiment.cs.meta
│ │ ├── ExperimentGroup.cs
│ │ ├── ExperimentGroup.cs.meta
│ │ ├── LaunchMode.cs
│ │ ├── LaunchMode.cs.meta
│ │ ├── Offering.cs
│ │ ├── Offering.cs.meta
│ │ ├── Offerings.cs
│ │ ├── Offerings.cs.meta
│ │ ├── Product.cs
│ │ ├── Product.cs.meta
│ │ ├── ProductStoreDetails.meta
│ │ ├── ProductStoreDetails
│ │ │ ├── PricingPhaseRecurrenceMode.cs
│ │ │ ├── PricingPhaseRecurrenceMode.cs.meta
│ │ │ ├── PricingPhaseType.cs
│ │ │ ├── PricingPhaseType.cs.meta
│ │ │ ├── ProductInAppDetails.cs
│ │ │ ├── ProductInAppDetails.cs.meta
│ │ │ ├── ProductInstallmentPlanDetails.cs
│ │ │ ├── ProductInstallmentPlanDetails.cs.meta
│ │ │ ├── ProductOfferDetails.cs
│ │ │ ├── ProductOfferDetails.cs.meta
│ │ │ ├── ProductPrice.cs
│ │ │ ├── ProductPrice.cs.meta
│ │ │ ├── ProductPricingPhase.cs
│ │ │ ├── ProductPricingPhase.cs.meta
│ │ │ ├── ProductStoreDetails.cs
│ │ │ └── ProductStoreDetails.cs.meta
│ │ ├── ProductType.cs
│ │ ├── ProductType.cs.meta
│ │ ├── PromotionalOffer.cs
│ │ ├── PromotionalOffer.cs.meta
│ │ ├── PurchaseModel.cs
│ │ ├── PurchaseModel.cs.meta
│ │ ├── PurchaseOptions.cs
│ │ ├── PurchaseOptions.cs.meta
│ │ ├── PurchaseOptionsBuilder.cs
│ │ ├── PurchaseOptionsBuilder.cs.meta
│ │ ├── PurchaseUpdateModel.cs
│ │ ├── PurchaseUpdateModel.cs.meta
│ │ ├── PurchaseUpdatePolicy.cs
│ │ ├── PurchaseUpdatePolicy.cs.meta
│ │ ├── QonversionError.cs
│ │ ├── QonversionError.cs.meta
│ │ ├── RemoteConfig.cs
│ │ ├── RemoteConfig.cs.meta
│ │ ├── RemoteConfigList.cs
│ │ ├── RemoteConfigList.cs.meta
│ │ ├── RemoteConfigurationSource.cs
│ │ ├── RemoteConfigurationSource.cs.meta
│ │ ├── ScreenPresentationConfig.cs
│ │ ├── ScreenPresentationConfig.cs.meta
│ │ ├── ScreenPresentationStyle.cs
│ │ ├── ScreenPresentationStyle.cs.meta
│ │ ├── SkProduct.meta
│ │ ├── SkProduct
│ │ │ ├── SKPraymentDiscount.cs
│ │ │ ├── SKPraymentDiscount.cs.meta
│ │ │ ├── SKProduct.cs
│ │ │ ├── SKProduct.cs.meta
│ │ │ ├── SKProductDiscount.cs
│ │ │ ├── SKProductDiscount.cs.meta
│ │ │ ├── SKProductSubscriptionPeriod.cs
│ │ │ └── SKProductSubscriptionPeriod.cs.meta
│ │ ├── SkuDetails.cs
│ │ ├── SkuDetails.cs.meta
│ │ ├── SubscriptionPeriod.cs
│ │ ├── SubscriptionPeriod.cs.meta
│ │ ├── SubscriptionPeriodUnit.cs
│ │ ├── SubscriptionPeriodUnit.cs.meta
│ │ ├── Transaction.cs
│ │ ├── Transaction.cs.meta
│ │ ├── User.cs
│ │ ├── User.cs.meta
│ │ ├── UserProperties.cs
│ │ ├── UserProperties.cs.meta
│ │ ├── UserProperty.cs
│ │ ├── UserProperty.cs.meta
│ │ ├── UserPropertyKey.cs
│ │ └── UserPropertyKey.cs.meta
│ ├── IAutomations.cs
│ ├── IAutomations.cs.meta
│ ├── IQonversion.cs
│ ├── IQonversion.cs.meta
│ ├── Internal.meta
│ ├── Internal
│ │ ├── AutomationsInternal.cs
│ │ ├── AutomationsInternal.cs.meta
│ │ ├── Constants.cs
│ │ ├── Constants.cs.meta
│ │ ├── Mapper.cs
│ │ ├── Mapper.cs.meta
│ │ ├── QonversionInternal.cs
│ │ ├── QonversionInternal.cs.meta
│ │ ├── Utils.cs
│ │ ├── Utils.cs.meta
│ │ ├── wrappers.meta
│ │ └── wrappers
│ │ │ ├── automations.meta
│ │ │ ├── automations
│ │ │ ├── AutomationsWrapperNoop.cs
│ │ │ ├── AutomationsWrapperNoop.cs.meta
│ │ │ ├── IAutomationsWrapper.cs
│ │ │ └── IAutomationsWrapper.cs.meta
│ │ │ ├── qonversion.meta
│ │ │ └── qonversion
│ │ │ ├── IQonversionWrapper.cs
│ │ │ ├── IQonversionWrapper.cs.meta
│ │ │ ├── QonversionWrapperNoop.cs
│ │ │ └── QonversionWrapperNoop.cs.meta
│ ├── Qonversion.cs
│ ├── Qonversion.cs.meta
│ ├── QonversionConfig.cs
│ ├── QonversionConfig.cs.meta
│ ├── QonversionConfigBuilder.cs
│ └── QonversionConfigBuilder.cs.meta
├── iOS.meta
└── iOS
│ ├── AutomationsWrapperIOS.cs
│ ├── AutomationsWrapperIOS.cs.meta
│ ├── Plugins.meta
│ ├── Plugins
│ ├── AutomationsBridge.m
│ ├── AutomationsBridge.m.meta
│ ├── Common.meta
│ ├── Common
│ │ ├── QNUAutomationsDelegate.h
│ │ ├── QNUAutomationsDelegate.h.meta
│ │ ├── QNUAutomationsDelegate.m
│ │ ├── QNUAutomationsDelegate.m.meta
│ │ ├── UtilityBridge.h
│ │ ├── UtilityBridge.h.meta
│ │ ├── UtilityBridge.m
│ │ └── UtilityBridge.m.meta
│ ├── QonversionBridge.m
│ └── QonversionBridge.m.meta
│ ├── QonversionWrapperIOS.cs
│ └── QonversionWrapperIOS.cs.meta
├── fastlane.meta
├── fastlane
├── Appfile
├── Appfile.meta
├── Fastfile
├── README.md
├── README.md.meta
├── fastfile.meta
├── report.xml
└── report.xml.meta
├── img.meta
├── img
├── UnityQonversionLauncher.png
└── UnityQonversionLauncher.png.meta
├── package.json
└── package.json.meta
/.github/workflows/manual_minor_prerelease.yml:
--------------------------------------------------------------------------------
1 | name: Manual Minor Prerelease
2 |
3 | on:
4 | workflow_dispatch
5 |
6 | jobs:
7 | patch-minor:
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 | with:
13 | ref: develop
14 |
15 | - name: Minor
16 | run: |
17 | fastlane minor
18 |
--------------------------------------------------------------------------------
/.github/workflows/manual_patch_prerelease.yml:
--------------------------------------------------------------------------------
1 | name: Manual Patch Prerelease
2 |
3 | on:
4 | workflow_dispatch
5 |
6 | jobs:
7 | patch-prerelease:
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 | with:
13 | ref: develop
14 |
15 | - name: Patch
16 | run: |
17 | fastlane patch
18 |
--------------------------------------------------------------------------------
/.github/workflows/prerelease_github.yml:
--------------------------------------------------------------------------------
1 | name: Pre-release Github
2 |
3 | on:
4 | push:
5 | branches:
6 | - "main"
7 |
8 | jobs:
9 | pre-release:
10 | runs-on: macos-latest
11 |
12 | steps:
13 | - uses: "marvinpinto/action-automatic-releases@latest"
14 | with:
15 | repo_token: "${{ secrets.GITHUB_TOKEN }}"
16 | automatic_release_tag: "latest"
17 | prerelease: true
18 | title: "Development Build"
19 | files: |
20 | LICENSE.txt
21 | *.jar
--------------------------------------------------------------------------------
/.github/workflows/release_pull_requests.yml:
--------------------------------------------------------------------------------
1 | name: Release pull requests from dev by tag
2 | on:
3 | push:
4 | tags:
5 | - prerelease/*
6 |
7 | jobs:
8 | handle_prerelease:
9 | uses: qonversion/shared-sdk-workflows/.github/workflows/prerelease_handling.yml@main
10 |
--------------------------------------------------------------------------------
/.github/workflows/stale_issues.yml:
--------------------------------------------------------------------------------
1 | name: Close stale issues
2 | on:
3 | schedule:
4 | - cron: '30 1 * * *'
5 |
6 | jobs:
7 | stale_issues:
8 | uses: qonversion/shared-sdk-workflows/.github/workflows/stale_issues.yml@main
--------------------------------------------------------------------------------
/.github/workflows/upgrade_sandwich.yml:
--------------------------------------------------------------------------------
1 | name: Upgrade Sandwich
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | sandwich_version:
6 | description: 'Sandwich version'
7 | required: true
8 | default: '0.0.0'
9 |
10 | jobs:
11 | upgrade:
12 | uses: qonversion/shared-sdk-workflows/.github/workflows/upgrade_sandwich.yml@main
13 | with:
14 | sandwich_version: ${{ github.event.inputs.sandwich_version }}
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This .gitignore file should be placed at the root of your Unity project directory
2 | #
3 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
4 | #
5 | /[Ll]ibrary/
6 | /[Tt]emp/
7 | /[Oo]bj/
8 | /[Bb]uild/
9 | /[Bb]uilds/
10 | /[Ll]ogs/
11 | /[Uu]ser[Ss]ettings/
12 |
13 | # MemoryCaptures can get excessive in size.
14 | # They also could contain extremely sensitive data
15 | /[Mm]emoryCaptures/
16 |
17 | # Recordings can get excessive in size
18 | /[Rr]ecordings/
19 |
20 | # Uncomment this line if you wish to ignore the asset store tools plugin
21 | # /[Aa]ssets/AssetStoreTools*
22 |
23 | # Autogenerated Jetbrains Rider plugin
24 | /[Aa]ssets/Plugins/Editor/JetBrains*
25 |
26 | # Visual Studio cache directory
27 | .vs/
28 |
29 | # Gradle cache directory
30 | .gradle/
31 |
32 | # Autogenerated VS/MD/Consulo solution and project files
33 | ExportedObj/
34 | .consulo/
35 | *.csproj
36 | *.unityproj
37 | *.sln
38 | *.suo
39 | *.tmp
40 | *.user
41 | *.userprefs
42 | *.pidb
43 | *.booproj
44 | *.svd
45 | *.pdb
46 | *.mdb
47 | *.opendb
48 | *.VC.db
49 | .idea
50 |
51 | # Unity3D generated meta files
52 | *.pidb.meta
53 | *.pdb.meta
54 | *.mdb.meta
55 |
56 | # Unity3D generated file on crash reports
57 | sysinfo.txt
58 |
59 | # Builds
60 | *.apk
61 | *.aab
62 | *.unitypackage
63 | *.app
64 |
65 | # Crashlytics generated file
66 | crashlytics-build.properties
67 |
68 | # Packed Addressables
69 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
70 |
71 | # Temporary auto-generated Android Assets
72 | /[Aa]ssets/[Ss]treamingAssets/aa.meta
73 | /[Aa]ssets/[Ss]treamingAssets/aa/*
--------------------------------------------------------------------------------
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 00dca6be949bd4393bfdbb3bc85e201a
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/QonversionDependencies.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Editor/QonversionDependencies.xml.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e8f49b3053cb24b62a0793a238b95380
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | Qonversion
3 |
4 |
5 | Qonversion - In-app subscription monetization: implement subscriptions and grow your app’s revenue with A/B experiments
6 |
7 | * In-app subscription management SDK
8 | * API and webhooks to make your subscription data available where you need it
9 | * Seamless Stripe integration to enable cross-platform access management
10 | * Subscribers CRM with user-level transactions
11 | * Instant access to real-time subscription analytics
12 | * Built-in A/B experiments for subscription business model
13 |
14 |
15 |
16 |
17 |
18 |
19 | [](https://openupm.com/packages/com.qonversion.unity/)
20 | [](https://qonversion.io)
21 |
22 |
23 | ## In-App Subscription Implementation & Management
24 |
25 |
26 |
27 |
28 |
29 |
30 | 1. Qonversion SDK provides three simple methods to manage subscriptions:
31 | * Get in-app product details
32 | * Make purchases
33 | * Check subscription status to manage premium access
34 | 2. Qonversion communicates with Apple or Google platforms both through SDK and server-side to process native in-app payments and keep subscription statuses up to date.
35 | 3. You can use Qonversion webhooks and API in addition to SDK to get user-level data where you need it.
36 |
37 | See the [quick start guide documentation](https://documentation.qonversion.io/docs/quickstart).
38 |
39 | ## Analytics
40 |
41 | Qonversion provides advanced subscription analytics out-of-the-box. You can monitor real-time metrics from new users and trial-to-paid conversions to revenue, MRR, ARR, cohort retention and more. Understand your customers and make better decisions with precise subscription analytics.
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | ## A/B Experiments
50 |
51 | Qonversion's A/B Experiments feature provides everything required to quickly launch paywall and other monetization experiments, analyze results and roll out winning versions without releasing a new app build. Qonversion A/B Experiments include:
52 |
53 | * User segmentation by country, install date, app version, free/paying user
54 | * Traffic allocation
55 | * Advanced subscription analytics
56 | * Visualization of A/B experiments results
57 | * Statistical significance of the results
58 | * Roll out winning versions without app release with remote config
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | See more details [here](https://documentation.qonversion.io/docs/paywall-experiments).
67 |
68 | ## Integrations
69 |
70 | Send user-level subscription data to your favorite platforms.
71 |
72 | * Amplitude
73 | * Mixpanel
74 | * Appsflyer
75 | * Adjust
76 | * Singular
77 | * CleverTap
78 | * [All other integrations here](qonversion.io/integrations)
79 |
80 |
81 |
82 |
83 |
84 |
85 | ## Why Qonversion?
86 |
87 | * **No headaches with Apple's StoreKit & Google Billing.** Qonversion provides simple methods to handle Apple StoreKit & Google Billing purchase flow.
88 | * **Receipt validation.** Qonversion validates user receipts with Apple and Google to provide 100% accurate purchase information and subscription statuses. It also prevents unauthorized access to the premium features of your app.
89 | * **Track and increase your revenue.** Qonversion provides detailed real-time revenue analytics including cohort analysis, trial conversion rates, country segmentation, and much more.
90 | * **Integrations with the leading mobile platforms.** Qonversion allows sending data to platforms like AppsFlyer, Adjust, Branch, Tenjin, Facebook Ads, Amplitude, Mixpanel, and many others.
91 | * **Change promoted in-app products.** Change promoted in-app products anytime without app releases.
92 | * **A/B test** and identify winning in-app purchases, subscriptions or paywals.
93 | * **Cross-device and cross-platform access management.** If you provide user authorization in your app, you can easily set Qonversion to provide premium access to authorized users across devices and operating systems.
94 | * **SDK caches the data.** Qonversion SDK caches purchase data including in-app products and entitlements, so the user experience is not affected even with the slow or interrupting network connection.
95 | * **Webhooks.** You can easily send all of the data to your server with Qonversion webhooks.
96 | * **Customer support.** You can always reach out to our customer support and get the help required.
97 |
98 | Convinced? Let's go!
99 |
100 | ## Documentation
101 |
102 | Check the [full documentation](https://documentation.qonversion.io/docs/quickstart) to learn about implementation details and available features.
103 |
104 | #### Help us improve the documentation
105 |
106 | Whether you’re a core user or trying it out for the first time, you can make a valuable contribution to Qonversion by improving the documentation. Help us by:
107 |
108 | * sending us feedback about something you thought was confusing or simply missing
109 | * sending us a pull request via GitHub
110 | * suggesting better wording or ways of explaining certain topics in the [Qonversion documentation](http://documentation.qonversion.io). Use `SUGGEST EDITS` button in the top right corner.
111 |
112 | ## Contributing
113 |
114 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
115 |
116 | 1. Fork the Project
117 | 2. Create your Feature Branch (`git checkout -b feature/SuperFeature`)
118 | 3. Commit your Changes. Use small commits with separate logic. (`git commit -m 'Add some super feature'`)
119 | 4. Push to the Branch (`git push origin feature/SuperFeature`)
120 | 5. Open a Pull Request
121 |
122 |
123 | ## Have a question?
124 |
125 | Contact us via [issues on GitHub](https://github.com/qonversion/unity-sdk/issues) or [ask a question](https://documentation.qonversion.io/discuss-new) on the site.
126 |
127 | ## License
128 |
129 | Qonversion SDK is available under the MIT license.
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5a66fc8572b164d4da7665448ad88ea5
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 76f61b2fdd3f42d4a83f044b683016db
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Android.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 68d19869c54f9764d855135c11d2ab00
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Android/AutomationsWrapperAndroid.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace QonversionUnity
4 | {
5 | internal class AutomationsWrapperAndroid : IAutomationsWrapper
6 | {
7 | public void Initialize(string gameObjectName)
8 | {
9 | CallAutomations("initialize", gameObjectName);
10 | }
11 |
12 | public void SetNotificationsToken(string token)
13 | {
14 | CallAutomations("setNotificationsToken", token);
15 | }
16 |
17 | public bool HandleNotification(string notification)
18 | {
19 | return CallAutomations("handleNotification", notification);
20 | }
21 |
22 | public string GetNotificationCustomPayload(string notification)
23 | {
24 | return CallAutomations("getNotificationCustomPayload", notification);
25 | }
26 |
27 | public void SubscribeOnAutomationEvents()
28 | {
29 | CallAutomations("subscribeOnAutomationEvents");
30 | }
31 |
32 | public void ShowScreen(string screenId, string callbackName)
33 | {
34 | CallAutomations("showScreen", screenId, callbackName);
35 | }
36 |
37 | public void SetScreenPresentationConfig(string configJson, string screenId)
38 | {
39 | CallAutomations("setScreenPresentationConfig", configJson, screenId);
40 | }
41 |
42 | private const string AutomationsWrapper = "com.qonversion.unitywrapper.AutomationsWrapper";
43 |
44 | private static T CallAutomations(string methodName, params object[] args)
45 | {
46 | using (var automations = new AndroidJavaClass(AutomationsWrapper))
47 | {
48 | return automations.CallStatic(methodName, args);
49 | }
50 | }
51 |
52 | private static void CallAutomations(string methodName, params object[] args)
53 | {
54 | using (var automations = new AndroidJavaClass(AutomationsWrapper))
55 | {
56 | automations.CallStatic(methodName, args);
57 | }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/Runtime/Android/AutomationsWrapperAndroid.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bf1469979a8544c5b531368ea34cec2f
3 | timeCreated: 1668776137
--------------------------------------------------------------------------------
/Runtime/Android/Plugins.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d7df7b917c788e84aaff9c56bab04ced
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a28459d5e109a944794b5a7a64aaabcd
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: dcef5ddb5c68df540ae5468498f4a949
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 06b40e5048253d04ab06b66f9d2452d2
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java:
--------------------------------------------------------------------------------
1 | package com.qonversion.unitywrapper;
2 |
3 | import android.util.Log;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.annotation.Nullable;
7 |
8 | import com.fasterxml.jackson.core.JsonProcessingException;
9 | import com.fasterxml.jackson.core.type.TypeReference;
10 | import com.fasterxml.jackson.databind.ObjectMapper;
11 | import com.fasterxml.jackson.databind.node.ObjectNode;
12 |
13 | import org.jetbrains.annotations.NotNull;
14 |
15 | import java.util.HashMap;
16 | import java.util.Map;
17 |
18 | import io.qonversion.sandwich.AutomationsEventListener;
19 | import io.qonversion.sandwich.AutomationsSandwich;
20 | import io.qonversion.sandwich.ResultListener;
21 | import io.qonversion.sandwich.SandwichError;
22 |
23 | @SuppressWarnings("UnnecessaryLocalVariable")
24 | public class AutomationsWrapper {
25 | private static final String EVENT_SCREEN_SHOWN = "OnAutomationsScreenShown";
26 | private static final String EVENT_ACTION_STARTED = "OnAutomationsActionStarted";
27 | private static final String EVENT_ACTION_FAILED = "OnAutomationsActionFailed";
28 | private static final String EVENT_ACTION_FINISHED = "OnAutomationsActionFinished";
29 | private static final String EVENT_AUTOMATIONS_FINISHED = "OnAutomationsFinished";
30 |
31 | public static String TAG = "AutomationsDelegate";
32 | private static MessageSender messageSender;
33 | private static AutomationsSandwich automationsSandwich;
34 |
35 | public static synchronized void initialize(String unityListener) {
36 | messageSender = new MessageSender(unityListener);
37 | automationsSandwich = new AutomationsSandwich();
38 | }
39 |
40 | public static synchronized void subscribeOnAutomationEvents() {
41 | automationsSandwich.setDelegate(new EventListener());
42 | }
43 |
44 | public static synchronized void setNotificationsToken(String token) {
45 | automationsSandwich.setNotificationToken(token);
46 | }
47 |
48 | public static synchronized boolean handleNotification(String notification) {
49 | try {
50 | ObjectMapper mapper = new ObjectMapper();
51 |
52 | TypeReference> typeRef
53 | = new TypeReference>() {
54 | };
55 | Map notificationInfo = mapper.readValue(notification, typeRef);
56 |
57 | boolean result = automationsSandwich.handleNotification(notificationInfo);
58 |
59 | return result;
60 | } catch (Exception e) {
61 | return false;
62 | }
63 | }
64 |
65 | @Nullable
66 | public static synchronized String getNotificationCustomPayload(String notification) {
67 | try {
68 | final ObjectMapper mapper = new ObjectMapper();
69 |
70 | final TypeReference> typeRef
71 | = new TypeReference>() {
72 | };
73 | final Map notificationInfo = mapper.readValue(notification, typeRef);
74 |
75 | final Map payload = automationsSandwich.getNotificationCustomPayload(notificationInfo);
76 | final String json = mapper.writeValueAsString(payload);
77 |
78 | return json;
79 | } catch (Exception e) {
80 | return null;
81 | }
82 | }
83 |
84 | public static synchronized void showScreen(String screenId, String unityCallbackName) {
85 | automationsSandwich.showScreen(screenId, new ResultListener() {
86 | @Override
87 | public void onSuccess(@NonNull Map data) {
88 | sendMessageToUnity(data, unityCallbackName);
89 | }
90 |
91 | @Override
92 | public void onError(@NonNull SandwichError error) {
93 | handleErrorResponse(error, unityCallbackName);
94 | }
95 | });
96 | }
97 |
98 | public static synchronized void setScreenPresentationConfig(String configJson, @Nullable String screenId) {
99 | try {
100 | ObjectMapper mapper = new ObjectMapper();
101 |
102 | TypeReference> typeRef
103 | = new TypeReference>() {};
104 | Map configData = mapper.readValue(configJson, typeRef);
105 |
106 | automationsSandwich.setScreenPresentationConfig(configData, screenId);
107 | } catch (JsonProcessingException e) {
108 | handleSerializationException(e);
109 | }
110 | }
111 |
112 | private static void handleErrorResponse(@NotNull SandwichError error, @NotNull String methodName) {
113 | final ObjectNode rootNode = Utils.createErrorNode(error);
114 |
115 | sendMessageToUnity(rootNode, methodName);
116 | }
117 |
118 | static class EventListener implements AutomationsEventListener {
119 | @Override
120 | public void onAutomationEvent(@NonNull Event event, @Nullable Map data) {
121 | String methodName;
122 | switch (event) {
123 | case ScreenShown:
124 | methodName = EVENT_SCREEN_SHOWN;
125 | break;
126 | case ActionStarted:
127 | methodName = EVENT_ACTION_STARTED;
128 | break;
129 | case ActionFinished:
130 | methodName = EVENT_ACTION_FINISHED;
131 | break;
132 | case ActionFailed:
133 | methodName = EVENT_ACTION_FAILED;
134 | break;
135 | case AutomationsFinished:
136 | methodName = EVENT_AUTOMATIONS_FINISHED;
137 | break;
138 | default:
139 | return;
140 | }
141 |
142 | sendMessageToUnity(data == null ? new HashMap<>() : data, methodName);
143 | }
144 | }
145 |
146 | private static void sendMessageToUnity(@NotNull Object objectToConvert, @NotNull String methodName) {
147 | try {
148 | messageSender.sendMessageToUnity(objectToConvert, methodName);
149 | } catch (JsonProcessingException e) {
150 | handleException(e);
151 | }
152 | }
153 |
154 | private static void handleException(Exception e) {
155 | Log.e(TAG, "An error occurred while processing automations flow: " + e.getLocalizedMessage());
156 | }
157 |
158 | private static void handleSerializationException(JsonProcessingException e) {
159 | Log.e(TAG, "An error occurred while serializing data: " + e.getLocalizedMessage());
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c343db7cc54e542d39f73bd2228012e6
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Android: Android
16 | second:
17 | enabled: 1
18 | settings: {}
19 | - first:
20 | Any:
21 | second:
22 | enabled: 0
23 | settings: {}
24 | - first:
25 | Editor: Editor
26 | second:
27 | enabled: 0
28 | settings:
29 | DefaultValueInitialized: true
30 | userData:
31 | assetBundleName:
32 | assetBundleVariant:
33 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/MessageSender.java:
--------------------------------------------------------------------------------
1 | package com.qonversion.unitywrapper;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.unity3d.player.UnityPlayer;
6 |
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public class MessageSender {
10 | private final String unityListenerName;
11 |
12 | public MessageSender(String unityListenerName) {
13 | this.unityListenerName = unityListenerName;
14 | }
15 |
16 | void sendMessageToUnity(@NotNull Object objectToConvert, @NotNull String methodName) throws JsonProcessingException {
17 | final ObjectMapper mapper = new ObjectMapper();
18 | final String json = mapper.writeValueAsString(objectToConvert);
19 | UnityPlayer.UnitySendMessage(unityListenerName, methodName, json);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/MessageSender.java.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 684884a01eddd4f10aa3ab971380605e
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Android: Android
16 | second:
17 | enabled: 1
18 | settings: {}
19 | - first:
20 | Any:
21 | second:
22 | enabled: 0
23 | settings: {}
24 | - first:
25 | Editor: Editor
26 | second:
27 | enabled: 0
28 | settings:
29 | DefaultValueInitialized: true
30 | userData:
31 | assetBundleName:
32 | assetBundleVariant:
33 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9b3bcac970bd57249a19f97cb4621515
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Android: Android
16 | second:
17 | enabled: 1
18 | settings: {}
19 | - first:
20 | Any:
21 | second:
22 | enabled: 0
23 | settings: {}
24 | - first:
25 | Editor: Editor
26 | second:
27 | enabled: 0
28 | settings:
29 | DefaultValueInitialized: true
30 | userData:
31 | assetBundleName:
32 | assetBundleVariant:
33 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java:
--------------------------------------------------------------------------------
1 | package com.qonversion.unitywrapper;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.fasterxml.jackson.databind.node.ObjectNode;
5 |
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import io.qonversion.sandwich.SandwichError;
10 |
11 | public class Utils {
12 |
13 | public static ObjectNode createErrorNode(@NotNull SandwichError error) {
14 | return createErrorNode(error.getCode(), error.getDescription(), error.getAdditionalMessage());
15 | }
16 |
17 | public static ObjectNode createErrorNode(String code, String description, @Nullable String additionalMessage) {
18 | ObjectMapper mapper = new ObjectMapper();
19 | ObjectNode errorNode = mapper.createObjectNode();
20 | errorNode.put("code", code);
21 | errorNode.put("description", description);
22 | if (additionalMessage != null) {
23 | errorNode.put("additionalMessage", additionalMessage);
24 | }
25 |
26 | ObjectNode rootNode = mapper.createObjectNode();
27 | rootNode.set("error", errorNode);
28 | return rootNode;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1b5c0dd49367425db4e808bbc38580bf
3 | timeCreated: 1670833335
--------------------------------------------------------------------------------
/Runtime/Android/QonversionWrapperAndroid.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ac748a0eedddf7f48bf78bd60d0d8b40
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Common.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9f8f248a64639f24d88b5cf8823ed8e0
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Common/MiniJSON.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fae5ccf0682f6754ea6da63d7ffe7e54
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Common/MiniJSON/Json.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9d3ee7b76aed97e4a94ba457376993fd
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Common/MiniJSON/MiniJsonExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity.MiniJSON
5 | {
6 | public static class MiniJsonExtensions
7 | {
8 | public static Dictionary GetHash(this Dictionary dic, string key)
9 | {
10 | return (Dictionary)dic[key];
11 | }
12 |
13 | public static T GetEnum(this Dictionary dic, string key)
14 | {
15 | if (dic.ContainsKey(key))
16 | {
17 | return (T)Enum.Parse(typeof(T), dic[key].ToString(), ignoreCase: true);
18 | }
19 | return default(T);
20 | }
21 |
22 | public static string GetString(this Dictionary dic, string key, string defaultValue = "")
23 | {
24 | if (dic.ContainsKey(key))
25 | {
26 | return dic[key].ToString();
27 | }
28 | return defaultValue;
29 | }
30 |
31 | public static long GetLong(this Dictionary dic, string key)
32 | {
33 | if (dic.ContainsKey(key))
34 | {
35 | return long.Parse(dic[key].ToString());
36 | }
37 | return 0L;
38 | }
39 |
40 | public static List GetStringList(this Dictionary dic, string key)
41 | {
42 | if (dic.ContainsKey(key))
43 | {
44 | List list = new List();
45 | List list2 = (List)dic[key];
46 | foreach (object item in list2)
47 | {
48 | list.Add(item.ToString());
49 | }
50 | return list;
51 | }
52 | return new List();
53 | }
54 |
55 | public static bool GetBool(this Dictionary dic, string key)
56 | {
57 | if (dic.ContainsKey(key))
58 | {
59 | return bool.Parse(dic[key].ToString());
60 | }
61 | return false;
62 | }
63 |
64 | public static T Get(this Dictionary dic, string key)
65 | {
66 | if (dic.ContainsKey(key))
67 | {
68 | return (T)dic[key];
69 | }
70 | return default(T);
71 | }
72 |
73 | public static string toJson(this Dictionary obj)
74 | {
75 | return MiniJson.JsonEncode(obj);
76 | }
77 |
78 | public static string toJson(this Dictionary obj)
79 | {
80 | return MiniJson.JsonEncode(obj);
81 | }
82 |
83 | public static string toJson(this string[] array)
84 | {
85 | List list = new List();
86 | foreach (string item in array)
87 | {
88 | list.Add(item);
89 | }
90 | return MiniJson.JsonEncode(list);
91 | }
92 |
93 | public static List ArrayListFromJson(this string json)
94 | {
95 | return MiniJson.JsonDecode(json) as List;
96 | }
97 |
98 | public static Dictionary HashtableFromJson(this string json)
99 | {
100 | return MiniJson.JsonDecode(json) as Dictionary;
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Runtime/Common/MiniJSON/MiniJsonExtensions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9c6171f44828f1f4c9629916a99e6b32
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Common/MiniJson.cs:
--------------------------------------------------------------------------------
1 | using QonversionUnity.MiniJSON;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class MiniJson
6 | {
7 | public static string JsonEncode(object json)
8 | {
9 | return Json.Serialize(json);
10 | }
11 |
12 | public static object JsonDecode(string json)
13 | {
14 | return Json.Deserialize(json);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Runtime/Common/MiniJson.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5fe28a6970fb6864a9081f9e960ab07a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Qonversion.Unity.Sdk.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Qonversion.Unity.Sdk"
3 | }
4 |
--------------------------------------------------------------------------------
/Runtime/Qonversion.Unity.Sdk.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7997463b3dbb27245a8ff4616b271e67
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 43b724a4537ec484ab8c8e7d293af0e0
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Rider ignored files
5 | /.idea.Scripts.iml
6 | /projectSettingsUpdater.xml
7 | /contentModel.xml
8 | /modules.xml
9 | # Editor-based HTTP Client requests
10 | /httpRequests/
11 | # Datasource local storage ignored files
12 | /dataSources/
13 | /dataSources.local.xml
14 |
--------------------------------------------------------------------------------
/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/indexLayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Automations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public static class Automations
7 | {
8 | [CanBeNull] private static IAutomations _backingInstance;
9 |
10 | ///
11 | /// Use this variable to get a current initialized instance of the Qonversion Automations.
12 | /// Please, use Automations only after calling .
13 | /// Otherwise, trying to access the variable will cause an error.
14 | ///
15 | /// Current initialized instance of the Qonversion Automations.
16 | /// throws exception if Qonversion has not been initialized.
17 | public static IAutomations GetSharedInstance()
18 | {
19 | if (_backingInstance == null)
20 | {
21 | try
22 | {
23 | Qonversion.GetSharedInstance();
24 | }
25 | catch (Exception e)
26 | {
27 | throw new Exception("Qonversion has not been initialized. " +
28 | "Automations should be used after Qonversion is initialized.");
29 | }
30 |
31 | _backingInstance = AutomationsInternal.CreateInstance();
32 | }
33 |
34 | return _backingInstance;
35 | }
36 |
37 | public delegate void OnShowScreenResponseReceived(QonversionError error);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Automations.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fb9026ffe23714e4094aebd9d036c9c2
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6941a58d609fd49ffac95120213d64a3
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ActionResult.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class ActionResult
7 | {
8 | public readonly ActionResultType Type;
9 | [CanBeNull] public readonly Dictionary Parameters;
10 | [CanBeNull] public readonly QonversionError Error;
11 |
12 | public ActionResult(Dictionary dict)
13 | {
14 | if (dict.TryGetValue("error", out var rawError ) && rawError != null) Error = new QonversionError((Dictionary)rawError);
15 | if (dict.TryGetValue("value", out var rawParams) && rawParams != null) Parameters = (Dictionary)rawParams;
16 | if (dict.TryGetValue("type", out var actionType)) Type = FormatActionResultType(actionType);
17 | }
18 |
19 | public override string ToString()
20 | {
21 | return $"{nameof(Type)}: {Type}, " +
22 | $"{nameof(Parameters)}: {Parameters}, " +
23 | $"{nameof(Error)}: {Error}";
24 | }
25 |
26 | private ActionResultType FormatActionResultType(object type)
27 | {
28 | string value = type as string;
29 | ActionResultType result;
30 | switch (value)
31 | {
32 | case "url":
33 | result = ActionResultType.URL;
34 | break;
35 | case "deeplink":
36 | result = ActionResultType.Deeplink;
37 | break;
38 | case "navigate":
39 | result = ActionResultType.Navigation;
40 | break;
41 | case "purchase":
42 | result = ActionResultType.Purchase;
43 | break;
44 | case "restore":
45 | result = ActionResultType.Restore;
46 | break;
47 | case "close":
48 | result = ActionResultType.Close;
49 | break;
50 | default:
51 | result = ActionResultType.Unknown;
52 | break;
53 | }
54 |
55 | return result;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ActionResult.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e27480d33c0774d5f9f7ce5a1d7c6c56
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ActionResultType.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum ActionResultType
4 | {
5 | Unknown,
6 | URL,
7 | Deeplink,
8 | Navigation,
9 | Purchase,
10 | Restore,
11 | Close
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ActionResultType.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 25342fbb35e8a4dce81d44d56b414766
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AttributionProvider.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum AttributionProvider
4 | {
5 | AppsFlyer = 0,
6 | Branch,
7 | Adjust,
8 | AppleSearchAds, // ios only
9 | AppleAdServices // ios only
10 | }
11 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AttributionProvider.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4b91d281dc6374342b819965b3694d4e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AutomationsDelegate.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace QonversionUnity
4 | {
5 | ///
6 | /// Delegate fires each time an automations event happens
7 | ///
8 | public abstract class AutomationsDelegate : MonoBehaviour
9 | {
10 | ///
11 | /// Called when Automations screen is shown
12 | ///
13 | /// shown screen Id
14 | public abstract void OnAutomationsScreenShown(string screenId);
15 |
16 | ///
17 | /// Called when Automations flow starts executing an action
18 | ///
19 | /// executed action
20 | public abstract void OnAutomationsActionStarted(ActionResult actionResult);
21 |
22 | ///
23 | /// Called when Automations flow fails executing an action
24 | ///
25 | /// executed action
26 | public abstract void OnAutomationsActionFailed(ActionResult actionResult);
27 |
28 | ///
29 | /// Called when Automations flow finishes executing an action
30 | /// For instance, if the user made a purchase then action.type == QONActionResultTypePurchase
31 | /// Then you can use the method to get available permissions
32 | ///
33 | /// executed action
34 | public abstract void OnAutomationsActionFinished(ActionResult actionResult);
35 |
36 | ///
37 | /// Called when Automations flow is finished and the Automations screen is closed
38 | ///
39 | public abstract void OnAutomationsFinished();
40 | }
41 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AutomationsDelegate.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a59920bdf2fc14ac1a37e77eb3f4d7b2
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AutomationsEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class AutomationsEvent
7 | {
8 | public readonly AutomationsEventType Type;
9 | public readonly DateTime Date;
10 |
11 | public AutomationsEvent(Dictionary dict)
12 | {
13 | if (dict.TryGetValue("timestamp", out object time)) Date = Utils.FormatDate(Convert.ToInt64((double)time));
14 | if (dict.TryGetValue("type", out object eventType)) Type = FormatAutomationsEventType(eventType);
15 | }
16 |
17 | public override string ToString()
18 | {
19 | return $"{nameof(Type)}: {Type}, " +
20 | $"{nameof(Date)}: {Date}";
21 | }
22 |
23 | private AutomationsEventType FormatAutomationsEventType(object type)
24 | {
25 | string value = type as string;
26 | AutomationsEventType result;
27 | switch (value)
28 | {
29 | case "trial_started":
30 | result = AutomationsEventType.TrialStarted;
31 | break;
32 | case "trial_converted":
33 | result = AutomationsEventType.TrialConverted;
34 | break;
35 | case "trial_canceled":
36 | result = AutomationsEventType.TrialCanceled;
37 | break;
38 | case "trial_billing_retry_entered":
39 | result = AutomationsEventType.TrialBillingRetry;
40 | break;
41 | case "subscription_started":
42 | result = AutomationsEventType.SubscriptionStarted;
43 | break;
44 | case "subscription_renewed":
45 | result = AutomationsEventType.SubscriptionRenewed;
46 | break;
47 | case "subscription_refunded":
48 | result = AutomationsEventType.SubscriptionRefunded;
49 | break;
50 | case "subscription_canceled":
51 | result = AutomationsEventType.SubscriptionCanceled;
52 | break;
53 | case "subscription_billing_retry_entered":
54 | result = AutomationsEventType.SubscriptionBillingRetry;
55 | break;
56 | case "in_app_purchase":
57 | result = AutomationsEventType.InAppPurchase;
58 | break;
59 | case "subscription_upgraded":
60 | result = AutomationsEventType.SubscriptionUpgraded;
61 | break;
62 | case "trial_still_active":
63 | result = AutomationsEventType.TrialStillActive;
64 | break;
65 | case "trial_expired":
66 | result = AutomationsEventType.TrialExpired;
67 | break;
68 | case "subscription_expired":
69 | result = AutomationsEventType.SubscriptionExpired;
70 | break;
71 | case "subscription_downgraded":
72 | result = AutomationsEventType.SubscriptionDowngraded;
73 | break;
74 | case "subscription_product_changed":
75 | result = AutomationsEventType.SubscriptionProductChanged;
76 | break;
77 | default:
78 | result = AutomationsEventType.Unknown;
79 | break;
80 | }
81 |
82 | return result;
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AutomationsEvent.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 687d028d5e04c4ad88e7995bfbf808c0
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AutomationsEventType.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum AutomationsEventType
4 | {
5 | Unknown,
6 | TrialStarted,
7 | TrialConverted,
8 | TrialCanceled,
9 | TrialBillingRetry,
10 | SubscriptionStarted,
11 | SubscriptionRenewed,
12 | SubscriptionRefunded,
13 | SubscriptionCanceled,
14 | SubscriptionBillingRetry,
15 | InAppPurchase,
16 | SubscriptionUpgraded,
17 | TrialStillActive,
18 | TrialExpired,
19 | SubscriptionExpired,
20 | SubscriptionDowngraded,
21 | SubscriptionProductChanged
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/AutomationsEventType.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d069be0d69cf1482da59364bce07633d
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Eligibility.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class Eligibility
6 | {
7 | public readonly EligibilityStatus Status;
8 |
9 | public Eligibility(Dictionary dict)
10 | {
11 | if (dict.TryGetValue("status", out object value)) Status = FormatEligibilityStatus(value);
12 | }
13 |
14 | public override string ToString()
15 | {
16 | return $"{nameof(Status)}: {Status}";
17 | }
18 |
19 | private EligibilityStatus FormatEligibilityStatus(object status)
20 | {
21 | string value = status as string;
22 | EligibilityStatus result;
23 | switch (value)
24 | {
25 | case "non_intro_or_trial_product":
26 | result = EligibilityStatus.NonIntroOrTrialProduct;
27 | break;
28 | case "intro_or_trial_ineligible":
29 | result = EligibilityStatus.Ineligible;
30 | break;
31 | case "intro_or_trial_eligible":
32 | result = EligibilityStatus.Eligible;
33 | break;
34 | default:
35 | result = EligibilityStatus.Unknown;
36 | break;
37 | }
38 |
39 | return result;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Eligibility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e5734643decb54c5b891603130ab213e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/EligibilityStatus.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum EligibilityStatus
4 | {
5 | Unknown,
6 | NonIntroOrTrialProduct,
7 | Ineligible,
8 | Eligible
9 | }
10 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/EligibilityStatus.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eb95a37986ad54d139d16c3bc624e387
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Entitlement.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8721b4598de3343a28465afe8261afe7
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum EntitlementsCacheLifetime
4 | {
5 | Week,
6 | TwoWeeks,
7 | Month,
8 | TwoMonths,
9 | ThreeMonths,
10 | SixMonths,
11 | Year,
12 | Unlimited
13 | }
14 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7a565dd602ce74950a70927782a8f4fe
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Environment.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum Environment
4 | {
5 | Sandbox,
6 | Production
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Environment.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1b02fbe89ab349a59491d47e9ca2329d
3 | timeCreated: 1668682691
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Experiment.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class Experiment
6 | {
7 | public readonly string Id;
8 | public readonly string Name;
9 | public readonly ExperimentGroup Group;
10 |
11 |
12 | public Experiment(Dictionary dict)
13 | {
14 | if (dict.TryGetValue("id", out object value)) Id = value as string;
15 | if (dict.TryGetValue("name", out value)) Name = value as string;
16 | if (dict.TryGetValue("group", out value) && value is Dictionary group)
17 | {
18 | Group = new ExperimentGroup(group);
19 | }
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return $"{nameof(Id)}: {Id}, " +
25 | $"{nameof(Name)}: {Name}, " +
26 | $"{nameof(Group)}: {Group}";
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Experiment.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 26f8b4a30f24045028e51326a03fb1e9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ExperimentGroup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 |
5 | namespace QonversionUnity
6 | {
7 | public class ExperimentGroup
8 | {
9 | public readonly string Id;
10 | public readonly string Name;
11 | public readonly ExperimentGroupType Type;
12 |
13 | public ExperimentGroup(Dictionary dict)
14 | {
15 | if (dict.TryGetValue("id", out object value)) Id = value as string;
16 | if (dict.TryGetValue("name", out value)) Name = value as string;
17 | if (dict.TryGetValue("type", out value)) Type = FormatGroupType(value);
18 | }
19 |
20 | public ExperimentGroupType FormatGroupType(object typeValue)
21 | {
22 | string type = typeValue as string;
23 | if (type == "control")
24 | {
25 | return ExperimentGroupType.Control;
26 | }
27 | else if (type == "treatment")
28 | {
29 | return ExperimentGroupType.Treatment;
30 | }
31 |
32 | return ExperimentGroupType.Unknown;
33 | }
34 |
35 | public override string ToString()
36 | {
37 | return $"{nameof(Id)}: {Id}, " +
38 | $"{nameof(Name)}: {Name}, " +
39 | $"{nameof(Type)}: {Type}";
40 | }
41 | }
42 |
43 | public enum ExperimentGroupType
44 | {
45 | Unknown = -1,
46 | Control = 0,
47 | Treatment = 1
48 | }
49 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ExperimentGroup.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3bea57f1886414de79be7bf2ea23f74b
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/LaunchMode.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum LaunchMode
4 | {
5 | Analytics,
6 | SubscriptionManagement
7 | }
8 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/LaunchMode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 24dcbe0f097a40c59733cfbd46312398
3 | timeCreated: 1668682749
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Offering.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 | using UnityEngine.Scripting;
5 |
6 | namespace QonversionUnity
7 | {
8 | public class Offering
9 | {
10 | public readonly string Id;
11 | public readonly QOfferingTag Tag;
12 | public readonly List Products;
13 |
14 | // Informs compiler to save this method from removal via optimization,
15 | // as even if it has no direct calls, it is called via reflection while mapping.
16 | [Preserve]
17 | public Offering(Dictionary dict)
18 | {
19 | if (dict.TryGetValue("id", out object value)) Id = value as string;
20 | if (dict.TryGetValue("tag", out value)) Tag = FormatOfferingTag(value);
21 | if (dict.TryGetValue("products", out value))
22 | {
23 | if (value is List products) Products = Mapper.ConvertObjectsList(products);
24 | }
25 | }
26 |
27 | [CanBeNull]
28 | public Product ProductForID(string id)
29 | {
30 | return Products.Find(product => product.QonversionId == id);
31 | }
32 |
33 | public QOfferingTag FormatOfferingTag(object tag) =>
34 | (QOfferingTag)Convert.ToInt32(tag);
35 |
36 | public override string ToString()
37 | {
38 | return $"{nameof(Id)}: {Id}, " +
39 | $"{nameof(Tag)}: {Tag}, " +
40 | $"{nameof(Products)}: {Utils.PrintObjectList(Products)}";
41 | }
42 | }
43 |
44 | public enum QOfferingTag
45 | {
46 | Unknown = -1,
47 | None = 0,
48 | Main = 1
49 | }
50 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Offering.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ad8db728bf4fd489b8a8a65677f0089b
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Offerings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class Offerings
7 | {
8 | [CanBeNull] public readonly Offering Main;
9 | public readonly List AvailableOfferings;
10 |
11 | public Offerings(Dictionary dict)
12 | {
13 | if (dict.TryGetValue("main", out object value) && value is Dictionary offering)
14 | {
15 | Main = new Offering(offering);
16 | }
17 | if (dict.TryGetValue("availableOfferings", out value) && value is List offerings)
18 | {
19 | AvailableOfferings = Mapper.ConvertObjectsList(offerings);
20 | }
21 | }
22 |
23 | [CanBeNull]
24 | public Offering OfferingForID(string id)
25 | {
26 | return AvailableOfferings.Find(offering => offering.Id == id);
27 | }
28 |
29 | public override string ToString()
30 | {
31 | return $"{nameof(Main)}: {Main}, " +
32 | $"{nameof(AvailableOfferings)}: {Utils.PrintObjectList(AvailableOfferings)}";
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Offerings.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b48e5e74dc2dc416881ccb7e3030bc3e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Product.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f7fdfa6fc70dc4ac08162a1886f1539a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9fbc1f954cf3c4c02b065ab4eccdc1ac
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/PricingPhaseRecurrenceMode.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | ///
4 | /// Recurrence mode of the pricing phase.
5 | ///
6 | public enum PricingPhaseRecurrenceMode
7 | {
8 | /// The billing plan payment recurs for infinite billing periods unless canceled.
9 | InfiniteRecurring,
10 |
11 | /// The billing plan payment recurs for a fixed number of billing periods
12 | /// set in .
13 | FiniteRecurring,
14 |
15 | /// The billing plan payment is a one-time charge that does not repeat.
16 | NonRecurring,
17 |
18 | /// Unknown recurrence mode.
19 | Unknown,
20 | }
21 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/PricingPhaseRecurrenceMode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c9d02b7b4c0a14d14840c161828aea94
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/PricingPhaseType.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | ///
4 | /// Type of the pricing phase.
5 | ///
6 | public enum PricingPhaseType
7 | {
8 | /// Regular subscription without any discounts like trial or intro offers.
9 | Regular,
10 |
11 | /// A free phase.
12 | FreeTrial,
13 |
14 | /// A phase with a discounted payment for a single period.
15 | DiscountedSinglePayment,
16 |
17 | /// A phase with a discounted payment for several periods, described in .
18 | DiscountedRecurringPayment,
19 |
20 | /// Unknown pricing phase type.
21 | Unknown,
22 | }
23 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/PricingPhaseType.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 65730d53808e4455d9c80ab2981353fa
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductInAppDetails.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity
5 | {
6 | ///
7 | /// This class contains all the information about the Google in-app product details.
8 | ///
9 | public class ProductInAppDetails
10 | {
11 | /// The price of the in-app product.
12 | public readonly ProductPrice Price;
13 |
14 | public ProductInAppDetails(Dictionary dict)
15 | {
16 | if (dict.TryGetValue("price", out object value) && value is Dictionary price)
17 | {
18 | Price = new ProductPrice(price);
19 | }
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return $"{nameof(Price)}: {Price}";
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductInAppDetails.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8f770c2c584a6456baee470c99f6f44d
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductInstallmentPlanDetails.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity
5 | {
6 | ///
7 | /// This class represents the details about the installment plan for a subscription product.
8 | ///
9 | public class ProductInstallmentPlanDetails
10 | {
11 | /// Committed payments count after a user signs up for this subscription plan.
12 | public readonly int CommitmentPaymentsCount;
13 |
14 | /// Subsequent committed payments count after this subscription plan renews.
15 | ///
16 | /// Returns 0 if the installment plan doesn't have any subsequent commitment,
17 | /// which means this subscription plan will fall back to a normal
18 | /// non-installment monthly plan when the plan renews.
19 | public readonly int SubsequentCommitmentPaymentsCount;
20 |
21 | public ProductInstallmentPlanDetails(Dictionary dict)
22 | {
23 | if (dict.TryGetValue("commitmentPaymentsCount", out object value)) CommitmentPaymentsCount = (int)(long)value;
24 | if (dict.TryGetValue("subsequentCommitmentPaymentsCount", out value)) SubsequentCommitmentPaymentsCount = (int)(long)value;
25 | }
26 |
27 | public override string ToString()
28 | {
29 | return $"{nameof(CommitmentPaymentsCount)}: {CommitmentPaymentsCount}, " +
30 | $"{nameof(SubsequentCommitmentPaymentsCount)}: {SubsequentCommitmentPaymentsCount}";
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductInstallmentPlanDetails.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e15d639930374a54829f77585619d381
3 | timeCreated: 1719504789
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductOfferDetails.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using JetBrains.Annotations;
4 |
5 | namespace QonversionUnity
6 | {
7 | ///
8 | /// This class contains all the information about the Google subscription offer details.
9 | /// It might be either a plain base plan details or a base plan with the concrete offer details.
10 | ///
11 | public class ProductOfferDetails
12 | {
13 | /// The identifier of the current base plan.
14 | public readonly string BasePlanId;
15 |
16 | /// The identifier of the concrete offer, to which these details belong.
17 | /// Null, if these are plain base plan details.
18 | [CanBeNull] public readonly string OfferId;
19 |
20 | /// A token to purchase the current offer.
21 | public readonly string OfferToken;
22 |
23 | /// List of tags set for the current offer.
24 | public readonly string[] Tags;
25 |
26 | /// A time-ordered list of pricing phases for the current offer.
27 | public readonly ProductPricingPhase[] PricingPhases;
28 |
29 | /// A base plan phase details.
30 | [CanBeNull] public readonly ProductPricingPhase BasePlan;
31 |
32 | /// Additional details of an installment plan, if exists.
33 | [CanBeNull] public readonly ProductInstallmentPlanDetails InstallmentPlanDetails;
34 |
35 | /// A trial phase details, if exists.
36 | [CanBeNull] public readonly ProductPricingPhase IntroPhase;
37 |
38 | /// An intro phase details, if exists.
39 | /// The intro phase is one of single or recurrent discounted payments.
40 | [CanBeNull] public readonly ProductPricingPhase TrialPhase;
41 |
42 | /// True, if there is a trial phase in the current offer. False otherwise.
43 | public readonly bool HasTrial;
44 |
45 | /// True, if there is any intro phase in the current offer. False otherwise.
46 | /// The intro phase is one of single or recurrent discounted payments.
47 | public readonly bool HasIntro;
48 |
49 | /// True, if there is any trial or intro phase in the current offer. False otherwise.
50 | /// The intro phase is one of single or recurrent discounted payments.
51 | public readonly bool HasTrialOrIntro;
52 |
53 | public ProductOfferDetails(Dictionary dict)
54 | {
55 | if (dict.TryGetValue("basePlanId", out object value)) BasePlanId = value as string;
56 | if (dict.TryGetValue("offerId", out value)) OfferId = value as string;
57 | if (dict.TryGetValue("offerToken", out value)) OfferToken = value as string;
58 | if (dict.TryGetValue("tags", out value) && value is List tags) {
59 | List result = new List();
60 | foreach (object tag in tags)
61 | {
62 | result.Add(tag.ToString());
63 | }
64 |
65 | Tags = result.ToArray();
66 | }
67 |
68 | if (dict.TryGetValue("pricingPhases", out value) && value is List pricingPhases)
69 | {
70 | List result = new List();
71 | foreach (object pricingPhase in pricingPhases)
72 | {
73 | if (pricingPhase is Dictionary)
74 | {
75 | ProductPricingPhase phase = new ProductPricingPhase(pricingPhase as Dictionary);
76 | result.Add(phase);
77 | }
78 | }
79 |
80 | PricingPhases = result.ToArray();
81 | }
82 |
83 | if (dict.TryGetValue("basePlan", out value) && value is Dictionary basePlan)
84 | {
85 | BasePlan = new ProductPricingPhase(basePlan);
86 | }
87 |
88 | if (dict.TryGetValue("installmentPlanDetails", out value) && value is Dictionary installmentPlan)
89 | {
90 | InstallmentPlanDetails = new ProductInstallmentPlanDetails(installmentPlan);
91 | }
92 |
93 | if (dict.TryGetValue("introPhase", out value) && value is Dictionary introPhase)
94 | {
95 | IntroPhase = new ProductPricingPhase(introPhase);
96 | }
97 |
98 | if (dict.TryGetValue("trialPhase", out value) && value is Dictionary trialPhase)
99 | {
100 | TrialPhase = new ProductPricingPhase(trialPhase);
101 | }
102 |
103 | if (dict.TryGetValue("hasTrial", out value)) HasTrial = (bool)value;
104 | if (dict.TryGetValue("hasIntro", out value)) HasIntro = (bool)value;
105 | if (dict.TryGetValue("hasTrialOrIntro", out value)) HasTrialOrIntro = (bool)value;
106 | }
107 |
108 | public override string ToString()
109 | {
110 | string tags = "";
111 | if (Tags != null)
112 | {
113 | tags = string.Join(", ", Tags.Select(tag => tag));
114 | }
115 |
116 | string pricingPhases = "";
117 | if (PricingPhases != null)
118 | {
119 | pricingPhases = string.Join(", ", PricingPhases.Select(phase => phase.ToString()));
120 | }
121 |
122 | return $"{nameof(BasePlanId)}: {BasePlanId}, " +
123 | $"{nameof(OfferId)}: {OfferId}, " +
124 | $"{nameof(OfferToken)}: {OfferToken}, " +
125 | $"{nameof(Tags)}: {tags}, " +
126 | $"{nameof(PricingPhases)}: {pricingPhases}, " +
127 | $"{nameof(BasePlan)}: {BasePlan}, " +
128 | $"{nameof(InstallmentPlanDetails)}: {InstallmentPlanDetails}, " +
129 | $"{nameof(IntroPhase)}: {IntroPhase}, " +
130 | $"{nameof(TrialPhase)}: {TrialPhase}, " +
131 | $"{nameof(HasTrial)}: {HasTrial}, " +
132 | $"{nameof(HasIntro)}: {HasIntro}, " +
133 | $"{nameof(HasTrialOrIntro)}: {HasTrialOrIntro}";
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductOfferDetails.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b389bf1726051461b97d14e1220443a1
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductPrice.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | ///
7 | /// Information about the Google product's price.
8 | ///
9 | public class ProductPrice
10 | {
11 | /// Total amount of money in micro-units,
12 | /// where 1,000,000 micro-units equal one unit of the currency.
13 | public readonly long PriceAmountMicros;
14 |
15 | /// ISO 4217 currency code for price.
16 | public readonly string PriceCurrencyCode;
17 |
18 | /// Formatted price for the payment, including its currency sign.
19 | public readonly string FormattedPrice;
20 |
21 | /// True, if the price is zero. False otherwise.
22 | public readonly bool IsFree;
23 |
24 | /// Price currency symbol. Null if failed to parse.
25 | [CanBeNull] public readonly string CurrencySymbol;
26 |
27 | public ProductPrice(Dictionary dict)
28 | {
29 | if (dict.TryGetValue("priceAmountMicros", out object value)) PriceAmountMicros = (long)value;
30 | if (dict.TryGetValue("priceCurrencyCode", out value)) PriceCurrencyCode = value as string;
31 | if (dict.TryGetValue("formattedPrice", out value)) FormattedPrice = value as string;
32 | if (dict.TryGetValue("isFree", out value)) IsFree = (bool)value;
33 | if (dict.TryGetValue("currencySymbol", out value)) CurrencySymbol = value as string;
34 | }
35 |
36 | public override string ToString()
37 | {
38 | return $"{nameof(PriceAmountMicros)}: {PriceAmountMicros}, " +
39 | $"{nameof(PriceCurrencyCode)}: {PriceCurrencyCode}, " +
40 | $"{nameof(FormattedPrice)}: {FormattedPrice}, " +
41 | $"{nameof(IsFree)}: {IsFree}, " +
42 | $"{nameof(CurrencySymbol)}: {CurrencySymbol}";
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductPrice.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a1fcbbb07eb2b4740ac8528874738326
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductPricingPhase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace QonversionUnity
4 | {
5 | ///
6 | /// This class represents a pricing phase, describing how a user pays at a point in time.
7 | ///
8 | public class ProductPricingPhase
9 | {
10 | /// Price for the current phase.
11 | public readonly ProductPrice Price;
12 |
13 | /// The billing period for which the given price applies.
14 | public readonly SubscriptionPeriod BillingPeriod;
15 |
16 | /// Number of cycles for which the billing period is applied.
17 | public readonly int BillingCycleCount;
18 |
19 | /// Recurrence mode for the pricing phase.
20 | public readonly PricingPhaseRecurrenceMode RecurrenceMode;
21 |
22 | /// Type of the pricing phase.
23 | public readonly PricingPhaseType Type;
24 |
25 | /// True, if the current phase is a trial period. False otherwise.
26 | public readonly bool IsTrial;
27 |
28 | /// True, if the current phase is an intro period. False otherwise.
29 | /// The intro phase is one of single or recurrent discounted payments.
30 | public readonly bool IsIntro;
31 |
32 | /// True, if the current phase represents the base plan. False otherwise.
33 | public readonly bool IsBasePlan;
34 |
35 | public ProductPricingPhase(Dictionary dict)
36 | {
37 | if (dict.TryGetValue("price", out object value) && value is Dictionary price)
38 | {
39 | Price = new ProductPrice(price);
40 | }
41 |
42 | if (dict.TryGetValue("billingPeriod", out value) && value is Dictionary billingPeriod)
43 | {
44 | BillingPeriod = new SubscriptionPeriod(billingPeriod);
45 | }
46 |
47 | if (dict.TryGetValue("billingCycleCount", out value)) BillingCycleCount = (int)(long)value;
48 | if (dict.TryGetValue("recurrenceMode", out value)) RecurrenceMode = FormatRecurrenceMode(value);
49 | if (dict.TryGetValue("type", out value)) Type = FormatType(value);
50 | if (dict.TryGetValue("isTrial", out value)) IsTrial = (bool)value;
51 | if (dict.TryGetValue("isIntro", out value)) IsIntro = (bool)value;
52 | if (dict.TryGetValue("isBasePlan", out value)) IsBasePlan = (bool)value;
53 | }
54 |
55 | private PricingPhaseType FormatType(object typeValue)
56 | {
57 | string type = typeValue as string;
58 | switch (type)
59 | {
60 | case "Regular": return PricingPhaseType.Regular;
61 | case "FreeTrial": return PricingPhaseType.FreeTrial;
62 | case "DiscountedSinglePayment": return PricingPhaseType.DiscountedSinglePayment;
63 | case "DiscountedRecurringPayment": return PricingPhaseType.DiscountedRecurringPayment;
64 | default: return PricingPhaseType.Unknown;
65 | }
66 | }
67 |
68 | private PricingPhaseRecurrenceMode FormatRecurrenceMode(object recurrenceModeValue)
69 | {
70 | string recurrenceMode = recurrenceModeValue as string;
71 | switch (recurrenceMode) {
72 | case "InfiniteRecurring": return PricingPhaseRecurrenceMode.InfiniteRecurring;
73 | case "FiniteRecurring": return PricingPhaseRecurrenceMode.FiniteRecurring;
74 | case "NonRecurring": return PricingPhaseRecurrenceMode.NonRecurring;
75 | default: return PricingPhaseRecurrenceMode.Unknown;
76 | }
77 | }
78 |
79 | public override string ToString()
80 | {
81 | return $"{nameof(Price)}: {Price}, " +
82 | $"{nameof(BillingPeriod)}: {BillingPeriod}, " +
83 | $"{nameof(BillingCycleCount)}: {BillingCycleCount}, " +
84 | $"{nameof(RecurrenceMode)}: {RecurrenceMode}, " +
85 | $"{nameof(Type)}: {Type}, " +
86 | $"{nameof(IsTrial)}: {IsTrial}, " +
87 | $"{nameof(IsIntro)}: {IsIntro}, " +
88 | $"{nameof(IsBasePlan)}: {IsBasePlan}";
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductPricingPhase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 129d13ec7f81348fb8a969e8f187c91a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductStoreDetails/ProductStoreDetails.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1aed806485ecb43eab6a4f2681282904
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductType.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum QProductType
4 | {
5 | /// Provides access to content on a recurring basis with a free offer
6 | Trial,
7 | /// Provides access to content on a recurring basis with an introductory offer
8 | /// Currently works for Android only. iOS support will be added soon.
9 | Intro,
10 | /// Provides access to content on a recurring basis
11 | Subscription,
12 | /// Content that users can purchase with a single, non-recurring charge
13 | InApp,
14 | /// Unknown product type
15 | Unknown,
16 | }
17 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ProductType.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8243ed1d06a04a3a9affcba77e8e2b98
3 | timeCreated: 1701454390
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PromotionalOffer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class PromotionalOffer
6 | {
7 | public readonly SKProductDiscount ProductDiscount;
8 | public readonly SKPaymentDiscount PaymentDiscount;
9 |
10 | public PromotionalOffer(Dictionary dict)
11 | {
12 | if (dict.TryGetValue("productDiscount", out object value) && value is Dictionary productDiscount)
13 | {
14 | ProductDiscount = new SKProductDiscount(productDiscount);
15 | }
16 | if (dict.TryGetValue("paymentDiscount", out value) && value is Dictionary paymentDiscount)
17 | {
18 | PaymentDiscount = new SKPaymentDiscount(paymentDiscount);
19 | }
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return $"{nameof(ProductDiscount)}: {ProductDiscount}, " +
25 | $"{nameof(PaymentDiscount)}: {PaymentDiscount}";
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PromotionalOffer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f3b6b8019f7640c7840cc65821a1d7a4
3 | timeCreated: 1732029067
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseModel.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace QonversionUnity
4 | {
5 | ///
6 | /// Used to provide all the necessary purchase data to the method.
7 | /// Can be created manually or using the method.
8 | ///
9 | /// If is not specified for Android, then the default offer will be applied.
10 | /// To know how we choose the default offer, see .
11 | ///
12 | /// If you want to remove any intro/trial offer from the purchase on Android (use only a bare base plan),
13 | /// call the method.
14 | ///
15 | public class PurchaseModel
16 | {
17 | public readonly string ProductId;
18 | [CanBeNull] public string OfferId;
19 |
20 | internal bool ApplyOffer = true;
21 |
22 | public PurchaseModel(string productId, [CanBeNull] string offerId = null)
23 | {
24 | ProductId = productId;
25 | OfferId = offerId;
26 | }
27 |
28 | public PurchaseModel RemoveOffer()
29 | {
30 | ApplyOffer = false;
31 | return this;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseModel.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d23e34be58ec4d1aae93cd7de23b3825
3 | timeCreated: 1701455044
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using JetBrains.Annotations;
4 |
5 | namespace QonversionUnity
6 | {
7 | public class PurchaseOptions
8 | {
9 | [CanBeNull] public readonly string OfferId;
10 |
11 | public readonly bool ApplyOffer;
12 |
13 | [CanBeNull] public readonly Product OldProduct;
14 |
15 | [CanBeNull] public readonly PurchaseUpdatePolicy? UpdatePolicy;
16 |
17 | [CanBeNull] public readonly List ContextKeys;
18 |
19 | public readonly int Quantity;
20 |
21 | [CanBeNull] public readonly PromotionalOffer PromotionalOffer;
22 |
23 | public PurchaseOptions(
24 | [CanBeNull] string offerId,
25 | bool applyOffer,
26 | [CanBeNull] Product oldProduct,
27 | [CanBeNull] PurchaseUpdatePolicy? updatePolicy,
28 | [CanBeNull] List contextKeys,
29 | int quantity,
30 | [CanBeNull] PromotionalOffer promotionalOffer)
31 | {
32 | OfferId = offerId;
33 | ApplyOffer = applyOffer;
34 | OldProduct = oldProduct;
35 | UpdatePolicy = updatePolicy;
36 | ContextKeys = contextKeys;
37 | Quantity = quantity;
38 | PromotionalOffer = promotionalOffer;
39 | }
40 |
41 | public override string ToString() {
42 | return $"{nameof(OfferId)}: {OfferId}, " +
43 | $"{nameof(ApplyOffer)}: {ApplyOffer}, " +
44 | $"{nameof(OldProduct)}: {OldProduct}, " +
45 | $"{nameof(UpdatePolicy)}: {UpdatePolicy}, " +
46 | $"{nameof(ContextKeys)}: {ContextKeys}, " +
47 | $"{nameof(Quantity)}: {Quantity}, " +
48 | $"{nameof(PromotionalOffer)}: {PromotionalOffer}";
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseOptions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4ad1a7d219a24e79b8b3d51c4e830b2f
3 | timeCreated: 1725357220
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseOptionsBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class PurchaseOptionsBuilder {
7 | [CanBeNull] private string _offerId;
8 | private bool _applyOffer = true;
9 | [CanBeNull] private Product _oldProduct;
10 | [CanBeNull] private PurchaseUpdatePolicy? _updatePolicy;
11 | [CanBeNull] private List _contextKeys;
12 | private int _quantity = 1;
13 | [CanBeNull] private PromotionalOffer _promotionalOffer;
14 |
15 | ///
16 | /// iOS only.
17 | /// Set quantity of product purchasing. Use for consumable in-app products.
18 | ///
19 | /// Quantity of product purchasing.
20 | /// Builder instance for chain calls.
21 | public PurchaseOptionsBuilder SetQuantity(int quantity)
22 | {
23 | this._quantity = quantity;
24 | return this;
25 | }
26 |
27 | ///
28 | /// Android only.
29 | /// Set offer for the purchase.
30 | ///
31 | /// Concrete offer which you'd like to purchase.
32 | /// Builder instance for chain calls.
33 | public PurchaseOptionsBuilder SetOffer(ProductOfferDetails offer)
34 | {
35 | _offerId = offer.OfferId;
36 | return this;
37 | }
38 |
39 | ///
40 | /// Android only.
41 | /// Set the offer ID to the purchase.
42 | ///
43 | /// Concrete offer ID which you'd like to purchase.
44 | /// Builder instance for chain calls.
45 | public PurchaseOptionsBuilder SetOfferId(string offerId)
46 | {
47 | _offerId = offerId;
48 | return this;
49 | }
50 |
51 | ///
52 | /// Android only.
53 | /// Call this function to remove any intro/trial offer from the purchase (use only a bare base plan).
54 | ///
55 | /// Builder instance for chain calls.
56 | public PurchaseOptionsBuilder RemoveOffer()
57 | {
58 | _applyOffer = false;
59 | return this;
60 | }
61 |
62 | ///
63 | /// Android only.
64 | /// Set Qonversion product from which the upgrade/downgrade will be initialized.
65 | ///
66 | /// Qonversion product from which the upgrade/downgrade will be initialized.
67 | /// Builder instance for chain calls.
68 | public PurchaseOptionsBuilder SetOldProduct(Product oldProduct)
69 | {
70 | _oldProduct = oldProduct;
71 | return this;
72 | }
73 |
74 |
75 | ///
76 | /// Android only.
77 | /// Set the update policy for the purchase.
78 | ///
79 | /// Update policy for the purchase.
80 | /// Builder instance for chain calls.
81 | public PurchaseOptionsBuilder SetUpdatePolicy(PurchaseUpdatePolicy updatePolicy)
82 | {
83 | _updatePolicy = updatePolicy;
84 | return this;
85 | }
86 |
87 | ///
88 | /// Set the context keys associated with a purchase.
89 | ///
90 | /// Context keys for the purchase.
91 | /// Builder instance for chain calls.
92 | public PurchaseOptionsBuilder SetContextKeys(List contextKeys)
93 | {
94 | _contextKeys = contextKeys;
95 | return this;
96 | }
97 |
98 | ///
99 | /// Set the promotional offer details.
100 | ///
101 | /// Promotional offer details.
102 | /// Builder instance for chain calls.
103 | public PurchaseOptionsBuilder SetPromotionalOffer(PromotionalOffer promoOffer)
104 | {
105 | _promotionalOffer = promoOffer;
106 | return this;
107 | }
108 |
109 | ///
110 | /// Generate a instance with all the provided options.
111 | ///
112 | /// The complete instance.
113 | public PurchaseOptions Build()
114 | {
115 | return new PurchaseOptions(_offerId, _applyOffer, _oldProduct, _updatePolicy, _contextKeys, _quantity, _promotionalOffer);
116 | }
117 | }
118 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseOptionsBuilder.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8c9a321d73824a668433f26898c31b17
3 | timeCreated: 1725357426
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseUpdateModel.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace QonversionUnity
4 | {
5 | ///
6 | /// Used to provide all the necessary purchase data to the method.
7 | /// Can be created manually or using the method.
8 | ///
9 | /// Requires Qonversion product identifiers - for the purchasing one and
10 | /// for the purchased one.
11 | ///
12 | /// If is not specified for Android, then the default offer will be applied.
13 | /// To know how we choose the default offer, see .
14 | ///
15 | /// If you want to remove any intro/trial offer from the purchase on Android (use only a bare base plan),
16 | /// call the method.
17 | ///
18 | public class PurchaseUpdateModel
19 | {
20 | public readonly string ProductId;
21 | public readonly string OldProductId;
22 | [CanBeNull] public PurchaseUpdatePolicy? UpdatePolicy;
23 | [CanBeNull] public string OfferId;
24 |
25 | internal bool ApplyOffer = true;
26 |
27 | public PurchaseUpdateModel(string productId, string oldProductId, [CanBeNull] PurchaseUpdatePolicy? updatePolicy = null, [CanBeNull] string offerId = null)
28 | {
29 | ProductId = productId;
30 | OldProductId = oldProductId;
31 | UpdatePolicy = updatePolicy;
32 | OfferId = offerId;
33 | }
34 |
35 | public PurchaseUpdateModel RemoveOffer()
36 | {
37 | ApplyOffer = false;
38 | return this;
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseUpdateModel.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f3649a3b94f94417a8ba61fa41937e6b
3 | timeCreated: 1701455222
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseUpdatePolicy.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | ///
4 | /// A policy used for purchase updates on Android, which describes
5 | /// how to migrate from purchased plan to a new one.
6 | ///
7 | /// Used in class for purchase updates.
8 | ///
9 | public enum PurchaseUpdatePolicy
10 | {
11 | /// The new plan takes effect immediately, and the user is charged full price of new plan
12 | /// and is given a full billing cycle of subscription, plus remaining prorated time
13 | /// from the old plan.
14 | ChargeFullPrice,
15 |
16 | /// The new plan takes effect immediately, and the billing cycle remains the same.
17 | ChargeProratedPrice,
18 |
19 | /// The new plan takes effect immediately, and the remaining time will be prorated
20 | /// and credited to the user.
21 | WithTimeProration,
22 |
23 | /// The new purchase takes effect immediately, the new plan will take effect
24 | /// when the old item expires.
25 | Deferred,
26 |
27 | /// The new plan takes effect immediately, and the new price will be charged
28 | /// on next recurrence time.
29 | WithoutProration,
30 |
31 | /// Unknown police.
32 | Unknown
33 | }
34 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/PurchaseUpdatePolicy.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 11d8a5507d73422bae604dc45573a52f
3 | timeCreated: 1701455289
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/QonversionError.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class QonversionError
7 | {
8 | public QErrorCode Code;
9 | public string Message;
10 |
11 | public QonversionError(Dictionary dict)
12 | {
13 | if (dict.TryGetValue("code", out object value)) Code = FormatErrorCode(value);
14 | string message = "";
15 | if (dict.TryGetValue("description", out object description))
16 | {
17 | message += description;
18 | if (dict.TryGetValue("domain", out object domain))
19 | {
20 | message += ". Domain: " + domain;
21 | }
22 | if (dict.TryGetValue("additionalMessage", out object additionalMessage))
23 | {
24 | message += "\nDebugInfo: " + additionalMessage;
25 | }
26 | }
27 |
28 | Message = message;
29 | }
30 |
31 | internal QonversionError(QErrorCode code, string message)
32 | {
33 | Code = code;
34 | Message = message;
35 | }
36 |
37 | public override string ToString()
38 | {
39 | return $"{nameof(Code)}: {Code}, " +
40 | $"{nameof(Message)}: {Message}";
41 | }
42 |
43 | private QErrorCode FormatErrorCode(object code)
44 | {
45 | return Enum.TryParse(code.ToString(), out QErrorCode parsedSource)
46 | ? parsedSource
47 | : QErrorCode.Unknown;
48 | }
49 | }
50 |
51 | public enum QErrorCode
52 | {
53 | Unknown, // Unknown error
54 | ApiRateLimitExceeded, // API requests rate limit exceeded
55 | AppleStoreError, // Apple Store error received
56 | BackendError, // There was a backend error
57 | BillingUnavailable, // The Billing service is unavailable on the device
58 | ClientInvalid, // Client is not allowed to issue the request, etc
59 | CloudServiceNetworkConnectionFailed, // The device could not connect to the network
60 | CloudServicePermissionDenied, // User is not allowed to access cloud service information
61 | CloudServiceRevoked, // User has revoked permission to use this cloud service
62 | FailedToReceiveData, // Could not receive data
63 | FeatureNotSupported, // The requested feature is not supported
64 | FraudPurchase, // Fraud purchase was detected
65 | IncorrectRequest, // Request failed
66 | InternalError, // Internal backend error
67 | InvalidClientUid, // Client Uid is invalid or not set
68 | InvalidCredentials, // Access token is invalid or not set
69 | InvalidStoreCredentials, // This account does not have access to the requested application
70 | LaunchError, // There was an error while launching Qonversion SDK
71 | NativeModuleError, // Something failed during native iOS or Android modules work or communication between Unity and native
72 | NetworkConnectionFailed, // There was a network issue. Make sure that the Internet connection is available on the device
73 | OfferingsNotFound, // No offerings found
74 | PaymentInvalid, // Purchase identifier was invalid, etc.
75 | PaymentNotAllowed, // This device is not allowed to make the payment
76 | PlayStoreError, // There was an issue with the Play Store service
77 | PrivacyAcknowledgementRequired, // User needs to acknowledge Apple's privacy policy
78 | ProductAlreadyOwned, // Failed to purchase since item is already owned
79 | ProductNotFound, // Failed to purchase since the Qonversion product was not found
80 | ProductNotOwned, // Failed to consume purchase since item is not owned
81 | ProjectConfigError, // The project is not configured or configured incorrectly in the Qonversion Dashboard
82 | PurchaseCanceled, // User pressed back or canceled a dialog for purchase
83 | PurchaseInvalid, // Failure of purchase
84 | PurchasePending, // Purchase is pending
85 | PurchaseUnspecified, // Unspecified state of the purchase
86 | ReceiptValidationError, // Receipt validation error
87 | RemoteConfigurationNotAvailable, // Remote configuration is not available for the current user or for the provided context key
88 | ResponseParsingFailed, // A problem occurred while serializing or deserializing data
89 | StoreProductNotAvailable, // Requested product is not available for purchase or its product id was not found
90 | UnauthorizedRequestData, // App is attempting to use SKPayment's requestData property, but does not have the appropriate entitlement
91 | UnknownClientPlatform, // The current platform is not supported
92 | }
93 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/QonversionError.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0b5335b7346c84e0d85ca63af24368c9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/RemoteConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 | using UnityEngine;
5 |
6 | namespace QonversionUnity
7 | {
8 | public class RemoteConfig
9 | {
10 | public readonly Dictionary Payload;
11 | [CanBeNull] public readonly Experiment Experiment;
12 | public readonly RemoteConfigurationSource Source;
13 |
14 | public RemoteConfig(Dictionary dict)
15 | {
16 | if (dict.TryGetValue("payload", out object value) && value is Dictionary) Payload = value as Dictionary;
17 | if (dict.TryGetValue("experiment", out value) && value is Dictionary experimentInfo)
18 | {
19 | Experiment = new Experiment(experimentInfo);
20 | }
21 | if (dict.TryGetValue("source", out value) && value is Dictionary sourceInfo)
22 | {
23 | Source = new RemoteConfigurationSource(sourceInfo);
24 | }
25 | }
26 |
27 | public override string ToString()
28 | {
29 | return $"{nameof(Payload)}: {Payload}, " +
30 | $"{nameof(Experiment)}: {Experiment}, " +
31 | $"{nameof(Source)}: {Source}";
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/RemoteConfig.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1ba2fbd2bcc0e45b5b4cab28b85ad25f
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/RemoteConfigList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 |
5 | namespace QonversionUnity
6 | {
7 | public class RemoteConfigList
8 | {
9 | public readonly List RemoteConfigs;
10 |
11 | public RemoteConfigList(Dictionary dict)
12 | {
13 | if (dict.TryGetValue("remoteConfigs", out object value) && value is List offerings)
14 | {
15 | RemoteConfigs = Mapper.ConvertObjectsList(offerings);
16 | }
17 | }
18 |
19 | [CanBeNull]
20 | public RemoteConfig RemoteConfigForContextKey(String contextKey)
21 | {
22 | return FindRemoteConfig(contextKey);
23 | }
24 |
25 | [CanBeNull]
26 | public RemoteConfig RemoteConfigForEmptyContextKey()
27 | {
28 | return FindRemoteConfig(null);
29 | }
30 |
31 | [CanBeNull]
32 | private RemoteConfig FindRemoteConfig([CanBeNull] String contextKey)
33 | {
34 | return RemoteConfigs.Find(remoteConfig => remoteConfig.Source.ContextKey == contextKey);
35 | }
36 |
37 | public override string ToString()
38 | {
39 | return $"{nameof(RemoteConfigs)}: {Utils.PrintObjectList(RemoteConfigs)}";
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/RemoteConfigList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c04d46990d4d4e03b14436e3cb92ce0e
3 | timeCreated: 1711619835
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/RemoteConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class RemoteConfigurationSource
7 | {
8 |
9 | public readonly string Id;
10 | public readonly string Name;
11 | public readonly RemoteConfigurationSourceType Type;
12 | public readonly RemoteConfigurationAssignmentType AssignmentType;
13 | [CanBeNull] public readonly string ContextKey;
14 |
15 |
16 | public RemoteConfigurationSource(Dictionary dict)
17 | {
18 | if (dict.TryGetValue("id", out object value)) Id = value as string;
19 | if (dict.TryGetValue("name", out value)) Name = value as string;
20 | if (dict.TryGetValue("assignmentType", out value)) AssignmentType = FormatAssignmentType(value);
21 | if (dict.TryGetValue("type", out value)) Type = FormatSourceType(value);
22 | if (dict.TryGetValue("contextKey", out value)) ContextKey = value as string;
23 | }
24 |
25 | public RemoteConfigurationAssignmentType FormatAssignmentType(object typeValue)
26 | {
27 | string type = typeValue as string;
28 | if (type == "auto")
29 | {
30 | return RemoteConfigurationAssignmentType.Auto;
31 | }
32 | else if (type == "manual")
33 | {
34 | return RemoteConfigurationAssignmentType.Manual;
35 | }
36 |
37 | return RemoteConfigurationAssignmentType.Unknown;
38 | }
39 |
40 | public RemoteConfigurationSourceType FormatSourceType(object typeValue)
41 | {
42 | string type = typeValue as string;
43 | if (type == "experiment_control_group")
44 | {
45 | return RemoteConfigurationSourceType.ExperimentControlGroup;
46 | }
47 | else if (type == "experiment_treatment_group")
48 | {
49 | return RemoteConfigurationSourceType.ExperimentTreatmentGroup;
50 | }
51 | else if (type == "remote_configuration")
52 | {
53 | return RemoteConfigurationSourceType.RemoteConfiguration;
54 | }
55 |
56 | return RemoteConfigurationSourceType.Unknown;
57 | }
58 |
59 | public override string ToString()
60 | {
61 | return $"{nameof(Id)}: {Id}, " +
62 | $"{nameof(Name)}: {Name}, " +
63 | $"{nameof(AssignmentType)}: {AssignmentType}, " +
64 | $"{nameof(Type)}: {Type}, " +
65 | $"{nameof(ContextKey)}: {ContextKey}";
66 | }
67 | }
68 |
69 | public enum RemoteConfigurationAssignmentType
70 | {
71 | Unknown,
72 | Auto,
73 | Manual
74 | }
75 |
76 | public enum RemoteConfigurationSourceType
77 | {
78 | Unknown,
79 | ExperimentControlGroup,
80 | ExperimentTreatmentGroup,
81 | RemoteConfiguration
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/RemoteConfigurationSource.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 47dd88424cf8b4b63b34e89a3f76b6fb
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ScreenPresentationConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using QonversionUnity.MiniJSON;
4 | using UnityEngine;
5 |
6 | namespace QonversionUnity
7 | {
8 | public class ScreenPresentationConfig
9 | {
10 | /// Describes how screens will be displayed.
11 | [Tooltip("For mode details see the enum description.")]
12 | public readonly ScreenPresentationStyle PresentationStyle;
13 |
14 | /// iOS only. For Android consider using .
15 | /// Describes whether should transaction be animated or not.
16 | /// Default value is true.
17 | public readonly bool Animated;
18 |
19 | public ScreenPresentationConfig(ScreenPresentationStyle presentationStyle)
20 | {
21 | PresentationStyle = presentationStyle;
22 | Animated = true;
23 | }
24 |
25 | public ScreenPresentationConfig(ScreenPresentationStyle presentationStyle, bool animated)
26 | {
27 | PresentationStyle = presentationStyle;
28 | Animated = animated;
29 | }
30 |
31 | public string ToJson()
32 | {
33 | Dictionary data = new Dictionary();
34 |
35 | string presentationStyleName = Enum.GetName(typeof(ScreenPresentationStyle), PresentationStyle);
36 | data["presentationStyle"] = presentationStyleName;
37 | data["animated"] = Animated ? "1" : "0";
38 |
39 | return data.toJson();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ScreenPresentationConfig.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c6a0a1bedf494be7901137a0ffbcc70b
3 | timeCreated: 1674808729
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ScreenPresentationStyle.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum ScreenPresentationStyle
4 | {
5 | /// on Android - default screen transaction animation will be used.
6 | /// on iOS - not a modal presentation. This style pushes a controller to a current navigation stack.
7 | /// For iOS NavigationController on the top of the stack is required.
8 | Push,
9 |
10 | /// on Android - screen will move from bottom to top.
11 | /// on iOS - UIModalPresentationFullScreen analog.
12 | FullScreen,
13 |
14 | /// iOS only - UIModalPresentationPopover analog
15 | Popover,
16 |
17 | /// Android only - screen will appear/disappear without any animation
18 | /// For iOS consider providing the flag.
19 | NoAnimation,
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/ScreenPresentationStyle.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c9772f14cb44431faca69bb2a0841fd6
3 | timeCreated: 1674808596
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 34cf22d7675f2416d9d88b74fa126afb
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKPraymentDiscount.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class SKPaymentDiscount {
6 | public readonly string Identifier;
7 | public readonly string KeyIdentifier;
8 | public readonly string Nonce;
9 | public readonly string Signature;
10 | public readonly long Timestamp;
11 |
12 | public SKPaymentDiscount(Dictionary dict) {
13 | if (dict.TryGetValue("identifier", out object value)) Identifier = value as string;
14 | if (dict.TryGetValue("keyIdentifier", out value)) KeyIdentifier = value as string;
15 | if (dict.TryGetValue("nonce", out value)) Nonce = value as string;
16 | if (dict.TryGetValue("signature", out value)) Signature = value as string;
17 | if (dict.TryGetValue("timestamp", out object timestamp)) Timestamp = (long)timestamp;
18 | }
19 |
20 | public override string ToString() {
21 | return $"{nameof(Identifier)}: {Identifier}, " +
22 | $"{nameof(KeyIdentifier)}: {KeyIdentifier}, " +
23 | $"{nameof(Nonce)}: {Nonce}, " +
24 | $"{nameof(Signature)}: {Signature}, " +
25 | $"{nameof(Timestamp)}: {Timestamp}";
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKPraymentDiscount.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 446d731fe6b84b17a0ae9f3ce196f7e2
3 | timeCreated: 1732029963
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKProduct.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class SKProduct
7 | {
8 | public readonly string ProductIdentifier;
9 | public readonly string LocalizedDescription;
10 | public readonly string LocalizedTitle;
11 | public readonly bool IsFamilyShareable;
12 | public readonly string Price;
13 | [CanBeNull] public readonly SKProductDiscount IntroductoryPrice;
14 | [CanBeNull] public readonly List Discounts;
15 | [CanBeNull] public readonly string SubscriptionGroupIdentifier;
16 | [CanBeNull] public readonly SKProductSubscriptionPeriod SubscriptionPeriod;
17 | public readonly bool IsDownloadable;
18 | [CanBeNull] public readonly List DownloadContentLengths;
19 | [CanBeNull] public readonly string DownloadContentVersion;
20 | [CanBeNull] public readonly string CurrencyCode;
21 |
22 | public SKProduct(Dictionary dict)
23 | {
24 | if (dict.TryGetValue("productIdentifier", out object value)) ProductIdentifier = value as string;
25 | if (dict.TryGetValue("localizedDescription", out value)) LocalizedDescription = value as string;
26 | if (dict.TryGetValue("localizedTitle", out value)) LocalizedTitle = value as string;
27 |
28 | if (dict.TryGetValue("isFamilyShareable", out value))
29 | {
30 | if (value is bool boolValue) IsFamilyShareable = boolValue;
31 | }
32 |
33 | if (dict.TryGetValue("price", out value)) Price = value as string;
34 |
35 | if (dict.TryGetValue("introductoryPrice", out value) && value is Dictionary introPrice)
36 | {
37 | IntroductoryPrice = new SKProductDiscount(introPrice);
38 | }
39 |
40 | if (dict.TryGetValue("discounts", out value))
41 | {
42 | if (value is List discounts) Discounts = Mapper.ConvertObjectsList(discounts);
43 | }
44 |
45 | if (dict.TryGetValue("subscriptionGroupIdentifier", out value)) SubscriptionGroupIdentifier = value as string;
46 |
47 | if (dict.TryGetValue("subscriptionPeriod", out value))
48 | {
49 | if (value is Dictionary subsPeriod) SubscriptionPeriod = new SKProductSubscriptionPeriod(subsPeriod);
50 | }
51 |
52 | if (dict.TryGetValue("isDownloadable", out value))
53 | {
54 | if (value is bool boolValue) IsDownloadable = boolValue;
55 | }
56 |
57 | if (dict.TryGetValue("downloadContentLengths", out value)) DownloadContentLengths = value as List;
58 | if (dict.TryGetValue("downloadContentVersion", out value)) DownloadContentVersion = value as string;
59 | if (dict.TryGetValue("priceLocale", out object priceLocale))
60 | {
61 | if (priceLocale is Dictionary priceLocaleDict)
62 | {
63 | if (priceLocaleDict.TryGetValue("currencyCode", out value))
64 | {
65 | CurrencyCode = value as string;
66 | }
67 | }
68 | }
69 | }
70 |
71 | public override string ToString()
72 | {
73 | return $"{nameof(ProductIdentifier)}: {ProductIdentifier}, " +
74 | $"{nameof(LocalizedDescription)}: {LocalizedDescription}, " +
75 | $"{nameof(LocalizedTitle)}: {LocalizedTitle}, " +
76 | $"{nameof(IsFamilyShareable)}: {IsFamilyShareable}, " +
77 | $"{nameof(Price)}: {Price} , " +
78 | $"{nameof(IntroductoryPrice)}: {IntroductoryPrice}, " +
79 | $"{nameof(Discounts)}: {Utils.PrintObjectList(Discounts)}, " +
80 | $"{nameof(SubscriptionGroupIdentifier)}: {SubscriptionGroupIdentifier}, " +
81 | $"{nameof(SubscriptionPeriod)}: {SubscriptionPeriod}, " +
82 | $"{nameof(IsDownloadable)}: {IsDownloadable} , " +
83 | $"{nameof(DownloadContentLengths)}: {Utils.PrintObjectList(DownloadContentLengths)}, " +
84 | $"{nameof(DownloadContentVersion)}: {DownloadContentVersion}, " +
85 | $"{nameof(CurrencyCode)}: {CurrencyCode}";
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKProduct.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a47619ab0f35e47b6882af6cbc4c6b05
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 |
5 | namespace QonversionUnity
6 | {
7 | public class SKProductDiscount
8 | {
9 | [CanBeNull] public readonly string Identifier;
10 | public readonly SKProductDiscountType Type;
11 | [CanBeNull] public readonly string Price;
12 | [CanBeNull] public readonly string LocaleIdentifier;
13 | public readonly SKProductDiscountPaymentMode PaymentMode;
14 | public readonly int NumberOfPeriods;
15 | [CanBeNull] public readonly SKProductSubscriptionPeriod SubscriptionPeriod;
16 | public readonly string CurrencySymbol;
17 |
18 | public SKProductDiscount(Dictionary dict)
19 | {
20 | if (dict.TryGetValue("identifier", out object value)) Identifier = value as string;
21 | if (dict.TryGetValue("type", out value)) Type = FormatDiscountType(value);
22 | if (dict.TryGetValue("price", out value)) Price = value as string;
23 | if (dict.TryGetValue("paymentMode", out value)) PaymentMode = FormatPaymentMode(value);
24 | if (dict.TryGetValue("numberOfPeriods", out value)) NumberOfPeriods = Convert.ToInt32(value);
25 |
26 | if (dict.TryGetValue("priceLocale", out object priceLocale))
27 | {
28 | if (priceLocale is Dictionary priceLocaleDict)
29 | {
30 | if (priceLocaleDict.TryGetValue("localeIdentifier", out value)) LocaleIdentifier = value as string;
31 | if (priceLocaleDict.TryGetValue("currencySymbol", out value)) CurrencySymbol = value as string;
32 | }
33 | }
34 |
35 | if (dict.TryGetValue("subscriptionPeriod", out value))
36 | {
37 | if (value is Dictionary subsPeriod) SubscriptionPeriod = new SKProductSubscriptionPeriod(subsPeriod);
38 | }
39 | }
40 |
41 | public override string ToString()
42 | {
43 | return $"{nameof(Identifier)}: {Identifier}, " +
44 | $"{nameof(Type)}: {Type}, " +
45 | $"{nameof(Price)}: {Price}, " +
46 | $"{nameof(LocaleIdentifier)}: {LocaleIdentifier}, " +
47 | $"{nameof(Price)}: {Price} , " +
48 | $"{nameof(PaymentMode)}: {PaymentMode}, " +
49 | $"{nameof(NumberOfPeriods)}: {NumberOfPeriods}, " +
50 | $"{nameof(SubscriptionPeriod)}: {SubscriptionPeriod}" +
51 | $"{nameof(CurrencySymbol)}: {CurrencySymbol}";
52 | }
53 |
54 | private SKProductDiscountType FormatDiscountType(object discountType) =>
55 | (SKProductDiscountType)Convert.ToInt32(discountType);
56 |
57 | private SKProductDiscountPaymentMode FormatPaymentMode(object paymentMode) =>
58 | (SKProductDiscountPaymentMode)Convert.ToInt32(paymentMode);
59 | }
60 |
61 | public enum SKProductDiscountType
62 | {
63 | Introductory,
64 | Subscription
65 | }
66 |
67 | public enum SKProductDiscountPaymentMode
68 | {
69 | PayAsYouGo,
70 | PayUpFront,
71 | FreeTrial
72 | }
73 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 022a118da08d74f60b495168da846a70
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class SKProductSubscriptionPeriod
7 | {
8 | public readonly int NumberOfUnits;
9 | public readonly SKPeriodUnit Unit;
10 |
11 | public SKProductSubscriptionPeriod(Dictionary dict)
12 | {
13 | if (dict.TryGetValue("numberOfUnits", out object value)) NumberOfUnits = Convert.ToInt32(value);
14 | if (dict.TryGetValue("unit", out value)) Unit = FormatPeriodUnit(value);
15 | }
16 |
17 | public override string ToString()
18 | {
19 | return $"{nameof(NumberOfUnits)}: {NumberOfUnits}, " +
20 | $"{nameof(Unit)}: {Unit}";
21 | }
22 |
23 | private SKPeriodUnit FormatPeriodUnit(object periodUnit) =>
24 | (SKPeriodUnit)Convert.ToInt32(periodUnit);
25 | }
26 |
27 | public enum SKPeriodUnit
28 | {
29 | Day,
30 | Week,
31 | Month,
32 | Year,
33 | }
34 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8451375a11e03434594db113652a3624
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkuDetails.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace QonversionUnity
5 | {
6 | [Obsolete("Consider using ProductStoreDetails instead.")]
7 | public class SkuDetails
8 | {
9 | /// Textual description of the product.
10 | public readonly string Description;
11 |
12 | /// Trial period in ISO 8601 format.
13 | public readonly string FreeTrialPeriod;
14 |
15 | /// Icon of the product if present.
16 | public readonly string IconUrl;
17 |
18 | /// Introductory price, only applies to [SkuType.subs]. Formatted ("$0.99").
19 | public readonly string IntroductoryPrice;
20 |
21 | /// Introductory price in micro-units
22 | public readonly long IntroductoryPriceAmountMicros;
23 |
24 | /// The number of billing perios that [introductoryPrice] is valid for ("2").
25 | public readonly int IntroductoryPriceCycles;
26 |
27 | /// The billing period of [introductoryPrice], in ISO 8601 format.
28 | public readonly string IntroductoryPricePeriod;
29 |
30 | /// String in JSON format that contains SKU details.
31 | public readonly string OriginalJson;
32 |
33 | /// The original price that the user purchased this product for.
34 | public readonly string OriginalPrice;
35 |
36 | /// [originalPrice] in micro-units (990000).
37 | public readonly long OriginalPriceAmountMicros;
38 |
39 | /// Formatted with currency symbol ("$0.99").
40 | public readonly string Price;
41 |
42 | /// Returns price in micro-units, where 1,000,000 micro-units equal one unit of the currency.
43 | public readonly long PriceAmountMicros;
44 |
45 | /// [price] ISO 4217 currency code.
46 | public readonly string PriceCurrencyCode;
47 |
48 | /// The product ID in Google Play Console.
49 | public readonly string Sku;
50 |
51 | /// Applies to [SkuType.subs], formatted in ISO 8601.
52 | public readonly string SubscriptionPeriod;
53 |
54 | /// The product's title.
55 | public readonly string Title;
56 |
57 | /// Inapp or subs.
58 | public readonly string Type;
59 |
60 | public SkuDetails(Dictionary dict)
61 | {
62 | if (dict.TryGetValue("description", out object value)) Description = value as string;
63 | if (dict.TryGetValue("freeTrialPeriod", out value)) FreeTrialPeriod = value as string;
64 | if (dict.TryGetValue("iconUrl", out value)) IconUrl = value as string;
65 | if (dict.TryGetValue("introductoryPrice", out value)) IntroductoryPrice = value as string;
66 | if (dict.TryGetValue("introductoryPriceAmountMicros", out value)) IntroductoryPriceAmountMicros = (long)value;
67 | if (dict.TryGetValue("introductoryPriceCycles", out value)) IntroductoryPriceCycles = Convert.ToInt32(value);
68 | if (dict.TryGetValue("introductoryPricePeriod", out value)) IntroductoryPricePeriod = value as string;
69 | if (dict.TryGetValue("originalJson", out value)) OriginalJson = value as string;
70 | if (dict.TryGetValue("originalPrice", out value)) OriginalPrice = value as string;
71 | if (dict.TryGetValue("originalPriceAmountMicros", out value)) OriginalPriceAmountMicros = (long)value;
72 | if (dict.TryGetValue("price", out value)) Price = value as string;
73 | if (dict.TryGetValue("priceAmountMicros", out value)) PriceAmountMicros = (long)value;
74 | if (dict.TryGetValue("priceCurrencyCode", out value)) PriceCurrencyCode = value as string;
75 | if (dict.TryGetValue("sku", out value)) Sku = value as string;
76 | if (dict.TryGetValue("subscriptionPeriod", out value)) SubscriptionPeriod = value as string;
77 | if (dict.TryGetValue("title", out value)) Title = value as string;
78 | if (dict.TryGetValue("type", out value)) Type = value as string;
79 | }
80 |
81 | public override string ToString()
82 | {
83 | return $"{nameof(Description)}: {Description}, \n" +
84 | $"{nameof(FreeTrialPeriod)}: {FreeTrialPeriod}, " +
85 | $"{nameof(IconUrl)}: {IconUrl}, " +
86 | $"{nameof(IntroductoryPrice)}: {IntroductoryPrice}, " +
87 | $"{nameof(IntroductoryPriceAmountMicros)}: {IntroductoryPriceAmountMicros}, " +
88 | $"{nameof(IntroductoryPriceCycles)}: {IntroductoryPriceCycles} , " +
89 | $"{nameof(IntroductoryPricePeriod)}: {IntroductoryPricePeriod}, " +
90 | $"{nameof(OriginalJson)}: {OriginalJson}, " +
91 | $"{nameof(OriginalPrice)}: {OriginalPrice}, " +
92 | $"{nameof(OriginalPriceAmountMicros)}: {OriginalPriceAmountMicros}, " +
93 | $"{nameof(Price)}: {Price}, " +
94 | $"{nameof(PriceAmountMicros)}: {PriceAmountMicros}, " +
95 | $"{nameof(PriceCurrencyCode)}: {PriceCurrencyCode}, " +
96 | $"{nameof(Sku)}: {Sku}, " +
97 | $"{nameof(SubscriptionPeriod)}: {SubscriptionPeriod}, " +
98 | $"{nameof(Title)}: {Title}, " +
99 | $"{nameof(Type)}: {Type}";
100 | }
101 | }
102 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SkuDetails.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 23ce9e7e4cd8f48f8840738ffaef5f55
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SubscriptionPeriod.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace QonversionUnity
4 | {
5 | ///
6 | /// A class describing a subscription period
7 | ///
8 | public class SubscriptionPeriod
9 | {
10 | /// A count of subsequent intervals.
11 | public readonly int UnitCount;
12 |
13 | /// Interval unit.
14 | public readonly SubscriptionPeriodUnit Unit;
15 |
16 | /// ISO 8601 representation of the period, e.g. "P7D", meaning 7 days period.
17 | public readonly string Iso;
18 |
19 | public SubscriptionPeriod(Dictionary dict)
20 | {
21 | if (dict.TryGetValue("iso", out object value)) Iso = value as string;
22 | if (dict.TryGetValue("unitCount", out value)) UnitCount = (int)(long)value;
23 | if (dict.TryGetValue("unit", out value)) Unit = FormatSubscriptionPeriodUnit(value);
24 | }
25 |
26 | public SubscriptionPeriodUnit FormatSubscriptionPeriodUnit(object unitValue)
27 | {
28 | string unit = unitValue as string;
29 | if (unit == "Day")
30 | {
31 | return SubscriptionPeriodUnit.Day;
32 | }
33 |
34 | if (unit == "Week")
35 | {
36 | return SubscriptionPeriodUnit.Week;
37 | }
38 |
39 | if (unit == "Month")
40 | {
41 | return SubscriptionPeriodUnit.Month;
42 | }
43 |
44 | if (unit == "Year")
45 | {
46 | return SubscriptionPeriodUnit.Year;
47 | }
48 |
49 | return SubscriptionPeriodUnit.Unknown;
50 | }
51 |
52 | public override string ToString()
53 | {
54 | return $"{nameof(UnitCount)}: {UnitCount}, " +
55 | $"{nameof(Iso)}: {Iso}, " +
56 | $"{nameof(Unit)}: {Unit}";
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SubscriptionPeriod.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 70b23c73445d4949880a71a288548384
3 | timeCreated: 1701437706
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SubscriptionPeriodUnit.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum SubscriptionPeriodUnit
4 | {
5 | Day,
6 | Week,
7 | Month,
8 | Year,
9 | Unknown,
10 | }
11 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/SubscriptionPeriodUnit.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2e3484a14d3e49c7b358851431e2bb66
3 | timeCreated: 1701437751
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/Transaction.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6c2207fece8b44558ad88f2591eb0f89
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/User.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class User
7 | {
8 | public readonly string QonversionId;
9 | [CanBeNull] public readonly string IdentityId;
10 |
11 | public User(string qonversionId, [CanBeNull] string identityId)
12 | {
13 | QonversionId = qonversionId;
14 | IdentityId = identityId;
15 | }
16 |
17 | public User(Dictionary dict)
18 | {
19 | if (dict.TryGetValue("qonversionId", out var qonversionId) && qonversionId != null)
20 | {
21 | QonversionId = qonversionId as string;
22 | }
23 |
24 | if (dict.TryGetValue("identityId", out var identityId) && identityId != null)
25 | {
26 | IdentityId = identityId as string;
27 | }
28 | }
29 |
30 | public override string ToString()
31 | {
32 | return $"{nameof(QonversionId)}: {QonversionId}, " +
33 | $"{nameof(IdentityId)}: {IdentityId}";
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/User.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e90e3bc36aae4e069c0c373e53427b0c
3 | timeCreated: 1668747828
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/UserProperties.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 | using UnityEngine;
5 |
6 | namespace QonversionUnity
7 | {
8 | public class UserProperties
9 | {
10 | ///
11 | /// List of all user properties.
12 | ///
13 | public readonly List Properties;
14 |
15 | ///
16 | /// List of user properties, set for the Qonversion defined keys.
17 | /// This is a subset of all list.
18 | /// .
19 | ///
20 | public readonly List DefinedProperties;
21 |
22 | ///
23 | /// List of user properties, set for custom keys.
24 | /// This is a subset of all list.
25 | /// .
26 | ///
27 | public readonly List CustomProperties;
28 |
29 | ///
30 | /// Map of all user properties.
31 | /// This is a flattened version of the list as a key-value map.
32 | ///
33 | public readonly Dictionary FlatPropertiesMap;
34 |
35 | ///
36 | /// Map of user properties, set for the Qonversion defined keys.
37 | /// This is a flattened version of the list as a key-value map.
38 | /// .
39 | ///
40 | public readonly Dictionary FlatDefinedPropertiesMap;
41 |
42 | ///
43 | /// Map of user properties, set for custom keys.
44 | /// This is a flattened version of the list as a key-value map.
45 | /// .
46 | ///
47 | public readonly Dictionary FlatCustomPropertiesMap;
48 |
49 | public UserProperties(Dictionary dict)
50 | {
51 | if (dict.TryGetValue("properties", out var value) && value is List properties)
52 | {
53 | Properties = Mapper.ConvertObjectsList(properties);
54 | }
55 | else
56 | {
57 | Debug.LogError("Failed to parse user properties array, assigning empty list.");
58 | Properties = new List();
59 | }
60 | DefinedProperties = CalculateDefinedProperties();
61 | CustomProperties = CalculateCustomProperties();
62 | FlatPropertiesMap = CalculateFlatPropertiesMap();
63 | FlatDefinedPropertiesMap = CalculateFlatDefinedPropertiesMap();
64 | FlatCustomPropertiesMap = CalculateFlatCustomPropertiesMap();
65 | }
66 |
67 | ///
68 | /// Searches for a property with the given property in all properties list.
69 | ///
70 | [CanBeNull]
71 | public UserProperty GetProperty(string key)
72 | {
73 | return Properties.Find(property => property.Key == key);
74 | }
75 |
76 | ///
77 | /// Searches for a property with the given Qonversion defined property
78 | /// in defined properties list.
79 | ///
80 | [CanBeNull]
81 | public UserProperty GetDefinedProperty(UserPropertyKey key)
82 | {
83 | return DefinedProperties.Find(property => property.DefinedKey == key);
84 | }
85 |
86 | private List CalculateDefinedProperties()
87 | {
88 | return Properties.FindAll(
89 | userProperty => userProperty.DefinedKey != UserPropertyKey.Custom
90 | );
91 | }
92 |
93 | private List CalculateCustomProperties()
94 | {
95 | return Properties.FindAll(
96 | userProperty => userProperty.DefinedKey == UserPropertyKey.Custom
97 | );
98 | }
99 |
100 | private Dictionary CalculateFlatPropertiesMap()
101 | {
102 | Dictionary flatPropertiesMap = new Dictionary();
103 | foreach (var property in Properties)
104 | {
105 | flatPropertiesMap[property.Key] = property.Value;
106 | }
107 | return flatPropertiesMap;
108 | }
109 |
110 | private Dictionary CalculateFlatDefinedPropertiesMap()
111 | {
112 | Dictionary flatDefinedPropertiesMap = new Dictionary();
113 | foreach (var property in Properties)
114 | {
115 | if (property.DefinedKey != UserPropertyKey.Custom)
116 | {
117 | flatDefinedPropertiesMap[property.DefinedKey] = property.Value;
118 | }
119 | }
120 | return flatDefinedPropertiesMap;
121 | }
122 |
123 | private Dictionary CalculateFlatCustomPropertiesMap()
124 | {
125 | Dictionary flatCustomPropertiesMap = new Dictionary();
126 | foreach (var property in Properties)
127 | {
128 | if (property.DefinedKey == UserPropertyKey.Custom)
129 | {
130 | flatCustomPropertiesMap[property.Key] = property.Value;
131 | }
132 | }
133 | return flatCustomPropertiesMap;
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/UserProperties.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1e8d7ac2990e44f2972a103d52a7b30d
3 | timeCreated: 1691165498
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/UserProperty.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine.Scripting;
3 |
4 | namespace QonversionUnity
5 | {
6 | public class UserProperty
7 | {
8 | public readonly string Key;
9 | public readonly string Value;
10 | public readonly UserPropertyKey DefinedKey;
11 |
12 | // Informs compiler to save this method from removal via optimization,
13 | // as even if it has no direct calls, it is called via reflection while mapping.
14 | [Preserve]
15 | public UserProperty(Dictionary dict)
16 | {
17 | if (dict.TryGetValue("key", out var key) && key != null)
18 | {
19 | Key = key as string;
20 | DefinedKey = ConvertUserPropertyKey(Key);
21 | }
22 |
23 | if (dict.TryGetValue("value", out var value) && value != null)
24 | {
25 | Value = value as string;
26 | }
27 | }
28 |
29 | public override string ToString()
30 | {
31 | return $"{nameof(Key)}: {Key}, " +
32 | $"{nameof(Value)}: {Value}";
33 | }
34 |
35 | private UserPropertyKey ConvertUserPropertyKey(string stringKey)
36 | {
37 | switch (stringKey)
38 | {
39 | case "_q_email":
40 | return UserPropertyKey.Email;
41 | case "_q_name":
42 | return UserPropertyKey.Name;
43 | case "_q_kochava_device_id":
44 | return UserPropertyKey.KochavaDeviceId;
45 | case "_q_appsflyer_user_id":
46 | return UserPropertyKey.AppsFlyerUserId;
47 | case "_q_adjust_adid":
48 | return UserPropertyKey.AdjustAdId;
49 | case "_q_custom_user_id":
50 | return UserPropertyKey.CustomUserId;
51 | case "_q_fb_attribution":
52 | return UserPropertyKey.FacebookAttribution;
53 | case "_q_firebase_instance_id":
54 | return UserPropertyKey.FirebaseAppInstanceId;
55 | case "_q_app_set_id":
56 | return UserPropertyKey.AppSetId;
57 | case "_q_advertising_id":
58 | return UserPropertyKey.AdvertisingId;
59 | case "_q_appmetrica_device_id":
60 | return UserPropertyKey.AppMetricaDeviceId;
61 | case "_q_appmetrica_user_profile_id":
62 | return UserPropertyKey.AppMetricaUserProfileId;
63 | case "_q_pushwoosh_hwid":
64 | return UserPropertyKey.PushWooshHwId;
65 | case "_q_pushwoosh_user_id":
66 | return UserPropertyKey.PushWooshUserId;
67 | case "_q_tenjin_aiid":
68 | return UserPropertyKey.TenjinAnalyticsInstallationId;
69 | }
70 |
71 | return UserPropertyKey.Custom;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/UserProperty.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 93d0d943d5504615ab21656f2090226c
3 | timeCreated: 1691165220
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/UserPropertyKey.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | public enum UserPropertyKey
4 | {
5 | Email,
6 | Name,
7 | KochavaDeviceId,
8 | AppsFlyerUserId,
9 | AdjustAdId,
10 | CustomUserId,
11 | FacebookAttribution, // Android only
12 | FirebaseAppInstanceId,
13 | AppSetId, // Android only
14 | AdvertisingId, // iOS only
15 | AppMetricaDeviceId,
16 | AppMetricaUserProfileId,
17 | PushWooshHwId,
18 | PushWooshUserId,
19 | TenjinAnalyticsInstallationId,
20 | Custom,
21 | }
22 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Dto/UserPropertyKey.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a3f3e84df946549f68ad3cbfa4f727f7
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/IAutomations.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | public interface IAutomations
7 | {
8 | ///
9 | /// The Automations delegate is responsible for handling in-app screens and actions when push notification is received.
10 | /// Make sure the method is called before Qonversion.handleNotification.
11 | ///
12 | /// The delegate to handle automations events
13 | public void SetDelegate(AutomationsDelegate automationsDelegate);
14 |
15 | ///
16 | /// Set push token to Qonversion to enable Qonversion push notifications
17 | ///
18 | /// Consider removing this method calls. Qonversion is not working with push notifications anymore.
19 | /// Firebase device token for Android. APNs device token for iOS.
20 | public void SetNotificationsToken(string token);
21 |
22 | ///
23 | /// Call to handle push notifications sent by Qonversion Automations.
24 | ///
25 | /// Consider removing this method calls. Qonversion is not working with push notifications anymore.
26 | /// notification payload data
27 | /// true when a push notification was received from Qonversion. Otherwise, returns false, so you need to handle the notification yourself
28 | /// Firebase RemoteMessage data
29 | /// APNs notification data
30 | public bool HandleNotification(Dictionary notification);
31 |
32 | ///
33 | /// Get parsed custom payload, which you added to the notification in the dashboard
34 | ///
35 | /// Consider removing this method calls. Qonversion is not working with push notifications anymore.
36 | /// notification payload data
37 | /// a map with custom payload from the notification or null if it's not provided
38 | [CanBeNull]
39 | public Dictionary GetNotificationCustomPayload(Dictionary notification);
40 |
41 | ///
42 | /// Show the screen using its ID.
43 | ///
44 | /// identifier of the screen which must be shown
45 | /// callback that will be called when response is received
46 | public void ShowScreen(string screenId, Automations.OnShowScreenResponseReceived callback);
47 |
48 | ///
49 | /// Set the configuration of screen representation.
50 | ///
51 | /// a configuration to apply
52 | /// identifier of screen, to which a config should be applied.
53 | /// If not provided, the config is used for all the screens
54 | public void SetScreenPresentationConfig(ScreenPresentationConfig config, [CanBeNull] string screenId = null);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Runtime/Scripts/IAutomations.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1bf6adea119149b5a8575fd688405c1d
3 | timeCreated: 1670849785
--------------------------------------------------------------------------------
/Runtime/Scripts/IQonversion.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9ded0a1938a14b2788563e72c5f7fbd6
3 | timeCreated: 1670849923
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 00384c60219c4bda98b08e4f7c65bc6f
3 | timeCreated: 1668672384
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/AutomationsInternal.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using QonversionUnity.MiniJSON;
3 | using UnityEngine;
4 |
5 | namespace QonversionUnity
6 | {
7 | internal class AutomationsInternal : MonoBehaviour, IAutomations
8 | {
9 | private const string GameObjectName = "QonvesrionAutomationsRuntimeGameObject";
10 | private const string OnShowScreenMethodName = "OnShowScreen";
11 |
12 | private IAutomationsWrapper _nativeWrapperInstance;
13 | private AutomationsDelegate _automationsDelegate;
14 |
15 | private Automations.OnShowScreenResponseReceived ShowScreenResponseReceivedCallback { get; set; }
16 |
17 | public static AutomationsInternal CreateInstance()
18 | {
19 | GameObject go = new GameObject(GameObjectName);
20 | AutomationsInternal instance = go.AddComponent();
21 | DontDestroyOnLoad(go);
22 |
23 | return instance;
24 | }
25 |
26 | public void SetDelegate(AutomationsDelegate automationsDelegate)
27 | {
28 | _automationsDelegate = automationsDelegate;
29 |
30 | IAutomationsWrapper instance = GetNativeWrapper();
31 | instance.SubscribeOnAutomationEvents();
32 | }
33 |
34 | public void SetNotificationsToken(string token)
35 | {
36 | IAutomationsWrapper instance = GetNativeWrapper();
37 | instance.SetNotificationsToken(token);
38 | }
39 |
40 | public bool HandleNotification(Dictionary notification)
41 | {
42 | IAutomationsWrapper instance = GetNativeWrapper();
43 | return instance.HandleNotification(notification.toJson());
44 | }
45 |
46 | public Dictionary GetNotificationCustomPayload(Dictionary notification)
47 | {
48 | IAutomationsWrapper instance = GetNativeWrapper();
49 | var payloadJson = instance.GetNotificationCustomPayload(notification.toJson());
50 |
51 | if (payloadJson == null)
52 | {
53 | return null;
54 | }
55 |
56 | if (!(Json.Deserialize(payloadJson) is Dictionary response))
57 | {
58 | Debug.LogError("Could not parse custom notification payload.");
59 | return null;
60 | }
61 |
62 | return response;
63 | }
64 |
65 | public void ShowScreen(string screenId, Automations.OnShowScreenResponseReceived callback)
66 | {
67 | ShowScreenResponseReceivedCallback = callback;
68 |
69 | IAutomationsWrapper instance = GetNativeWrapper();
70 | instance.ShowScreen(screenId, OnShowScreenMethodName);
71 | }
72 |
73 | public void SetScreenPresentationConfig(ScreenPresentationConfig config, string screenId = null)
74 | {
75 | IAutomationsWrapper instance = GetNativeWrapper();
76 | instance.SetScreenPresentationConfig(config.ToJson(), screenId);
77 | }
78 |
79 | private IAutomationsWrapper GetNativeWrapper()
80 | {
81 | if (_nativeWrapperInstance != null)
82 | {
83 | return _nativeWrapperInstance;
84 | }
85 |
86 | switch (Application.platform)
87 | {
88 | case RuntimePlatform.Android:
89 | _nativeWrapperInstance = new AutomationsWrapperAndroid();
90 | break;
91 | case RuntimePlatform.IPhonePlayer:
92 | _nativeWrapperInstance = new AutomationsWrapperIOS();
93 | break;
94 | default:
95 | _nativeWrapperInstance = new AutomationsWrapperNoop();
96 | break;
97 | }
98 | _nativeWrapperInstance.Initialize(GameObjectName);
99 |
100 | return _nativeWrapperInstance;
101 | }
102 |
103 | // The below methods are called from native when Automations events occur
104 | private void OnAutomationsScreenShown(string jsonString)
105 | {
106 | if (_automationsDelegate == null)
107 | {
108 | return;
109 | }
110 |
111 | string screenId = Mapper.ScreenIdFromJson(jsonString);
112 |
113 | _automationsDelegate.OnAutomationsScreenShown(screenId);
114 | }
115 |
116 | private void OnAutomationsActionStarted(string jsonString)
117 | {
118 | if (_automationsDelegate == null)
119 | {
120 | return;
121 | }
122 |
123 | ActionResult actionResult = Mapper.ActionResultFromJson(jsonString);
124 | _automationsDelegate.OnAutomationsActionStarted(actionResult);
125 | }
126 |
127 | private void OnAutomationsActionFailed(string jsonString)
128 | {
129 | if (_automationsDelegate == null)
130 | {
131 | return;
132 | }
133 |
134 | ActionResult actionResult = Mapper.ActionResultFromJson(jsonString);
135 | _automationsDelegate.OnAutomationsActionFailed(actionResult);
136 | }
137 |
138 |
139 | private void OnAutomationsActionFinished(string jsonString)
140 | {
141 | if (_automationsDelegate == null)
142 | {
143 | return;
144 | }
145 |
146 | ActionResult actionResult = Mapper.ActionResultFromJson(jsonString);
147 | _automationsDelegate.OnAutomationsActionFinished(actionResult);
148 | }
149 |
150 | private void OnAutomationsFinished(string jsonString)
151 | {
152 | if (_automationsDelegate == null)
153 | {
154 | return;
155 | }
156 |
157 | _automationsDelegate.OnAutomationsFinished();
158 | }
159 |
160 | private void OnShowScreen(string jsonString)
161 | {
162 | var error = Mapper.ErrorFromJson(jsonString);
163 | ShowScreenResponseReceivedCallback(error);
164 | ShowScreenResponseReceivedCallback = null;
165 | }
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/AutomationsInternal.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c4a786ad04fb4a94b86844c34f317f23
3 | timeCreated: 1668753627
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | internal static class Constants
4 | {
5 | public const int PriceMicrosRatio = 1000000;
6 | }
7 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/Constants.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5ea3fffc4c6514bbdbdce589ee67f561
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/Mapper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c9bbffdaa971c4956be8e45ffcd4b28a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/QonversionInternal.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 38c50778583feeb4da0934f2fa914b96
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | internal static class Utils
5 | {
6 | internal static DateTime FormatDate(long time)
7 | {
8 | DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(time);
9 |
10 | return dateTimeOffset.DateTime.ToLocalTime();
11 | }
12 |
13 | internal static string PrintObjectList(List objectsToPrint)
14 | {
15 | if (objectsToPrint == null) return "";
16 |
17 | string result = string.Empty;
18 | foreach (T val in objectsToPrint)
19 | {
20 | if (val != null) result += val.ToString();
21 | }
22 |
23 | return result;
24 | }
25 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/Utils.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7e1c5a8d202334384887efe986d70d57
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bc8c98aad7534db3bf2a3733e1e9b9eb
3 | timeCreated: 1668776043
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/automations.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d39ad171d37c4033a7b7a4c23c0ea18a
3 | timeCreated: 1668776048
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | internal class AutomationsWrapperNoop : IAutomationsWrapper
4 | {
5 | public void Initialize(string gameObjectName)
6 | {
7 | }
8 |
9 | public void SetNotificationsToken(string token)
10 | {
11 | }
12 |
13 | public bool HandleNotification(string notification)
14 | {
15 | return false;
16 | }
17 |
18 | public string GetNotificationCustomPayload(string notification)
19 | {
20 | return null;
21 | }
22 |
23 | public void SubscribeOnAutomationEvents()
24 | {
25 | }
26 |
27 | public void ShowScreen(string screenId, string callbackName)
28 | {
29 | }
30 |
31 | public void SetScreenPresentationConfig(string configJson, string screenId)
32 | {
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: efc8a0074ad9d48879dfbbec563b3225
3 | timeCreated: 1668776080
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace QonversionUnity
4 | {
5 | internal interface IAutomationsWrapper
6 | {
7 | void Initialize(string gameObjectName);
8 | void SetNotificationsToken(string token);
9 | bool HandleNotification(string notification);
10 | [CanBeNull] string GetNotificationCustomPayload(string notification);
11 | void SubscribeOnAutomationEvents();
12 | void ShowScreen(string screenId, string callbackName);
13 | void SetScreenPresentationConfig(string configJson, [CanBeNull] string screenId);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e55580a6da23457280c02026ad96b05d
3 | timeCreated: 1668776004
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/qonversion.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b14757828b514a959d4e299c27c50782
3 | timeCreated: 1668776059
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace QonversionUnity
5 | {
6 | internal interface IQonversionWrapper
7 | {
8 | void Initialize(string gameObjectName);
9 | void InitializeSdk(string projectKey, string launchMode, [CanBeNull] string environment, [CanBeNull] string entitlementsCacheLifetime, [CanBeNull] string proxyUrl, bool kidsMode);
10 | void StoreSdkInfo(string version, string source);
11 | void SyncHistoricalData();
12 | void SyncStoreKit2Purchases();
13 | void SetAdvertisingID();
14 | void SetUserProperty(UserPropertyKey key, string value);
15 | void SetCustomUserProperty(string key, string value);
16 | void UserProperties(string callbackName);
17 | void SyncPurchases();
18 | void AddAttributionData(string conversionData, string providerName);
19 | void CheckEntitlements(string callbackName);
20 | void GetPromotionalOffer(string productId, string discountId, string callbackName);
21 | void Purchase(string productId, PurchaseOptions purchaseOptions, string callbackName);
22 | void Purchase(PurchaseModel purchaseModel, string callbackName);
23 | void Restore(string callbackName);
24 | void UpdatePurchase(PurchaseUpdateModel purchaseUpdateModel, string callbackName);
25 | void Products(string callbackName);
26 | void Offerings(string callbackName);
27 | void RemoteConfig([CanBeNull] string contextKey, string callbackName);
28 | void RemoteConfigList(string callbackName);
29 | void RemoteConfigList(string contextKeysJson, bool includeEmptyContextKey, string callbackName);
30 | void AttachUserToExperiment(string experimentId, string groupId, string callbackName);
31 | void DetachUserFromExperiment(string experimentId, string callbackName);
32 | void AttachUserToRemoteConfiguration(string remoteConfigurationId, string callbackName);
33 | void DetachUserFromRemoteConfiguration(string remoteConfigurationId, string callbackName);
34 | void IsFallbackFileAccessible(string callbackName);
35 | void CheckTrialIntroEligibility(string productIdsJson, string callbackName);
36 | void SetAppleSearchAdsAttributionEnabled(bool enable);
37 | void Identify(string userID, string callbackName);
38 | void Logout();
39 | void UserInfo(string callbackName);
40 | void PromoPurchase(string storeProductId, string callbackName);
41 | void PresentCodeRedemptionSheet();
42 | }
43 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f8a6901a4a36fb14dbb0c19d2093caf3
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs:
--------------------------------------------------------------------------------
1 | namespace QonversionUnity
2 | {
3 | internal class QonversionWrapperNoop : IQonversionWrapper
4 | {
5 | public void Initialize(string gameObjectName)
6 | {
7 | }
8 |
9 | public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime,
10 | string proxyUrl, bool kidsMode)
11 | {
12 | }
13 |
14 | public void SyncHistoricalData()
15 | {
16 | }
17 |
18 | public void SyncStoreKit2Purchases()
19 | {
20 | }
21 |
22 | public void SetUserProperty(UserPropertyKey key, string value)
23 | {
24 | }
25 |
26 | public void SetCustomUserProperty(string key, string value)
27 | {
28 | }
29 |
30 | public void UserProperties(string callbackName)
31 | {
32 | }
33 |
34 | public void AddAttributionData(string conversionData, string providerName)
35 | {
36 | }
37 |
38 | public void SyncPurchases()
39 | {
40 | }
41 |
42 | public void SetAdvertisingID()
43 | {
44 | }
45 |
46 | public void CheckEntitlements(string callbackName)
47 | {
48 | }
49 |
50 | public void GetPromotionalOffer(string productId, string discountId, string callbackName)
51 | {
52 | }
53 |
54 | public void Purchase(PurchaseModel purchaseModel, string callbackName)
55 | {
56 | }
57 |
58 | public void Purchase(string productId, PurchaseOptions purchaseOptions, string callbackName)
59 | {
60 | }
61 |
62 | public void Restore(string callbackName)
63 | {
64 | }
65 |
66 | public void UpdatePurchase(PurchaseUpdateModel purchaseUpdateModel, string callbackName)
67 | {
68 | }
69 |
70 | public void Products(string callbackName)
71 | {
72 | }
73 |
74 | public void Offerings(string callbackName)
75 | {
76 | }
77 |
78 | public void RemoteConfig(string contextKey, string callbackName)
79 | {
80 | }
81 |
82 | public void RemoteConfigList(string callbackName)
83 | {
84 | }
85 |
86 | public void RemoteConfigList(string contextKeysJson, bool includeEmptyContextKey, string callbackName)
87 | {
88 | }
89 |
90 | public void AttachUserToExperiment(string experimentId, string groupId, string callbackName)
91 | {
92 | }
93 |
94 | public void DetachUserFromExperiment(string experimentId, string callbackName)
95 | {
96 | }
97 |
98 | public void AttachUserToRemoteConfiguration(string remoteConfigurationId, string callbackName)
99 | {
100 | }
101 |
102 | public void DetachUserFromRemoteConfiguration(string remoteConfigurationId, string callbackName)
103 | {
104 | }
105 |
106 | public void IsFallbackFileAccessible(string callbackName)
107 | {
108 | }
109 |
110 | public void StoreSdkInfo(string version, string source)
111 | {
112 | }
113 |
114 | public void CheckTrialIntroEligibility(string productIdsJson, string callbackName)
115 | {
116 | }
117 |
118 | public void SetAppleSearchAdsAttributionEnabled(bool enable)
119 | {
120 | }
121 |
122 | public void Identify(string userID, string callbackName)
123 | {
124 | }
125 |
126 | public void Logout()
127 | {
128 | }
129 |
130 | public void UserInfo(string callbackName)
131 | {
132 | }
133 |
134 | public void PromoPurchase(string storeProductId, string callbackName)
135 | {
136 | }
137 |
138 | public void PresentCodeRedemptionSheet()
139 | {
140 | }
141 | }
142 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1ba1c72708b384965890bb327159ac57
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Qonversion.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 |
5 | namespace QonversionUnity
6 | {
7 | public static class Qonversion
8 | {
9 | [CanBeNull] private static volatile IQonversion _backingInstance;
10 | private static object _syncRoot = new Object();
11 |
12 | ///
13 | /// Use this variable to get a current initialized instance of the Qonversion SDK.
14 | /// Please, use the property only after calling .
15 | /// Otherwise, trying to access the variable will cause an exception.
16 | ///
17 | /// Current initialized instance of the Qonversion SDK.
18 | /// throws exception if the instance has not been initialized
19 | public static IQonversion GetSharedInstance()
20 | {
21 | if (_backingInstance == null)
22 | {
23 | throw new Exception(
24 | "Qonversion has not been initialized. You should call " +
25 | "the initialize method before accessing the shared instance of Qonversion."
26 | );
27 | }
28 |
29 | return _backingInstance;
30 | }
31 |
32 | ///
33 | /// An entry point to use Qonversion SDK. Call to initialize Qonversion SDK with required and extra configs.
34 | /// The function is the best way to set additional configs you need to use Qonversion SDK.
35 | /// You still have an option to set a part of additional configs later via calling separate setters.
36 | ///
37 | /// a config that contains key SDK settings.
38 | /// Call to configure and create a QonversionConfig instance.
39 | /// Initialized instance of the Qonversion SDK.
40 | public static IQonversion Initialize(QonversionConfig config)
41 | {
42 | if (_backingInstance == null)
43 | {
44 | lock (_syncRoot)
45 | {
46 | if (_backingInstance == null)
47 | {
48 | IQonversion instance = QonversionInternal.CreateInstance();
49 | instance.InitializeInstance(config);
50 |
51 | _backingInstance = instance;
52 | }
53 | }
54 | }
55 |
56 | return _backingInstance;
57 | }
58 |
59 | public delegate void OnPurchaseResultReceived(Dictionary entitlements, QonversionError error, bool isCancelled);
60 | public delegate void OnEntitlementsReceived(Dictionary entitlements, QonversionError error);
61 | public delegate void OnProductsReceived(Dictionary products, QonversionError error);
62 | public delegate void OnOfferingsReceived(Offerings offerings, QonversionError error);
63 | public delegate void OnRemoteConfigReceived(RemoteConfig remoteConfig, QonversionError error);
64 | public delegate void OnRemoteConfigListReceived(RemoteConfigList remoteConfigList, QonversionError error);
65 | public delegate void OnUserPropertiesReceived(UserProperties userProperties, QonversionError error);
66 | public delegate void OnAttachUserResponseReceived(bool success, QonversionError error);
67 | public delegate void OnEligibilitiesReceived(Dictionary eligibilities, QonversionError error);
68 | public delegate void OnUserInfoReceived(User userInfo, QonversionError error);
69 | public delegate void OnFallbackFileAccessibilityResponseReceived(bool success);
70 | public delegate void OnPromotionalOfferReceived(PromotionalOffer promotionalOffer, QonversionError error);
71 |
72 | ///
73 | /// Delegate fires each time a promo purchase from the App Store happens.
74 | /// Be sure you define a delegate for the event .
75 | /// Call StartPromoPurchase in case of your app is ready to start promo purchase.
76 | /// Or cache that delegate and call later when you need.
77 | ///
78 | /// StoreKit product identifier
79 | /// A delegate that will start a promo purchase flow.
80 | ///
81 | ///
82 | public delegate void OnPromoPurchasesReceived(string productId, StartPromoPurchase purchaseDelegate);
83 |
84 | ///
85 | /// Call the function if your app can handle a promo purchase at the current time.
86 | /// Or you can cache the delegate, and call it when the app is ready to make the purchase.
87 | ///
88 | /// Callback that will be called when response is received. Returns entitlements or potentially a QonversionError.
89 | ///
90 | ///
91 | public delegate void StartPromoPurchase(OnEntitlementsReceived callback);
92 |
93 | ///
94 | /// Delegate fires each time a user entitlements change asynchronously,
95 | /// for example, when pending purchases like SCA, Ask to buy, etc., happen.
96 | ///
97 | public delegate void OnUpdatedEntitlementsReceived(Dictionary entitlements);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Runtime/Scripts/Qonversion.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3d153a0da53e4ab38cd2815b94987e82
3 | timeCreated: 1668681655
--------------------------------------------------------------------------------
/Runtime/Scripts/QonversionConfig.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class QonversionConfig
6 | {
7 | public readonly string ProjectKey;
8 | public readonly LaunchMode LaunchMode;
9 | public readonly Environment Environment;
10 | public readonly EntitlementsCacheLifetime EntitlementsCacheLifetime;
11 | [CanBeNull] public readonly string ProxyUrl;
12 | public readonly bool KidsMode;
13 |
14 | public QonversionConfig(
15 | string projectKey,
16 | LaunchMode launchMode,
17 | Environment environment,
18 | EntitlementsCacheLifetime entitlementsCacheLifetime,
19 | [CanBeNull] string proxyUrl,
20 | bool kidsMode
21 | )
22 | {
23 | ProjectKey = projectKey;
24 | LaunchMode = launchMode;
25 | Environment = environment;
26 | EntitlementsCacheLifetime = entitlementsCacheLifetime;
27 | ProxyUrl = proxyUrl;
28 | KidsMode = kidsMode;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/QonversionConfig.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 081671b389ce42258e66635391aa5c2f
3 | timeCreated: 1668682590
--------------------------------------------------------------------------------
/Runtime/Scripts/QonversionConfigBuilder.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace QonversionUnity
4 | {
5 | public class QonversionConfigBuilder
6 | {
7 | private readonly string _projectKey;
8 | private readonly LaunchMode _launchMode;
9 | private Environment _environment = Environment.Production;
10 | private EntitlementsCacheLifetime _entitlementsCacheLifetime = EntitlementsCacheLifetime.Month;
11 | [CanBeNull] private string _proxyUrl = null;
12 | private bool _kidsMode = false;
13 |
14 | public QonversionConfigBuilder(string projectKey, LaunchMode launchMode)
15 | {
16 | _projectKey = projectKey;
17 | _launchMode = launchMode;
18 | }
19 |
20 | ///
21 | /// Set current application . Used to distinguish sandbox and production users.
22 | ///
23 | /// current environment.
24 | /// builder instance for chain calls.
25 | public QonversionConfigBuilder SetEnvironment(Environment environment)
26 | {
27 | _environment = environment;
28 | return this;
29 | }
30 |
31 | ///
32 | /// Entitlements cache is used when there are problems with the Qonversion API
33 | /// or internet connection. If so, Qonversion will return the last successfully loaded
34 | /// entitlements. The current method allows you to configure how long that cache may be used.
35 | /// The default value is .
36 | ///
37 | /// desired entitlements cache lifetime duration.
38 | /// builder instance for chain calls.
39 | public QonversionConfigBuilder SetEntitlementsCacheLifetime(EntitlementsCacheLifetime lifetime)
40 | {
41 | _entitlementsCacheLifetime = lifetime;
42 | return this;
43 | }
44 |
45 | ///
46 | /// Provide a URL to your proxy server which will redirect all the requests from the app
47 | /// to our API. Please, contact us before using this feature.
48 | ///
49 | /// your proxy server url.
50 | /// builder instance for chain calls.
51 | ///
52 | public QonversionConfigBuilder SetProxyURL(string url)
53 | {
54 | _proxyUrl = url;
55 | return this;
56 | }
57 |
58 | ///
59 | /// Android only.
60 | /// Use this function to enable Qonversion SDK Kids mode.
61 | /// With this mode activated, our SDK does not collect any information that violates Google Children’s Privacy Policy.
62 | ///
63 | /// builder instance for chain calls.
64 | public QonversionConfigBuilder EnableKidsMode()
65 | {
66 | _kidsMode = true;
67 | return this;
68 | }
69 |
70 | ///
71 | /// Generate instance with all the provided configurations.
72 | ///
73 | /// the complete instance.
74 | public QonversionConfig Build()
75 | {
76 | return new QonversionConfig(
77 | _projectKey,
78 | _launchMode,
79 | _environment,
80 | _entitlementsCacheLifetime,
81 | _proxyUrl,
82 | _kidsMode
83 | );
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/Runtime/Scripts/QonversionConfigBuilder.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e965105671494d86988de6e150a1a2a3
3 | timeCreated: 1668683063
--------------------------------------------------------------------------------
/Runtime/iOS.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 12ddc0ad3eba449488e2184ea69f2006
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/iOS/AutomationsWrapperIOS.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_IOS
2 | using System.Runtime.InteropServices;
3 | #endif
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using JetBrains.Annotations;
8 | using UnityEngine;
9 |
10 | namespace QonversionUnity
11 | {
12 | internal class AutomationsWrapperIOS : IAutomationsWrapper
13 | {
14 | #if UNITY_IOS
15 | [DllImport("__Internal")]
16 | private static extern void _initializeAutomations(string gameObjectName);
17 |
18 | [DllImport("__Internal")]
19 | private static extern void _setNotificationsToken(string token);
20 |
21 | [DllImport("__Internal")]
22 | private static extern bool _handleNotification(string notification);
23 |
24 | [DllImport("__Internal")]
25 | private static extern string _getNotificationCustomPayload(string notification);
26 |
27 | [DllImport("__Internal")]
28 | private static extern void _subscribeOnAutomationEvents();
29 |
30 | [DllImport("__Internal")]
31 | private static extern void _showScreen(string screenId, string callbackName);
32 |
33 | [DllImport("__Internal")]
34 | private static extern void _setScreenPresentationConfig(string configJson, [CanBeNull] string screenId);
35 | #endif
36 |
37 | public void Initialize(string gameObjectName)
38 | {
39 | #if UNITY_IOS
40 | _initializeAutomations(gameObjectName);
41 | #endif
42 | }
43 | public void SetNotificationsToken(string token)
44 | {
45 | #if UNITY_IOS
46 | _setNotificationsToken(token);
47 | #endif
48 | }
49 |
50 | public bool HandleNotification(string notification)
51 | {
52 | #if UNITY_IOS
53 | return _handleNotification(notification);
54 | #else
55 | return false;
56 | #endif
57 | }
58 |
59 | public string GetNotificationCustomPayload(string notification)
60 | {
61 | #if UNITY_IOS
62 | return _getNotificationCustomPayload(notification);
63 | #else
64 | return null;
65 | #endif
66 | }
67 |
68 | public void SubscribeOnAutomationEvents()
69 | {
70 | #if UNITY_IOS
71 | _subscribeOnAutomationEvents();
72 | #endif
73 | }
74 | public void ShowScreen(string screenId, string callbackName)
75 | {
76 | #if UNITY_IOS
77 | _showScreen(screenId, callbackName);
78 | #endif
79 | }
80 |
81 | public void SetScreenPresentationConfig(string configJson, string screenId)
82 | {
83 | #if UNITY_IOS
84 | _setScreenPresentationConfig(configJson, screenId);
85 | #endif
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Runtime/iOS/AutomationsWrapperIOS.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 833a9b7bdb0a43228b1153c40421e900
3 | timeCreated: 1668776223
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1f220c0e7d2a77d4ba1b6302c752a67a
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/AutomationsBridge.m:
--------------------------------------------------------------------------------
1 | #import "UtilityBridge.h"
2 | #import "QNUAutomationsDelegate.h"
3 | @import QonversionSandwich;
4 |
5 | char* automationsUnityListenerName = nil;
6 |
7 | static QNUAutomationsDelegate *automationsBridge;
8 |
9 | void _initializeAutomations(const char* unityListener) {
10 | unsigned long len = strlen(unityListener);
11 | automationsUnityListenerName = malloc(len + 1);
12 | strcpy(automationsUnityListenerName, unityListener);
13 |
14 | automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:automationsUnityListenerName];
15 | }
16 |
17 | void _setNotificationsToken(const char* token) {
18 | NSString *tokenStr = [UtilityBridge convertCStringToNSString:token];
19 | [automationsBridge setNotificationsToken:tokenStr];
20 | }
21 |
22 | bool _handleNotification(const char* notification) {
23 | NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString:[UtilityBridge convertCStringToNSString:notification]];
24 |
25 | BOOL isQonversionNotification = [automationsBridge handleNotification:notificationInfo];
26 |
27 | return isQonversionNotification;
28 | }
29 |
30 | char* _getNotificationCustomPayload(const char* notification) {
31 | NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString:[UtilityBridge convertCStringToNSString:notification]];
32 |
33 | NSDictionary *payload = [automationsBridge getNotificationCustomPayload:notificationInfo];
34 |
35 | if (payload == nil) {
36 | return nil;
37 | }
38 |
39 | const char *data = [UtilityBridge jsonStringFromObject:payload];
40 |
41 | char* cString = (char*)malloc(strlen(data) + 1);
42 | strcpy(cString, data);
43 |
44 | return cString;
45 | }
46 |
47 | void _showScreen(const char* screenId, const char* unityCallbackName) {
48 | NSString *callbackName = [UtilityBridge convertCStringToNSString:unityCallbackName];
49 | NSString *screenIdStr = [UtilityBridge convertCStringToNSString:screenId];
50 | [automationsBridge showScreenWithId:screenIdStr callbackName:callbackName];
51 | }
52 |
53 | void _subscribeOnAutomationEvents() {
54 | [automationsBridge subscribe];
55 | }
56 |
57 | void _setScreenPresentationConfig(const char* configData, const char* screenId) {
58 | NSDictionary *config = [UtilityBridge dictionaryFromJsonString:[UtilityBridge convertCStringToNSString:configData]];
59 | NSString *screenIdStr = [UtilityBridge convertCStringToNSString:screenId];
60 | [automationsBridge setScreenPresentationConfig:config screenId:screenIdStr];
61 | }
62 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/AutomationsBridge.m.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3274bd50e96104e20b153fb581760138
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Any:
16 | second:
17 | enabled: 0
18 | settings: {}
19 | - first:
20 | Editor: Editor
21 | second:
22 | enabled: 0
23 | settings:
24 | DefaultValueInitialized: true
25 | - first:
26 | iPhone: iOS
27 | second:
28 | enabled: 1
29 | settings: {}
30 | - first:
31 | tvOS: tvOS
32 | second:
33 | enabled: 1
34 | settings: {}
35 | userData:
36 | assetBundleName:
37 | assetBundleVariant:
38 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1c5765ecd60071e49a790d0145515f91
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNUAutomationsDelegate.h
3 | // Unity-iPhone
4 | //
5 | // Created by Surik Sarkisyan on 15.03.2022.
6 | //
7 |
8 | #import
9 | @import QonversionSandwich;
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface QNUAutomationsDelegate : NSObject
14 |
15 | - (instancetype)initWithListenerName:(char *)unityListenerName;
16 | - (void)subscribe;
17 | - (void)setNotificationsToken:(NSString *)token;
18 | - (BOOL)handleNotification:(NSDictionary *)notificationInfo;
19 | - (NSDictionary *)getNotificationCustomPayload:(NSDictionary *)payload;
20 | - (void)showScreenWithId:(NSString *)screenId callbackName:(NSString *)callbackName;
21 | - (void)setScreenPresentationConfig:(NSDictionary *)config screenId:(NSString *)screenId;
22 |
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 185ee14cf41c34a3ca880e5d40585f29
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Any:
16 | second:
17 | enabled: 1
18 | settings: {}
19 | - first:
20 | Editor: Editor
21 | second:
22 | enabled: 0
23 | settings:
24 | DefaultValueInitialized: true
25 | userData:
26 | assetBundleName:
27 | assetBundleVariant:
28 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNUAutomationsDelegate.m
3 | // Unity-iPhone
4 | //
5 | // Created by Surik Sarkisyan on 15.03.2022.
6 | //
7 |
8 | #import "QNUAutomationsDelegate.h"
9 | #import "UtilityBridge.h"
10 |
11 | static NSString *const kEventScreenShown = @"OnAutomationsScreenShown";
12 | static NSString *const kEventActionStarted = @"OnAutomationsActionStarted";
13 | static NSString *const kEventActionFailed = @"OnAutomationsActionFailed";
14 | static NSString *const kEventActionFinished = @"OnAutomationsActionFinished";
15 | static NSString *const kEventAutomationsFinished = @"OnAutomationsFinished";
16 |
17 | char* listenerName = nil;
18 |
19 | @interface QNUAutomationsDelegate ()
20 |
21 | @property (nonatomic, strong) AutomationsSandwich *automationsSandwich;
22 | @property (nonatomic, copy) NSDictionary *automationEvents;
23 |
24 | @end
25 |
26 | @implementation QNUAutomationsDelegate
27 |
28 | - (instancetype)initWithListenerName:(char *)unityListenerName {
29 | self = [super init];
30 |
31 | if (self) {
32 | listenerName = unityListenerName;
33 | _automationsSandwich = [AutomationsSandwich new];
34 | _automationEvents = @{
35 | @"automations_screen_shown": kEventScreenShown,
36 | @"automations_action_started": kEventActionStarted,
37 | @"automations_action_failed": kEventActionFailed,
38 | @"automations_action_finished": kEventActionFinished,
39 | @"automations_finished": kEventAutomationsFinished
40 | };
41 | }
42 |
43 | return self;
44 | }
45 |
46 | - (void)subscribe {
47 | [self.automationsSandwich subscribe:self];
48 | }
49 |
50 | - (void)setNotificationsToken:(NSString *)token {
51 | [self.automationsSandwich setNotificationToken:token];
52 | }
53 |
54 | - (BOOL)handleNotification:(NSDictionary *)notificationInfo {
55 | return [self.automationsSandwich handleNotification:notificationInfo];
56 | }
57 |
58 | - (NSDictionary *)getNotificationCustomPayload:(NSDictionary *)payload {
59 | return [self.automationsSandwich getNotificationCustomPayload:payload];
60 | }
61 |
62 | - (void)automationDidTriggerWithEvent:(NSString * _Nonnull)event payload:(NSDictionary * _Nullable)payload {
63 | NSString *methodName = self.automationEvents[event];
64 |
65 | [UtilityBridge sendUnityMessage:payload ?: @{} toMethod:methodName unityListener: listenerName];
66 | }
67 |
68 | - (void)showScreenWithId:(NSString *)screenId callbackName:(NSString *)callbackName {
69 | [self.automationsSandwich showScreen:screenId completion:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) {
70 | [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:listenerName];
71 | }];
72 | }
73 |
74 | - (void)setScreenPresentationConfig:(NSDictionary *)config screenId:(NSString *)screenId {
75 | [self.automationsSandwich setScreenPresentationConfig:config forScreenId:screenId];
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3539a63d5587c4502ad192926adb131c
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Any:
16 | second:
17 | enabled: 0
18 | settings: {}
19 | - first:
20 | Editor: Editor
21 | second:
22 | enabled: 0
23 | settings:
24 | DefaultValueInitialized: true
25 | - first:
26 | iPhone: iOS
27 | second:
28 | enabled: 1
29 | settings: {}
30 | - first:
31 | tvOS: tvOS
32 | second:
33 | enabled: 1
34 | settings: {}
35 | userData:
36 | assetBundleName:
37 | assetBundleVariant:
38 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/UtilityBridge.h:
--------------------------------------------------------------------------------
1 | #import
2 | @import QonversionSandwich;
3 |
4 | @interface UtilityBridge : NSObject
5 |
6 | + (NSString*)convertCStringToNSString:(const char *)string;
7 | + (NSDictionary*)dictionaryFromJsonString:(NSString*) jsonString;
8 | + (NSArray*)arrayFromJsonString:(NSString*) jsonString;
9 | + (NSDictionary *)serializeErrorWithCode:(NSString *)code
10 | domain:(NSString *)domain
11 | description:(NSString *)description
12 | additionalMessage:(NSString *)additionalMessage;
13 | + (NSDictionary *)serializeSandwichError:(SandwichError *)error;
14 | + (const char *)jsonStringFromObject:(NSObject *)objectToConvert;
15 |
16 | + (void)sendUnityMessage:(NSObject *)objectToConvert toMethod:(NSString *)methodName
17 | unityListener:(const char *)unityListenerName;
18 |
19 | + (void)handleErrorResponse:(SandwichError *)error toMethod:(NSString *)methodName
20 | unityListener:(const char *)unityListenerName;
21 | + (void)handleLocalError:(NSError *)error
22 | message:(NSString *)message
23 | toMethod:(NSString *)methodName
24 | unityListener:(const char *)unityListenerName;
25 | + (void)handleResult:(NSDictionary *)result
26 | error:(SandwichError *)error
27 | callbackName:(NSString *)callbackName
28 | unityListener:(const char *)unityListenerName;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/UtilityBridge.h.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 48e3194c80281f049b6f5ba07f3b215c
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Any:
16 | second:
17 | enabled: 1
18 | settings: {}
19 | - first:
20 | Editor: Editor
21 | second:
22 | enabled: 0
23 | settings:
24 | DefaultValueInitialized: true
25 | userData:
26 | assetBundleName:
27 | assetBundleVariant:
28 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/UtilityBridge.m:
--------------------------------------------------------------------------------
1 | #import "UtilityBridge.h"
2 |
3 | static NSString *const nativeModuleErrorCode = @"NativeModuleError";
4 |
5 | @implementation UtilityBridge
6 |
7 | + (NSString*)convertCStringToNSString:(const char *)string {
8 | if (string == NULL) {
9 | return nil;
10 | }
11 |
12 | return [NSString stringWithUTF8String:string];
13 | }
14 |
15 | + (NSDictionary*)dictionaryFromJsonString:(NSString*) jsonString {
16 | if (!jsonString) {
17 | return @{};
18 | }
19 |
20 | NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
21 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
22 |
23 | return dictionary;
24 | }
25 |
26 | + (NSArray*)arrayFromJsonString:(NSString*) jsonString {
27 | if (!jsonString) {
28 | return @[];
29 | }
30 |
31 | NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
32 | NSArray *array = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
33 |
34 | return array;
35 | }
36 |
37 | + (NSDictionary *)serializeErrorWithCode:(NSString *)code
38 | domain:(NSString *)domain
39 | description:(NSString *)description
40 | additionalMessage:(NSString *)additionalMessage {
41 | NSMutableDictionary *errorDict = [NSMutableDictionary new];
42 | errorDict[@"code"] = code;
43 | errorDict[@"domain"] = domain;
44 | errorDict[@"description"] = description;
45 | errorDict[@"additionalMessage"] = additionalMessage;
46 |
47 | NSMutableDictionary *result = [NSMutableDictionary new];
48 | result[@"error"] = errorDict;
49 |
50 | return [result copy];
51 | }
52 |
53 | + (NSDictionary *)serializeSandwichError:(SandwichError *)error {
54 | NSDictionary *errorDict = [UtilityBridge serializeErrorWithCode:error.code
55 | domain:error.domain
56 | description:error.details
57 | additionalMessage:error.additionalMessage];
58 |
59 | return [errorDict copy];
60 | }
61 |
62 | + (void)handleErrorResponse:(SandwichError *)error toMethod:(NSString *)methodName
63 | unityListener:(const char *)unityListenerName {
64 | NSDictionary *errorDict = [UtilityBridge serializeSandwichError:error];
65 | [UtilityBridge sendUnityMessage:errorDict toMethod:methodName unityListener:unityListenerName];
66 | }
67 |
68 | + (void)handleLocalError:(NSError *)error
69 | message:(NSString *)message
70 | toMethod:(NSString *)methodName
71 | unityListener:(const char *)unityListenerName {
72 | NSDictionary *errorDict = [UtilityBridge serializeErrorWithCode:nativeModuleErrorCode
73 | domain:error.domain
74 | description:message
75 | additionalMessage:error.localizedDescription];
76 | [UtilityBridge sendUnityMessage:errorDict toMethod:methodName unityListener:unityListenerName];
77 | }
78 |
79 | + (const char *)jsonStringFromObject:(NSObject *)objectToConvert {
80 | if (objectToConvert == nil) {
81 | return nil;
82 | }
83 |
84 | NSError *error = nil;
85 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:objectToConvert options:0 error:&error];
86 |
87 | if (error) {
88 | NSLog(@"An error occurred while serializing data: %@", error.localizedDescription);
89 | return nil;
90 | }
91 |
92 | if (jsonData) {
93 | NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
94 | return json.UTF8String;
95 | }
96 | return nil;
97 | }
98 |
99 | + (void)sendUnityMessage:(NSObject *)objectToConvert
100 | toMethod:(NSString *)methodName
101 | unityListener:(const char *)unityListenerName {
102 | const char *data = [UtilityBridge jsonStringFromObject:objectToConvert];
103 |
104 | if (data) {
105 | UnitySendMessage(unityListenerName, methodName.UTF8String, data);
106 | }
107 | return;
108 | }
109 |
110 | + (void)handleResult:(NSDictionary *)result
111 | error:(SandwichError *)error
112 | callbackName:(NSString *)callbackName
113 | unityListener:(const char *)unityListenerName {
114 | if (error) {
115 | [UtilityBridge handleErrorResponse:error toMethod:callbackName unityListener:unityListenerName];
116 | } else {
117 | [UtilityBridge sendUnityMessage:result toMethod:callbackName unityListener:unityListenerName];
118 | }
119 | }
120 |
121 | @end
122 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/Common/UtilityBridge.m.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 666fb1fa0c7e977428a9aee8f0797497
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 1
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Any:
16 | second:
17 | enabled: 0
18 | settings: {}
19 | - first:
20 | Editor: Editor
21 | second:
22 | enabled: 0
23 | settings:
24 | DefaultValueInitialized: true
25 | - first:
26 | iPhone: iOS
27 | second:
28 | enabled: 1
29 | settings: {}
30 | - first:
31 | tvOS: tvOS
32 | second:
33 | enabled: 1
34 | settings: {}
35 | userData:
36 | assetBundleName:
37 | assetBundleVariant:
38 |
--------------------------------------------------------------------------------
/Runtime/iOS/Plugins/QonversionBridge.m.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bd940853716574fd8a7a72a9a6d34390
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 0
10 | isOverridable: 0
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | Any:
16 | second:
17 | enabled: 0
18 | settings: {}
19 | - first:
20 | Editor: Editor
21 | second:
22 | enabled: 0
23 | settings:
24 | DefaultValueInitialized: true
25 | - first:
26 | iPhone: iOS
27 | second:
28 | enabled: 1
29 | settings: {}
30 | - first:
31 | tvOS: tvOS
32 | second:
33 | enabled: 1
34 | settings: {}
35 | userData:
36 | assetBundleName:
37 | assetBundleVariant:
38 |
--------------------------------------------------------------------------------
/Runtime/iOS/QonversionWrapperIOS.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c9b40e5937b479a4e8d83a389ea7e051
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/fastlane.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 089159a4944c04210aeeacfd063d3601
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qonversion/unity-sdk/fab0c8c34d3428624f14b77926eefbaf4e50dcfc/fastlane/Appfile
--------------------------------------------------------------------------------
/fastlane/Appfile.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: df504593313e54776a427d43dca4e661
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | def update_package_json(new_version)
2 | path = "../package.json"
3 | regex = /"version": ".*",/
4 | result_value = "\"version\": \"#{new_version}\","
5 |
6 | update_file(path, regex, result_value)
7 | end
8 |
9 | def update_constant(new_version)
10 | path = "../Runtime/Scripts/Internal/QonversionInternal.cs"
11 | regex = /private const string SdkVersion = ".*";/
12 | result_value = "private const string SdkVersion = \"#{new_version}\";"
13 |
14 | update_file(path, regex, result_value)
15 | end
16 |
17 | def upgrade_sandwich_android(new_version)
18 | path = "../Editor/QonversionDependencies.xml"
19 | common_part = " /
21 | result_value = "#{common_part}#{new_version}\" \/>"
22 |
23 | update_file(path, regex, result_value)
24 | end
25 |
26 | def upgrade_sandwich_ios(new_version)
27 | path = "../Editor/QonversionDependencies.xml"
28 | common_part = " /
30 | result_value = "#{common_part}#{new_version}\" \/>"
31 |
32 | update_file(path, regex, result_value)
33 | end
34 |
35 | def update_file(path, regex, result_value)
36 | file = File.read(path)
37 | new_content = file.gsub(regex, result_value)
38 | File.open(path, 'w') { |line| line.puts new_content }
39 | end
40 |
41 | def get_tag
42 | tag = last_git_tag()
43 | puts tag
44 | result_tag = tag.scan(%r{\d{1,2}.\d{1,2}.\d{1,3}}).first
45 | return result_tag
46 | end
47 |
48 | def calculate_minor_version(tag)
49 | major, minor, patch = parse_versions(tag)
50 | new_minor_version = minor.to_i.next.to_s
51 | new_version = major + "." + new_minor_version + "." + "0"
52 | return new_version
53 | end
54 |
55 | def calculate_patch_version(tag)
56 | major, minor, patch = parse_versions(tag)
57 | new_patch_version = patch.to_i.next.to_s
58 | new_version = major + "." + minor + "." + new_patch_version
59 |
60 | return new_version
61 | end
62 |
63 | def push_tag(tag)
64 | system("git checkout develop")
65 | system("git pull origin develop")
66 | add_git_tag(tag: tag)
67 | push_git_tags(tag: tag)
68 | end
69 |
70 | def parse_versions(tag)
71 | split_version_array = tag.split(".", 3)
72 |
73 | if split_version_array.length == 3
74 | major = split_version_array[0]
75 | minor = split_version_array[1]
76 | patch = split_version_array[2]
77 |
78 | return major, minor, patch
79 | end
80 | end
81 |
82 | lane :patch do
83 | tag = get_tag
84 | new_version = calculate_patch_version(tag)
85 | new_tag = "prerelease/" + new_version
86 | push_tag(new_tag)
87 | end
88 |
89 | lane :minor do
90 | tag = get_tag
91 | new_version = calculate_minor_version(tag)
92 | new_tag = "prerelease/" + new_version
93 | push_tag(new_tag)
94 | end
95 |
96 | lane :bump do |options|
97 | new_version = options[:version]
98 |
99 | update_package_json(new_version)
100 | update_constant(new_version)
101 | end
102 |
103 | lane :upgrade_sandwich do |options|
104 | new_version = options[:version]
105 |
106 | upgrade_sandwich_android(new_version)
107 | upgrade_sandwich_ios(new_version)
108 | end
109 |
110 | lane :provide_next_patch_version do
111 | tag = get_tag
112 | new_version = calculate_patch_version(tag)
113 | sh("echo version=#{new_version} >> \"$GITHUB_ENV\"")
114 | end
115 |
--------------------------------------------------------------------------------
/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ----
3 |
4 | # Installation
5 |
6 | Make sure you have the latest version of the Xcode command line tools installed:
7 |
8 | ```sh
9 | xcode-select --install
10 | ```
11 |
12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
13 |
14 | # Available Actions
15 |
16 | ### patch
17 |
18 | ```sh
19 | [bundle exec] fastlane patch
20 | ```
21 |
22 |
23 |
24 | ### minor
25 |
26 | ```sh
27 | [bundle exec] fastlane minor
28 | ```
29 |
30 |
31 |
32 | ### bump
33 |
34 | ```sh
35 | [bundle exec] fastlane bump
36 | ```
37 |
38 |
39 |
40 | ### upgrade_sandwich
41 |
42 | ```sh
43 | [bundle exec] fastlane upgrade_sandwich
44 | ```
45 |
46 |
47 |
48 | ### provide_next_patch_version
49 |
50 | ```sh
51 | [bundle exec] fastlane provide_next_patch_version
52 | ```
53 |
54 |
55 |
56 | ----
57 |
58 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
59 |
60 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
61 |
62 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
63 |
--------------------------------------------------------------------------------
/fastlane/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0f7d66a11e8894098917aa1f4ef1507a
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/fastlane/fastfile.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0490d362f09d34421838ef526cb8839d
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/fastlane/report.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/fastlane/report.xml.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ce3590874b3444ee79db9c2164fd95be
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/img.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 48c2b6eb637629f45a1e09fdfab22448
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/img/UnityQonversionLauncher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qonversion/unity-sdk/fab0c8c34d3428624f14b77926eefbaf4e50dcfc/img/UnityQonversionLauncher.png
--------------------------------------------------------------------------------
/img/UnityQonversionLauncher.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 721fa4cd076d647b7a88c24f5c0e1aec
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 1
40 | wrapV: 1
41 | wrapW: 1
42 | nPOTScale: 0
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 1
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 1
55 | spriteTessellationDetail: -1
56 | textureType: 8
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | platformSettings:
67 | - serializedVersion: 3
68 | buildTarget: DefaultTexturePlatform
69 | maxTextureSize: 2048
70 | resizeAlgorithm: 0
71 | textureFormat: -1
72 | textureCompression: 1
73 | compressionQuality: 50
74 | crunchedCompression: 0
75 | allowsAlphaSplitting: 0
76 | overridden: 0
77 | androidETC2FallbackOverride: 0
78 | forceMaximumCompressionQuality_BC6H_BC7: 0
79 | spriteSheet:
80 | serializedVersion: 2
81 | sprites: []
82 | outline: []
83 | physicsShape: []
84 | bones: []
85 | spriteID: 5e97eb03825dee720800000000000000
86 | internalID: 0
87 | vertices: []
88 | indices:
89 | edges: []
90 | weights: []
91 | secondaryTextures: []
92 | nameFileIdTable: {}
93 | spritePackingTag:
94 | pSDRemoveMatte: 0
95 | pSDShowRemoveMatteOption: 0
96 | userData:
97 | assetBundleName:
98 | assetBundleVariant:
99 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "com.qonversion.unity",
3 | "displayName": "Qonversion",
4 | "version": "8.2.0",
5 | "unity": "2018.3",
6 | "description": "Empower your mobile app marketing and product decisions with precise subscription data.",
7 | "author": {
8 | "name": "qonversion.io",
9 | "url": "https://github.com/qonversion/unity-sdk"
10 | },
11 | "keywords": [
12 | "unity",
13 | "qonversion",
14 | "ios",
15 | "android",
16 | "apple",
17 | "subscription",
18 | "analytics",
19 | "iap",
20 | "purchase"
21 | ],
22 | "category": "Unity",
23 | "files": [
24 | "/README.md",
25 | "/README.md.meta",
26 | "/package.json",
27 | "/package.json.meta",
28 | "/Runtime",
29 | "/Runtime.meta",
30 | "/Editor",
31 | "/Editor.meta"
32 | ],
33 | "dependencies": {}
34 | }
35 |
--------------------------------------------------------------------------------
/package.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e77a923a5f798344db5fb608a5876fed
3 | PackageManifestImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------