Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .scripts/changes.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
- Apptentive Android SDK: 6.9.3
- Apptentive iOS SDK: 6.9.1
- Apptentive iOS SDK: 6.9.2
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 2025-11-17 - v6.9.4

- Apptentive Android SDK: 6.9.3
- Apptentive iOS SDK: 6.9.2

# 2025-03-20 - v6.9.3

- Apptentive Android SDK: 6.9.3
Expand Down
1 change: 1 addition & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
.buildlog/
.history
.svn/
credentials.dart

# IntelliJ related
*.iml
Expand Down
11 changes: 1 addition & 10 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,4 @@ Demonstrates how to use the apptentive_flutter plugin.

## Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)

For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
Copy the file named `lib/credentials-template.dart` to `lib/credentials.dart` and add the credentials from the API & Development section of the Settings tab in your Alchemer Digital Dashboard.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
Expand All @@ -43,11 +44,13 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
Expand Down
6 changes: 6 additions & 0 deletions example/lib/credentials-template.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ApptentiveCredentials {
static const String iOSKey = "<YOUR_IOS_KEY>";
static const String iOSSignature = "<YOUR_IOS_SIGNATURE>";
static const String androidKey = "<YOUR_ANDROID_KEY>";
static const String androidSignature = "<YOUR_ANDROID_SIGNATURE>";
}
9 changes: 5 additions & 4 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:async';
import 'dart:io' show Platform;
import 'package:fluttertoast/fluttertoast.dart';
import 'package:apptentive_flutter/apptentive_flutter.dart';
import 'credentials.dart';

