Skip to content

Commit dca30f4

Browse files
authored
Merge pull request #159 from qonversion/release/4.4.0
Release 4.4.0
2 parents ae73fd0 + 9615533 commit dca30f4

19 files changed

+203
-12
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 4.4.0
2+
* Added support of network connection lack or unexpected backend errors. Now Qonversion SDK will handle user permissions correctly even if it can't reach out to the API and will actualize them with the next successful request. Also, products and offerings become permanently available after the first successful launch - nothing will interfere user from the purchase.
3+
* Added method `setPermissionsCacheLifetime` to configure the lifetime of permissions cache. It is used if we faced any error trying to get permissions from our API. Defaults to one month.
4+
* Added a new defined property `FirebaseAppInstanceId` for Firebase integration.
5+
* _(Android only)_ Fixed a bug with introductory price tracking causing wrong data in the analytics dashboard for some purchases.
6+
17
## 4.3.4
28
* Updated native SDK versions. Android 3.2.4 -> 3.2.9. iOS 2.18.3 -> 2.19.1.
39

android/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
group 'com.qonversion.flutter.sdk.qonversion_flutter_sdk'
2-
version '4.3.4'
2+
version '4.4.0'
33

44
buildscript {
55
ext.kotlin_version = '1.3.50'
6-
ext.qonversion_version = '3.2.9'
6+
ext.qonversion_version = '3.3.0'
77
repositories {
88
google()
99
jcenter()

android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/FlutterResult+CustomErrors.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ fun MethodChannel.Result.noSdkInfo() {
7171
return this.error("15", "Could not find sdk info", passValidValue)
7272
}
7373

74+
fun MethodChannel.Result.noLifetime() {
75+
return this.error("16", "Could not find lifetime", passValidValue)
76+
}
77+
7478
fun MethodChannel.Result.noProductIdField(details: String?) {
7579
return this.error("NoProductIdField", "Could not find qonversionId in Product", details)
7680
}

android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/Mapper.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.qonversion.android.sdk.automations.QActionResult
1212
import com.qonversion.android.sdk.automations.QActionResultType
1313
import com.qonversion.android.sdk.dto.QLaunchResult
1414
import com.qonversion.android.sdk.dto.QPermission
15+
import com.qonversion.android.sdk.dto.QPermissionsCacheLifetime
1516
import com.qonversion.android.sdk.dto.eligibility.QEligibility
1617
import com.qonversion.android.sdk.dto.eligibility.QIntroEligibilityStatus
1718
import com.qonversion.android.sdk.dto.offerings.QOffering
@@ -199,4 +200,19 @@ fun AutomationsEventType.toInt(): Int {
199200
AutomationsEventType.SubscriptionDowngraded -> 15
200201
AutomationsEventType.SubscriptionProductChanged -> 16
201202
}
203+
}
204+
205+
fun parsePermissionsCacheLifetime(lifetime: String): QPermissionsCacheLifetime? {
206+
val lifetimes = mapOf(
207+
"Week" to QPermissionsCacheLifetime.WEEK,
208+
"TwoWeeks" to QPermissionsCacheLifetime.TWO_WEEKS,
209+
"Month" to QPermissionsCacheLifetime.MONTH,
210+
"TwoMonths" to QPermissionsCacheLifetime.TWO_MONTHS,
211+
"ThreeMonths" to QPermissionsCacheLifetime.THREE_MONTHS,
212+
"SixMonths" to QPermissionsCacheLifetime.SIX_MONTHS,
213+
"Year" to QPermissionsCacheLifetime.YEAR,
214+
"Unlimited" to QPermissionsCacheLifetime.UNLIMITED
215+
)
216+
217+
return lifetimes[lifetime]
202218
}

android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionFlutterSdkPlugin.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.google.gson.JsonSyntaxException
1010
import com.qonversion.android.sdk.*
1111
import com.qonversion.android.sdk.dto.QLaunchResult
1212
import com.qonversion.android.sdk.dto.QPermission
13+
import com.qonversion.android.sdk.dto.QPermissionsCacheLifetime
1314
import com.qonversion.android.sdk.dto.eligibility.QEligibility
1415
import com.qonversion.android.sdk.dto.offerings.QOfferings
1516
import com.qonversion.android.sdk.dto.products.QProduct
@@ -115,6 +116,7 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
115116
"checkTrialIntroEligibility" -> checkTrialIntroEligibility(args, result)
116117
"storeSdkInfo" -> storeSdkInfo(args, result)
117118
"identify" -> identify(args["userId"] as? String, result)
119+
"setPermissionsCacheLifetime" -> setPermissionsCacheLifetime(args, result)
118120
"setNotificationsToken" -> setNotificationsToken(args["notificationsToken"] as? String, result)
119121
"handleNotification" -> handleNotification(args, result)
120122
else -> result.notImplemented()
@@ -341,6 +343,18 @@ class QonversionFlutterSdkPlugin : MethodCallHandler, FlutterPlugin, ActivityAwa
341343
})
342344
}
343345

