Cài đặt & cấu hình Flutter SDK
Adapty SDK bao gồm hai module chính để tích hợp liền mạch vào ứng dụng Flutter của bạn:
- Core Adapty: SDK cốt lõi này là bắt buộc để Adapty hoạt động đúng trong ứng dụng của bạn.
- AdaptyUI: Module này hiển thị các flow, cũng như các paywall được xây dựng bằng builder cũ.
Bạn muốn xem ví dụ thực tế về cách tích hợp Adapty SDK vào ứng dụng di động? Hãy xem ứng dụng mẫu của chúng tôi, nơi minh họa toàn bộ quá trình thiết lập, bao gồm hiển thị paywall, thực hiện mua hàng và các chức năng cơ bản khác.
Yêu cầu
Adapty Flutter SDK yêu cầu iOS 15.0+, Xcode 26+ và Flutter 3.32.0+ (Dart 3.8.0+). Xem Swift Package Manager (iOS) bên dưới để biết chi tiết cài đặt.
Cài đặt SDK là bước 5 trong quá trình thiết lập Adapty. Trước khi các giao dịch mua hàng hoạt động trong ứng dụng, bạn cần kết nối ứng dụng với các cửa hàng, sau đó tạo sản phẩm, paywall và placement trong Adapty Dashboard. Hướng dẫn quickstart sẽ hướng dẫn bạn qua tất cả các bước cần thiết.
Phụ thuộc
Adapty SDK hoạt động với các phiên bản Google Play Billing Library sau trên Android:
| Phiên bản Adapty SDK | Phiên bản Billing Library |
|---|---|
| 4.0.4 trở lên | v8 |
| 4.0.0–4.0.3 | v7 theo mặc định, v8 nếu một dependency khác nâng lên |
Tương thích với một phiên bản Billing Library không có nghĩa là Adapty hỗ trợ mọi tính năng mà Google giới thiệu trong phiên bản đó. Trước khi áp dụng một khả năng thanh toán mới của Google Play, hãy xem Sản phẩm trên Play Store.
Cài đặt Adapty SDK
Chúng tôi luôn khuyến nghị cài đặt phiên bản SDK mới nhất hiện có — phiên bản này bao gồm các bản sửa lỗi ổn định và cải tiến mới nhất.
Các bước này yêu cầu Flutter 3.32.0+ (Dart 3.8.0+). Plugin kéo native iOS SDK thông qua Swift Package Manager — xem Swift Package Manager (iOS) để biết cách thiết lập một lần.
- Thêm Adapty vào file
pubspec.yamlcủa bạn:
dependencies:
adapty_flutter: ^<the latest SDK version>
-
Chạy lệnh sau để cài đặt các dependencies:
flutter pub get -
Import Adapty SDK vào ứng dụng của bạn:
import 'package:adapty_flutter/adapty_flutter.dart';
Swift Package Manager (iOS)
Plugin này sử dụng iOS SDK gốc thông qua Swift Package Manager. Nếu bạn đang dùng Flutter 3.32–3.43, hãy bật hỗ trợ Swift Package Manager một lần:
flutter config --enable-swift-package-manager
Flutter 3.44 trở lên đã bật Swift Package Manager theo mặc định, nên bạn không cần làm gì thêm.
Để xem các thay đổi API trong v4, hãy tham khảo hướng dẫn migration.
Kích hoạt module Adapty của Adapty SDK
Kích hoạt Adapty SDK trong code ứng dụng của bạn.
Adapty SDK chỉ cần được kích hoạt một lần trong ứng dụng của bạn.
Để lấy Public SDK Key:
- Truy cập Adapty Dashboard và điều hướng đến App settings → General.
- Trong phần Api keys, sao chép Public SDK Key (KHÔNG phải Secret Key).
- Thay thế
"YOUR_PUBLIC_SDK_KEY"trong code.
Hoặc lấy theo cách lập trình, sử dụng Adapty CLI:
npm install -g adapty
adapty auth login
adapty apps list
Hoặc, trực tiếp:
npx adapty auth login
adapty apps list
- Đảm bảo bạn sử dụng Public SDK key để khởi tạo Adapty, Secret key chỉ nên dùng cho server-side API.
- SDK keys là duy nhất cho mỗi ứng dụng, vì vậy nếu bạn có nhiều ứng dụng, hãy đảm bảo chọn đúng key.
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
_initializeAdapty();
super.initState();
}
Future<void> _initializeAdapty() async {
try {
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY'),
);
} catch (e) {
// handle the error
}
}
Widget build(BuildContext context) {
return Text("Hello");
}
}
Hãy đợi activate hoàn tất trước khi gọi bất kỳ phương thức nào khác của Adapty SDK. Xem Thứ tự gọi trong Flutter SDK để biết toàn bộ trình tự.
Bây giờ hãy thiết lập paywall trong ứng dụng của bạn:
- Nếu bạn dùng Flow & Paywall Builder, trước tiên hãy kích hoạt module AdaptyUI bên dưới, rồi làm theo hướng dẫn nhanh.
- Nếu bạn tự xây dựng giao diện paywall, xem hướng dẫn nhanh cho paywall tùy chỉnh.
Kích hoạt module AdaptyUI của Adapty SDK
Nếu bạn có kế hoạch sử dụng Flow & Paywall Builder và đã cài đặt module AdaptyUI, bạn cũng cần kích hoạt AdaptyUI:
Các dependency liên quan đến AdaptyUI được liên kết với ứng dụng của bạn bất kể AdaptyUI có được kích hoạt hay không.
Trong code của bạn, bạn phải kích hoạt module Adapty core trước khi kích hoạt AdaptyUI.
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withActivateUI(true), // This automatically activates AdaptyUI
);
Thiết lập tùy chọn
Ghi log
Thiết lập hệ thống ghi log
Adapty ghi lại các lỗi và thông tin quan trọng khác để giúp bạn hiểu điều gì đang xảy ra. Có các cấp độ sau:
| Level | Mô tả |
|---|---|
AdaptyLogLevel.error | Chỉ ghi lại các lỗi. |
AdaptyLogLevel.warn | Ghi lại các lỗi và thông báo từ SDK không gây ra lỗi nghiêm trọng nhưng đáng chú ý. |
AdaptyLogLevel.info | Ghi lại các lỗi, cảnh báo và nhiều thông báo thông tin khác nhau. Giá trị mặc định. |
AdaptyLogLevel.verbose | Ghi lại mọi thông tin bổ sung có thể hữu ích trong quá trình debug, chẳng hạn như các lời gọi hàm, truy vấn API, v.v. |
AdaptyLogLevel.debug | Ghi lại thông tin debug. |
Bạn có thể đặt mức độ log trong ứng dụng trước khi cấu hình Adapty:
// Set log level before activation.
// 'verbose' is recommended for development and the first production release
await Adapty().setLogLevel(AdaptyLogLevel.verbose);
// Or set it during configuration
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withLogLevel(AdaptyLogLevel.verbose),
);
Chính sách dữ liệu
Adapty không lưu trữ dữ liệu cá nhân của người dùng trừ khi bạn chủ động gửi lên, nhưng bạn có thể áp dụng các chính sách bảo mật dữ liệu bổ sung để tuân thủ quy định của cửa hàng hoặc từng quốc gia.
Tắt tính năng thu thập và chia sẻ địa chỉ IP
Khi khởi tạo module Adapty, đặt ipAddressCollectionDisabled thành true để tắt tính năng thu thập và chia sẻ địa chỉ IP của người dùng. Giá trị mặc định là false.
Sử dụng tham số này để tăng cường quyền riêng tư cho người dùng, tuân thủ các quy định bảo vệ dữ liệu theo khu vực (như GDPR hoặc CCPA), hoặc giảm thiểu việc thu thập dữ liệu không cần thiết khi các tính năng dựa trên địa chỉ IP không được yêu cầu trong ứng dụng của bạn.
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withIpAddressCollectionDisabled(true),
);
Tắt tính năng thu thập và chia sẻ advertising ID
Khi kích hoạt module Adapty, đặt appleIdfaCollectionDisabled (iOS) hoặc googleAdvertisingIdCollectionDisabled (Android) thành true để tắt việc thu thập mã định danh quảng cáo. Giá trị mặc định là false.
Sử dụng tham số này để tuân thủ chính sách của App Store/Play Store, tránh kích hoạt lời nhắc App Tracking Transparency, hoặc nếu ứng dụng của bạn không cần attribution quảng cáo hay phân tích dựa trên ID quảng cáo.
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withAppleIdfaCollectionDisabled(true) // iOS
..withGoogleAdvertisingIdCollectionDisabled(true), // Android
);
Thiết lập cấu hình bộ nhớ cache media cho AdaptyUI
Module này được kích hoạt tự động cùng với Adapty SDK. Nếu Adapty không render màn hình của bạn và bạn muốn tắt module AdaptyUI, hãy truyền withActivateUI(false) trong quá trình kích hoạt.
Theo mặc định, AdaptyUI lưu bộ nhớ đệm cho các tệp media (như hình ảnh và video) để cải thiện hiệu suất và giảm lưu lượng mạng. Bạn có thể tùy chỉnh cài đặt bộ nhớ đệm bằng cách cung cấp một cấu hình tùy chỉnh.
Sử dụng withMediaCacheConfiguration để ghi đè các giới hạn bộ nhớ đệm mặc định. Đây là tùy chọn — nếu bạn không gọi phương thức này, các giá trị mặc định sẽ được dùng (100MB dung lượng đĩa, không giới hạn số lượng trong bộ nhớ). Tuy nhiên, nếu bạn tạo đối tượng cấu hình, tất cả các tham số của nó đều là bắt buộc.
final mediaCacheConfig = AdaptyUIMediaCacheConfiguration(
memoryStorageTotalCostLimit: 200 * 1024 * 1024, // 200 MB
memoryStorageCountLimit: 2147483647, // max int value
diskStorageSizeLimit: 200 * 1024 * 1024, // 200 MB
);
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withMediaCacheConfiguration(mediaCacheConfig),
);
Tham số:
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
| memoryStorageTotalCostLimit | bắt buộc | Tổng kích thước cache trong bộ nhớ tính bằng byte. Mặc định là 100 MB. |
| memoryStorageCountLimit | bắt buộc | Giới hạn số lượng item trong bộ nhớ. Mặc định là giá trị int tối đa. |
| diskStorageSizeLimit | bắt buộc | Giới hạn kích thước file trên đĩa tính bằng byte. Mặc định là 100 MB. |
Bật mức độ truy cập cục bộ (Android)
Theo mặc định, mức độ truy cập cục bộ được bật trên iOS và tắt trên Android. Để bật trên Android, hãy đặt withGoogleLocalAccessLevelAllowed thành true:
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withGoogleLocalAccessLevelAllowed(true),
);
Xóa dữ liệu khi khôi phục từ backup
Khi appleClearDataOnBackup được đặt thành true, SDK sẽ phát hiện khi ứng dụng được khôi phục từ bản backup iCloud và xóa toàn bộ dữ liệu SDK được lưu trữ cục bộ, bao gồm thông tin hồ sơ người dùng đã cache, chi tiết sản phẩm và paywall. Sau đó SDK sẽ khởi tạo lại với trạng thái sạch. Giá trị mặc định là false.
Chỉ có bộ nhớ cache cục bộ của SDK bị xóa. Lịch sử giao dịch với Apple và dữ liệu người dùng trên máy chủ Adapty vẫn không thay đổi.
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withAppleClearDataOnBackup(true) // default – false
);
Bật Adapty Attribution
Tham số này có sẵn từ SDK phiên bản 4.1 trở lên.
Nếu bạn sử dụng Adapty Attribution, hãy gọi withAdaptyAttributionEnabled(true) khi kích hoạt SDK. Giá trị mặc định là false: nếu không có tham số này, SDK sẽ không ghi nhận lượt cài đặt hoặc gửi thông tin cài đặt về ứng dụng của bạn. Trong các phiên bản SDK thấp hơn 4.1, Adapty Attribution được bật tự động.
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withAdaptyAttributionEnabled(true)
);
Khắc phục sự cố
Quy tắc sao lưu Android (cấu hình Auto Backup)
Một số SDK (bao gồm Adapty) có cấu hình Android Auto Backup riêng. Nếu bạn dùng nhiều SDK cùng định nghĩa backup rules, quá trình merge Android manifest có thể thất bại với lỗi liên quan đến android:fullBackupContent, android:dataExtractionRules, hoặc android:allowBackup.
Triệu chứng lỗi thường gặp: Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/your_data_extraction_rules) is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)
Các thay đổi này cần được thực hiện trong thư mục Android của dự án (thường nằm ở thư mục android/ trong project của bạn).
Để khắc phục, bạn cần:
-
Yêu cầu manifest merger sử dụng giá trị của ứng dụng cho các thuộc tính liên quan đến backup.
-
Tạo các file backup rule kết hợp rules của Adapty với rules từ các SDK khác.
1. Thêm namespace tools vào manifest
Trong file AndroidManifest.xml, đảm bảo thẻ root <manifest> có chứa tools:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.app">
...
</manifest>
2. Ghi đè các thuộc tính backup trong <application>
Trong cùng file AndroidManifest.xml, cập nhật thẻ <application> để ứng dụng của bạn cung cấp giá trị cuối cùng và yêu cầu manifest merger thay thế các giá trị từ thư viện:
<application
android:name=".App"
android:allowBackup="true"
android:fullBackupContent="@xml/sample_backup_rules"
android:dataExtractionRules="@xml/sample_data_extraction_rules"
tools:replace="android:fullBackupContent,android:dataExtractionRules">
...
</application>
Nếu có SDK nào đó cũng đặt android:allowBackup, hãy thêm nó vào tools:replace:
tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules"
3. Tạo các file backup rules đã gộp
Tạo các file XML trong thư mục res/xml/ của Android project, kết hợp rules của Adapty với rules từ các SDK khác. Android sử dụng các định dạng backup rule khác nhau tùy theo phiên bản hệ điều hành, vì vậy việc tạo cả hai file đảm bảo tương thích với tất cả các phiên bản Android mà ứng dụng hỗ trợ.
Các ví dụ dưới đây dùng AppsFlyer như một SDK bên thứ ba minh họa. Hãy thay thế hoặc bổ sung rules cho các SDK khác mà bạn đang dùng trong ứng dụng.
Dành cho Android 12 trở lên (sử dụng định dạng data extraction rules mới):
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="sharedpref" path="appsflyer-purchase-data"/>
<exclude domain="database" path="afpurchases.db"/>
<exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>
</cloud-backup>
<device-transfer>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="sharedpref" path="appsflyer-purchase-data"/>
<exclude domain="database" path="afpurchases.db"/>
<exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>
</device-transfer>
</data-extraction-rules>
Dành cho Android 11 trở xuống (sử dụng định dạng full backup content cũ):
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>
Giao dịch mua thất bại sau khi quay lại từ ứng dụng khác trên Android
Nếu Activity khởi động luồng mua hàng sử dụng launchMode không phải mặc định, Android có thể tạo lại hoặc tái sử dụng Activity đó không đúng cách khi người dùng quay lại từ Google Play, ứng dụng ngân hàng, hoặc trình duyệt. Điều này có thể khiến kết quả giao dịch mua bị mất hoặc bị coi là đã hủy.
Để đảm bảo giao dịch mua hoạt động đúng, chỉ sử dụng chế độ khởi chạy standard hoặc singleTop cho Activity khởi động luồng mua hàng, và tránh các chế độ khác.
Trong AndroidManifest.xml của bạn, hãy đảm bảo Activity khởi động flow mua hàng được đặt thành standard hoặc singleTop:
<activity
android:name=".MainActivity"
android:launchMode="standard" />
Lỗi build Swift 6 do Podfile ghi đè SWIFT_VERSION
Điều này chỉ áp dụng khi các SDK iOS của Adapty được cài đặt dưới dạng CocoaPods trong dự án của bạn. Khi chúng được cài đặt dưới dạng Swift package, việc ghi đè SWIFT_VERSION trong post_install sẽ không ảnh hưởng đến chúng.
Khi build ứng dụng Flutter cho iOS, bạn có thể gặp lỗi biên dịch Swift 6 trên các pod target của Adapty. Biểu hiện thường thấy gồm: @Sendable mismatch trong AdaptyUIBuilderLogic, thiếu conformance Sendable trên các kiểu của Adapty, hoặc lỗi actor isolation.
Các pod Adapty khai báo s.swift_version = '6.0' và yêu cầu Swift 6 để build. Code ứng dụng của bạn vẫn có thể dùng Swift 5 — chỉ các pod target của Adapty (Adapty, AdaptyUI, AdaptyUIBuilder, AdaptyLogger, AdaptyPlugin) mới cần build với Swift 6.
Nguyên nhân phổ biến nhất là một hook post_install trong ios/Podfile ghi đè SWIFT_VERSION cho mọi pod target:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '5.9'
end
end
end
Cách khắc phục: Loại trừ các Adapty pod target khỏi phần ghi đè:
post_install do |installer|
installer.pods_project.targets.each do |target|
next if %w[Adapty AdaptyUI AdaptyUIBuilder AdaptyLogger AdaptyPlugin].include?(target.name)
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '5.9'
end
end
end
Sau đó chạy pod install từ thư mục ios/ và build lại.
Để kiểm tra, mở ios/Pods/Pods.xcodeproj, chọn pod target Adapty → Build Settings → Swift Language Version. Giá trị phải là Swift 6.