@@ -2,9 +2,11 @@ package com.qonversion.flutter.sdk.qonversion_flutter_sdk
22
33import android.app.Activity
44import android.app.Application
5+ import android.util.Log
56import androidx.annotation.NonNull
67import androidx.preference.PreferenceManager
78import com.google.gson.Gson
9+ import com.google.gson.JsonSyntaxException
810import com.qonversion.android.sdk.*
911import com.qonversion.android.sdk.dto.QLaunchResult
1012import com.qonversion.android.sdk.dto.QPermission
@@ -20,6 +22,7 @@ import io.flutter.plugin.common.MethodChannel
2022import io.flutter.plugin.common.MethodChannel.MethodCallHandler
2123import io.flutter.plugin.common.MethodChannel.Result
2224import io.flutter.plugin.common.PluginRegistry.Registrar
25+ import java.lang.Exception
2326
2427/* * QonversionFlutterSdkPlugin */
2528class QonversionFlutterSdkPlugin : MethodCallHandler , FlutterPlugin , ActivityAware {
@@ -93,10 +96,6 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
9396 Qonversion .logout()
9497 return result.success(null )
9598 }
96- " resetUser" -> {
97- Qonversion .resetUser()
98- return result.success(null )
99- }
10099 }
101100
102101 // Methods with args
@@ -106,7 +105,9 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
106105 when (call.method) {
107106 " launch" -> launch(args, result)
108107 " purchase" -> purchase(args[" productId" ] as ? String , result)
108+ " purchaseProduct" -> purchaseProduct(args[" product" ] as ? String , result)
109109 " updatePurchase" -> updatePurchase(args, result)
110+ " updatePurchaseWithProduct" -> updatePurchaseWithProduct(args, result)
110111 " setUserId" -> setUserId(args[" userId" ] as ? String , result)
111112 " setProperty" -> setProperty(args, result)
112113 " setUserProperty" -> setUserProperty(args, result)
@@ -162,43 +163,71 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
162163
163164 private fun purchase (productId : String? , result : Result ) {
164165 if (productId == null ) {
165- result.noProductIdError()
166- return
166+ return result.noProductIdError()
167167 }
168168
169- activity?.let { activity ->
170- Qonversion .purchase(activity, productId, callback = object : QonversionPermissionsCallback {
171- override fun onSuccess (permissions : Map <String , QPermission >) {
172- result.success(PurchaseResult (permissions).toMap())
173- }
169+ activity?.let {
170+ Qonversion .purchase(it, productId, getPurchasesListener(result))
171+ } ? : handleMissingActivityOnPurchase(result, object {}.javaClass.enclosingMethod?.name)
172+ }
173+
174+ private fun purchaseProduct (jsonProduct : String? , result : Result ) {
175+ if (jsonProduct == null ) {
176+ return result.noProduct()
177+ }
178+
179+ val funcName = object {}.javaClass.enclosingMethod?.name
180+ try {
181+ val product = mapQProduct(jsonProduct)
182+ ? : return handleMissingProductIdField(result, funcName)
183+
184+ activity?.let {
185+ Qonversion .purchase(it, product, getPurchasesListener(result))
186+ } ? : handleMissingActivityOnPurchase(result, funcName)
174187
175- override fun onError (error : QonversionError ) {
176- result.success(PurchaseResult (error = error).toMap())
177- }
178- })
179- } ? : result.error(QonversionErrorCode .PurchaseInvalid .name, " Couldn't make purchase. There is no Activity context" , null )
188+ } catch (e: JsonSyntaxException ) {
189+ handleJsonExceptionOnPurchase(result, e, funcName)
190+ } catch (e: IllegalArgumentException ) {
191+ handleExceptionOnPurchase(result, e, funcName)
192+ } catch (e: ClassCastException ) {
193+ handleExceptionOnPurchase(result, e, funcName)
194+ }
180195 }
181196
182197 private fun updatePurchase (args : Map <String , Any >, result : Result ) {
183198 val newProductId = args[" newProductId" ] as ? String ? : return result.noNewProductIdError()
184199 val oldProductId = args[" oldProductId" ] as ? String ? : return result.noOldProductIdError()
185200 val prorationMode = args[" proration_mode" ] as ? Int
186201
187- activity?.let { activity ->
188- Qonversion .updatePurchase(activity, newProductId, oldProductId, prorationMode, callback = object : QonversionPermissionsCallback {
189- override fun onSuccess (permissions : Map <String , QPermission >) {
190- result.success(permissions.mapValues { it.value.toMap() })
191- }
202+ activity?.let {
203+ Qonversion .updatePurchase(it, newProductId, oldProductId, prorationMode, getUpdatePurchasesListener(result))
204+ } ? : handleMissingActivityOnPurchase(result, object {}.javaClass.enclosingMethod?.name)
205+ }
206+
207+ private fun updatePurchaseWithProduct (args : Map <String , Any >, result : Result ) {
208+ val jsonProduct = args[" product" ] as ? String ? : return result.noProduct()
209+ val oldProductId = args[" oldProductId" ] as ? String ? : return result.noOldProductIdError()
210+ val prorationMode = args[" proration_mode" ] as ? Int
192211
193- override fun onError (error : QonversionError ) {
194- result.qonversionError(error.description, error.additionalMessage)
195- }
196- })
197- } ? : result.error(QonversionErrorCode .PurchaseInvalid .name, " Couldn't update purchase. There is no Activity context" , null )
212+ val funcName = object {}.javaClass.enclosingMethod?.name
213+ try {
214+ val product = mapQProduct(jsonProduct)
215+ ? : return handleMissingProductIdField(result, funcName)
216+
217+ activity?.let {
218+ Qonversion .updatePurchase(it, product, oldProductId, prorationMode, getUpdatePurchasesListener(result))
219+ } ? : handleMissingActivityOnPurchase(result, funcName)
220+ } catch (e: JsonSyntaxException ) {
221+ handleJsonExceptionOnPurchase(result, e, funcName)
222+ } catch (e: IllegalArgumentException ) {
223+ handleExceptionOnPurchase(result, e, funcName)
224+ } catch (e: ClassCastException ) {
225+ handleExceptionOnPurchase(result, e, funcName)
226+ }
198227 }
199228
200229 private fun checkPermissions (result : Result ) {
201- Qonversion .checkPermissions(object : QonversionPermissionsCallback {
230+ Qonversion .checkPermissions(object : QonversionPermissionsCallback {
202231 override fun onSuccess (permissions : Map <String , QPermission >) {
203232 result.success(permissions.mapValues { it.value.toMap() })
204233 }
@@ -210,7 +239,7 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
210239 }
211240
212241 private fun restore (result : Result ) {
213- Qonversion .restore(object : QonversionPermissionsCallback {
242+ Qonversion .restore(object : QonversionPermissionsCallback {
214243 override fun onSuccess (permissions : Map <String , QPermission >) {
215244 result.success(permissions.mapValues { it.value.toMap() })
216245 }
@@ -222,7 +251,7 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
222251 }
223252
224253 private fun offerings (result : Result ) {
225- Qonversion .offerings(callback = object : QonversionOfferingsCallback {
254+ Qonversion .offerings(callback = object : QonversionOfferingsCallback {
226255 override fun onSuccess (offerings : QOfferings ) {
227256 val jsonOfferings = Gson ().toJson(offerings.toMap())
228257 result.success(jsonOfferings)
@@ -235,7 +264,7 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
235264 }
236265
237266 private fun products (result : Result ) {
238- Qonversion .products(callback = object : QonversionProductsCallback {
267+ Qonversion .products(callback = object : QonversionProductsCallback {
239268 override fun onSuccess (products : Map <String , QProduct >) {
240269 result.success(products.mapValues { it.value.toMap() })
241270 }
@@ -306,7 +335,7 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
306335 private fun checkTrialIntroEligibility (args : Map <String , Any >, result : Result ) {
307336 val ids = args[" ids" ] as ? List <String > ? : return result.noDataError()
308337
309- Qonversion .checkTrialIntroEligibilityForProductIds(ids, callback = object : QonversionEligibilityCallback {
338+ Qonversion .checkTrialIntroEligibilityForProductIds(ids, callback = object : QonversionEligibilityCallback {
310339 override fun onSuccess (eligibilities : Map <String , QEligibility >) {
311340 val jsonEligibilities = Gson ().toJson(eligibilities.mapValues { it.value.toMap() })
312341 result.success(jsonEligibilities)
@@ -318,6 +347,46 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
318347 })
319348 }
320349
350+ private fun getPurchasesListener (result : Result ) = object : QonversionPermissionsCallback {
351+ override fun onSuccess (permissions : Map <String , QPermission >) =
352+ result.success(PurchaseResult (permissions).toMap())
353+
354+ override fun onError (error : QonversionError ) =
355+ result.success(PurchaseResult (error = error).toMap())
356+ }
357+
358+ private fun getUpdatePurchasesListener (result : Result ) = object : QonversionPermissionsCallback {
359+ override fun onSuccess (permissions : Map <String , QPermission >) =
360+ result.success(permissions.mapValues { it.value.toMap() })
361+
362+ override fun onError (error : QonversionError ) =
363+ result.qonversionError(error.description, error.additionalMessage)
364+ }
365+
366+ private fun handleMissingProductIdField (result : Result , functionName : String? ) {
367+ val errorMessage = " Failed to deserialize Qonversion Product. There is no qonversionId"
368+ Log .d(" Qonversion" , " $functionName () -> $errorMessage " )
369+ result.noProductIdField(errorMessage)
370+ }
371+
372+ private fun handleMissingActivityOnPurchase (result : Result , functionName : String? ) {
373+ val errorMessage = " Couldn't make a purchase. There is no Activity context"
374+ Log .d(" Qonversion" , " $functionName () -> $errorMessage " )
375+ result.error(QonversionErrorCode .PurchaseInvalid .name, errorMessage, null )
376+ }
377+
378+ private fun handleExceptionOnPurchase (result : Result , e : Exception , functionName : String? ) {
379+ val errorMessage = " Couldn't make a purchase as an Exception occurred. ${e.localizedMessage} ."
380+ Log .d(" Qonversion" , " $functionName () -> $errorMessage " )
381+ result.error(QonversionErrorCode .PurchaseInvalid .name, errorMessage, null )
382+ }
383+
384+ private fun handleJsonExceptionOnPurchase (result : Result , e : JsonSyntaxException , functionName : String? ) {
385+ val errorMessage = " Failed to deserialize Qonversion Product: ${e.localizedMessage} ."
386+ Log .d(" Qonversion" , " $functionName () -> $errorMessage " )
387+ result.jsonSerializationError(errorMessage)
388+ }
389+
321390 private fun storeSdkInfo (args : Map <String , Any >, result : Result ) {
322391 val version = args[" version" ] as ? String ? : return result.noSdkInfo()
323392 val versionKey = args[" versionKey" ] as ? String ? : return result.noSdkInfo()
0 commit comments