346+
private fun setPermissionsCacheLifetime(args: Map<String, Any>, result: Result) {
347+
val rawLifetime = args["lifetime"] as? String ?: return result.noLifetime()
348+
349+
val lifetime = parsePermissionsCacheLifetime(rawLifetime) ?: run {
350+
result.parsingError("No permissions cache lifetime associated with the provided value: $rawLifetime")
351+
return
352+
}
353+
354+
Qonversion.setPermissionsCacheLifetime(lifetime)
355+
result.success(null)
356+
}
357+
344358
private fun setNotificationsToken(token: String?, result: Result) {
345359
token?.let {
346360
Qonversion.setNotificationsToken(it)

ios/Classes/FlutterError+Custom.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ extension FlutterError {
7575
static let noSdkInfo = FlutterError(code: "15",
7676
message: "Could not find sdk info",
7777
details: passValidValue)
78-
78+
79+
static let noLifetime = FlutterError(code: "16",
80+
message: "Could not find lifetime",
81+
details: passValidValue)
82+
7983
static func promoPurchaseError(_ productId: String) -> FlutterError {
8084
return FlutterError (code: "PromoPurchase",
8185
message: "Could not find completion block for Product ID: \(productId)",

ios/Classes/Mapper.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ extension Qonversion.Property {
120120

121121
case "CustomUserId":
122122
return .userID
123+
124+
case "FirebaseAppInstanceId":
125+
return .firebaseAppInstanceId
123126

124127
default:
125128
throw ParsingError.runtimeError("Could not parse Qonversion.Property")
@@ -210,3 +213,36 @@ extension QONAutomationsEvent {
210213
"date": date.toMilliseconds()]
211214
}
212215
}
216+
217+
extension Qonversion.PermissionsCacheLifetime {
218+
static func fromString(_ string: String) throws -> Self {
219+
switch string {
220+
case "Week":
221+
return .week;
222+
223+
case "TwoWeeks":
224+
return .twoWeeks;
225+
226+
case "Month":
227+
return .month;
228+
229+
case "TwoMonths":
230+
return .twoMonth;
231+
232+
case "ThreeMonths":
233+
return .threeMonth;
234+
235+
case "SixMonths":
236+
return .sixMonth;
237+
238+
case "Year":
239+
return .year;
240+
241+
case "Unlimited":
242+
return .unlimited;
243+
244+
default:
245+
throw ParsingError.runtimeError("Could not parse Qonversion.PermissionsCacheLifetime");
246+
}
247+
}
248+
}

ios/Classes/SwiftQonversionFlutterSdkPlugin.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public class SwiftQonversionFlutterSdkPlugin: NSObject, FlutterPlugin {
111111
case "setAppleSearchAdsAttributionEnabled":
112112
let enable = args["enable"] as? Bool ?? false
113113
return setAppleSearchAdsAttributionEnabled(enable, result)
114+
115+
case "setPermissionsCacheLifetime":
116+
return setPermissionsCacheLifetime(args, result)
114117

115118
case "setNotificationsToken":
116119
return setNotificationsToken(args["notificationsToken"] as? String, result)
@@ -356,7 +359,26 @@ public class SwiftQonversionFlutterSdkPlugin: NSObject, FlutterPlugin {
356359
}
357360
result(nil)
358361
}
359-
362+
363+
private func setPermissionsCacheLifetime(_ args: [String: Any], _ result: @escaping FlutterResult) {
364+
guard let rawLifetime = args["lifetime"] as? String else {
365+
return result(FlutterError.noLifetime)
366+
}
367+
368+
do {
369+
let lifetime = try Qonversion.PermissionsCacheLifetime.fromString(rawLifetime)
370+
371+
Qonversion.setPermissionsCacheLifetime(lifetime)
372+
result(nil)
373+
} catch ParsingError.runtimeError(let message) {
374+
result(FlutterError.parsingError(message))
375+
} catch {
376+
if let nsError = error as NSError? {
377+
result(FlutterError.qonversionError(nsError))
378+
}
379+
}
380+
}
381+
360382
private func setNotificationsToken(_ token: String?, _ result: @escaping FlutterResult) {
361383
guard let token = token else {
362384
result(FlutterError.noArgs)

ios/qonversion_flutter.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
Pod::Spec.new do |s|
66
s.name = 'qonversion_flutter'
7-
s.version = '4.3.4'
7+
s.version = '4.4.0'
88
s.summary = 'Flutter Qonversion SDK'
99
s.description = <<-DESC
1010
Powerful yet simple subscription analytics
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
1818
s.platform = :ios, '9.0'
19-
s.dependency 'Qonversion', '2.19.1'
19+
s.dependency 'Qonversion', '2.20.0'
2020

2121
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
2222
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }

lib/qonversion_flutter.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ export 'src/models/qonversion_error.dart';
1818
export 'src/models/sk_product/discount_payment_mode.dart';
1919
export 'src/models/sk_product/subscription_period_unit.dart';
2020
export 'src/models/user_property.dart';
21+
export 'src/models/permissions_cache_lifetime.dart';
2122
export 'src/qa_provider.dart';
2223
export 'src/qonversion.dart';

0 commit comments

Comments
 (0)