// import 'package:firebase_core/firebase_core.dart';
// import 'package:firebase_messaging/firebase_messaging.dart';
Expand Down Expand Up @@ -46,11 +47,11 @@ class _MyAppState extends State<MyApp> {
final String apptentiveKey;
final String apptentiveSignature;
if (Platform.isAndroid) {
apptentiveKey = "<YOUR_ANDROID_KEY>";
apptentiveSignature = "<YOUR_ANDROID_SIGNATURE>";
apptentiveKey = ApptentiveCredentials.androidKey;
apptentiveSignature = ApptentiveCredentials.androidSignature;
} else if (Platform.isIOS) {
apptentiveKey = "<YOUR_IOS_KEY>";
apptentiveSignature = "<YOUR_IOS_SIGNATURE>";
apptentiveKey = ApptentiveCredentials.iOSKey;
apptentiveSignature = ApptentiveCredentials.iOSSignature;
} else {
String os = Platform.operatingSystem;
print("E Apptentive: Platform not supported for Apptentive Flutter Plugin: ${os}. Apptentive failed to initialize.");
Expand Down
4 changes: 2 additions & 2 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ dependencies:
path: ../

cupertino_icons: ^1.0.2
firebase_messaging: ^14.3.0
firebase_core: ^2.9.0
firebase_messaging: ^15.2.5
firebase_core: ^3.13.0
fluttertoast: ^8.0.8

dev_dependencies:
Expand Down
28 changes: 18 additions & 10 deletions ios/Classes/ApptentiveFlutterPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class ApptentiveFlutterPlugin: NSObject, FlutterApplicationLifeCycleDeleg
private static let errorCode = "Apptentive Error"
private var observation: NSKeyValueObservation?
private let channel: FlutterMethodChannel
private var isSDKRegistered: Bool = false

// Register the method channel and plugin instance
public static func register(with registrar: FlutterPluginRegistrar) {
Expand Down Expand Up @@ -37,6 +38,7 @@ public class ApptentiveFlutterPlugin: NSObject, FlutterApplicationLifeCycleDeleg
case "sendAttachmentText": handleSendAttachmentTextCall(call, result)
case "login": handleLoginCall(call, result)
case "logout": handleLogoutCall(result)
case "isSDKRegistered": handleIsSDKRegisteredCall(result)
default: result(FlutterMethodNotImplemented)
}
}
Expand Down Expand Up @@ -97,20 +99,22 @@ public class ApptentiveFlutterPlugin: NSObject, FlutterApplicationLifeCycleDeleg
Apptentive.shared.distributionName = distributionName
Apptentive.shared.distributionVersion = distributionVersion

guard let (logLevel, appCredentials) = self.unpackConfiguration(callArguments["configuration"]) else {
guard let (logLevel, appCredentials, apiBaseURL) = self.unpackConfiguration(callArguments["configuration"]) else {
return result(FlutterError.init(code: Self.errorCode, message: "Missing or invalid app credentials (key/signature)", details: "Configuration is \(callArguments["configuration"] ?? "missing")"))
}

ApptentiveLogger.logLevel = logLevel
let region = apiBaseURL.flatMap { ApptentiveKit.Apptentive.Region(apiBaseURL: $0) } ?? .us

// Register Apptentive using credentials
Apptentive.shared.register(with: appCredentials, completion: { (completionResult) -> Void in
switch completionResult {
case .success:
result(true)
case .failure(let error):
result(FlutterError.init(code: Self.errorCode, message: "Apptentive SDK failed to register.", details: error.localizedDescription))
}
Apptentive.shared.register(with: appCredentials, region:region, completion: { (completionResult) -> Void in
switch completionResult {
case .success:
self.isSDKRegistered = true
result(true)
case .failure(let error):
result(FlutterError.init(code: Self.errorCode, message: "Apptentive SDK failed to register.", details: error.localizedDescription))
}
})
}

Expand Down Expand Up @@ -293,6 +297,9 @@ public class ApptentiveFlutterPlugin: NSObject, FlutterApplicationLifeCycleDeleg
result(true)
}

private func handleIsSDKRegisteredCall(_ result: @escaping FlutterResult) {
result(self.isSDKRegistered)
}

@objc func eventEngaged(notification: Notification) {
guard let userInfo = notification.userInfo as? [String: String],
Expand Down Expand Up @@ -341,7 +348,7 @@ public class ApptentiveFlutterPlugin: NSObject, FlutterApplicationLifeCycleDeleg
}
}

private func unpackConfiguration(_ configuration: Any?) -> (LogLevel, Apptentive.AppCredentials)? {
private func unpackConfiguration(_ configuration: Any?) -> (LogLevel, Apptentive.AppCredentials, URL?)? {
guard let configuration = configuration as? [String: Any],
let key = configuration["key"] as? String,
let signature = configuration["signature"] as? String
Expand All @@ -351,7 +358,8 @@ public class ApptentiveFlutterPlugin: NSObject, FlutterApplicationLifeCycleDeleg
}

let logLevel = configuration["log_level"] as? String
return (self.convertLogLevel(logLevel: logLevel), .init(key: key, signature: signature))
let apiBaseURL = (configuration["api_base_url"] as? String).flatMap { URL(string: $0) }
return (self.convertLogLevel(logLevel: logLevel), .init(key: key, signature: signature), apiBaseURL)
}

private func convertCustomDataArguments(_ callArguments: Any?) -> (String, CustomDataCompatible)? {
Expand Down
4 changes: 2 additions & 2 deletions ios/apptentive_flutter.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'apptentive_flutter'
s.version = "6.9.3"
s.version = "6.9.4"
s.summary = 'Apptentive SDK for Flutter'
s.description = <<-DESC
Apptentive SDK for Flutter
Expand All @@ -12,7 +12,7 @@ Apptentive SDK for Flutter
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.dependency 'ApptentiveKit', '6.9.1'
s.dependency 'ApptentiveKit', '6.9.2'
s.platform = :ios, '13.0'

# Flutter.framework does not contain a i386 slice.
Expand Down
9 changes: 6 additions & 3 deletions lib/apptentive_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ class ApptentiveConfiguration {
final String distributionVersion;
final int ratingInteractionThrottleLength;
final String? customAppStoreURL;
final String? apiBaseURL;

ApptentiveConfiguration({required this.apptentiveKey, required this.apptentiveSignature,
this.logLevel = LogLevel.info,
this.shouldInheritAppTheme = true,
this.shouldEncryptStorage = false,
this.shouldSanitizeLogMessages = true,
this.distributionName = "Flutter",
this.distributionVersion = "6.9.3",
this.distributionVersion = "6.9.4",
this.ratingInteractionThrottleLength = 604800000, // 1 week
this.customAppStoreURL
this.customAppStoreURL,
this.apiBaseURL
});
}

Expand Down Expand Up @@ -240,7 +242,8 @@ class ApptentiveFlutter {
"rating_interaction_throttle_length": configuration.ratingInteractionThrottleLength,
"custom_app_store_url": configuration.customAppStoreURL,
"distribution_name": configuration.distributionName,
"distribution_version": configuration.distributionVersion
"distribution_version": configuration.distributionVersion,
"api_base_url": configuration.apiBaseURL
};
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: apptentive_flutter
description: Apptentive SDK for Flutter
version: 6.9.3
version: 6.9.4
repository: https://github.com/apptentive/apptentive-flutter
issue_tracker: https://github.com/apptentive/apptentive-flutter/issues
documentation: https://learn.apptentive.com/knowledge-base/apptentive-sdk-flutter-plugin-guide/
Expand Down