Capacitor - Cài đặt & cấu hình Adapty SDK

Adapty SDK bao gồm hai module chính để tích hợp vào ứng dụng Capacitor của bạn:

  • Core Adapty: Module này bắt buộc để Adapty hoạt động trong ứng dụng.
  • AdaptyUI: Module này cần thiết nếu bạn dùng Adapty Paywall Builder — công cụ no-code thân thiện để tạo paywall đa nền tảng. AdaptyUI được kích hoạt tự động cùng với module core.

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, 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 Capacitor SDK yêu cầu các phiên bản sau:

Phiên bản Adapty SDKPhiên bản CapacitorPhiên bản iOS
3.16.0+815.0+
3.15714.0+

Capacitor phiên bản 6 trở xuống không được hỗ trợ.

Từ SDK v3.17 trở đi, Adapty SDK sử dụng Google Play Billing Library v8.0.0 theo mặc định.

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.

Cài đặt Adapty SDK

Release

Cài đặt Adapty SDK:

npm install @adapty/capacitor
npx cap sync

Kích hoạt module Adapty của Adapty SDK

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:

  1. Vào Adapty Dashboard và điều hướng đến App settings → General.
  2. Trong phần Api keys, sao chép Public SDK Key (KHÔNG phải Secret Key).
  3. Thay "YOUR_PUBLIC_SDK_KEY" trong code.
  • Đảm bảo bạn dùng Public SDK key để khởi tạo Adapty, còn Secret key chỉ 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 chắc chắn chọn đúng key.

Sao chép đoạn code sau vào bất kỳ file nào trong ứng dụng để kích hoạt Adapty:


try {
  await adapty.activate({
    apiKey: 'YOUR_PUBLIC_SDK_KEY',
    params: {
      // verbose logging is recommended for the development purposes and for the first production release
        logLevel: 'verbose',
      // in the development environment, use this variable to avoid multiple activation errors. Set it to your development environment variable
      __ignoreActivationOnFastRefresh: true,
    }
  });
  console.log('Adapty activated successfully!');
} catch (error) {
  console.error('Failed to activate Adapty SDK:', error);
}

Hãy chờ activate hoàn thành 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 Capacitor SDK để biết trình tự đầy đủ.

Để tránh lỗi kích hoạt trong môi trường phát triển, hãy xem các mẹo.

Tiếp theo, thiết lập paywall trong ứng dụng:

Kích hoạt module AdaptyUI của Adapty SDK

Nếu bạn dự định dùng Paywall Builder, bạn cần module AdaptyUI. Module này được kích hoạt tự động khi bạn kích hoạt module core; bạn không cần làm thêm gì.

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 để giúp bạn hiểu chuyện gì đang xảy ra. Các cấp độ log có sẵn:

Cấp độMô tả
errorChỉ ghi lại lỗi
warnGhi lại lỗi và các thông báo từ SDK không gây lỗi nghiêm trọng nhưng đáng chú ý
infoGhi lại lỗi, cảnh báo và các thông báo thông tin
verboseGhi lại mọi thông tin bổ sung có thể hữu ích khi debug, như lệnh gọi hàm, truy vấn API, v.v.

Bạn có thể đặt cấp độ log trong ứng dụng trước hoặc trong quá trình cấu hình Adapty:

// Set log level before activation
adapty.setLogLevel({ logLevel: 'verbose' });

// Or set it during configuration
await adapty.activate({
  apiKey: 'YOUR_PUBLIC_SDK_KEY',
  params: {
    logLevel: '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 gửi rõ ràng, 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ủ hướng dẫn của cửa hàng hoặc quy định quốc gia.

Tắt thu thập và chia sẻ địa chỉ IP

Khi kích hoạt module Adapty, đặt ipAddressCollectionDisabled thành true để tắt thu thập và chia sẻ địa chỉ IP của người dùng. Giá trị mặc định là false.

Dùng tham số này để tăng cường quyền riêng tư của người dùng, tuân thủ các quy định bảo vệ dữ liệu khu vực (như GDPR hoặc CCPA), hoặc giảm thu thập dữ liệu không cần thiết khi tính năng dựa trên IP không được yêu cầu cho ứng dụng của bạn.

await adapty.activate({
  apiKey: 'YOUR_PUBLIC_SDK_KEY',
  params: {
    ipAddressCollectionDisabled: true,
  }
});

Tắt thu thập và chia sẻ ID quảng cáo

Khi kích hoạt module Adapty, đặt ios.idfaCollectionDisabled (iOS) hoặc android.adIdCollectionDisabled (Android) thành true để tắt thu thập ID quảng cáo. Giá trị mặc định là false.

Dùng tham số này để tuân thủ chính sách 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({
  apiKey: 'YOUR_PUBLIC_SDK_KEY',
  params: {
    ios: {
      idfaCollectionDisabled: true,
    },
    android: {
      adIdCollectionDisabled: true,
    },
  }
});

Thiết lập cấu hình bộ đệm media cho AdaptyUI

Theo mặc định, AdaptyUI lưu bộ đệm media (như hình ảnh và video) để cải thiện hiệu suất và giảm sử dụng mạng. Bạn có thể tùy chỉnh cài đặt bộ đệm bằng cách cung cấp cấu hình tùy chỉnh.

Dùng mediaCache để ghi đè cài đặt bộ đệm mặc định:

await adapty.activate({
  apiKey: 'YOUR_PUBLIC_SDK_KEY',
  params: {
    mediaCache: {
      memoryStorageTotalCostLimit: 200 * 1024 * 1024, // Optional: memory cache size in bytes
      memoryStorageCountLimit: 2147483647,            // Optional: max number of items in memory
      diskStorageSizeLimit: 200 * 1024 * 1024,       // Optional: disk cache size in bytes
    },
  }
});

Tham số:

Tham sốBắt buộcMô tả
memoryStorageTotalCostLimittùy chọnTổng kích thước bộ đệm trong bộ nhớ tính bằng byte. Mặc định theo giá trị của nền tảng.
memoryStorageCountLimittùy chọnGiới hạn số lượng mục trong bộ nhớ đệm. Mặc định theo giá trị của nền tảng.
diskStorageSizeLimittùy chọnGiới hạn kích thước file trên đĩa tính bằng byte. Mặc định theo giá trị của nền tảng.

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, đặt localAccessLevelAllowed thành true:

await adapty.activate({
    apiKey: 'YOUR_PUBLIC_SDK_KEY',
    params: {
        android: {
            localAccessLevelAllowed: true,
        },
    }
});

Xóa dữ liệu khi khôi phục từ backup

Khi clearDataOnBackup được đặt thành true, SDK phát hiện khi ứng dụng được khôi phục từ backup iCloud và xóa toàn bộ dữ liệu SDK được lưu 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 khởi tạo lại với trạng thái sạch. Giá trị mặc định là false.

Chỉ bộ nhớ đệm 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({
    apiKey: 'YOUR_PUBLIC_SDK_KEY',
    params: {
        ios: {
            clearDataOnBackup: true,
        },
    }
});

Mẹo cho môi trường phát triển

Xử lý lỗi kích hoạt SDK khi dùng live-reload của Capacitor

Khi phát triển với Adapty SDK trong Capacitor, bạn có thể gặp lỗi: Adapty can only be activated once. Ensure that the SDK activation call is not made more than once.

Lỗi này xảy ra vì tính năng live-reload của Capacitor kích hoạt nhiều lần gọi kích hoạt trong quá trình phát triển. Để tránh điều này, dùng tùy chọn __ignoreActivationOnFastRefresh và đặt nó thành biến cờ chế độ phát triển của Capacitor — giá trị này sẽ khác nhau tùy theo bundle bạn đang dùng.

try {
  await adapty.activate({
    apiKey: 'YOUR_PUBLIC_SDK_KEY',
    params: {
        // Set your development environment variable
      __ignoreActivationOnFastRefresh: true,
    }
  });
} catch (error) {
  console.error('Failed to activate Adapty SDK:', error);
  // Handle the error appropriately for your app
}

Xử lý sự cố

Lỗi phiên bản iOS tối thiểu

Nếu bạn gặp lỗi phiên bản iOS tối thiểu, hãy cập nhật Podfile:

-platform :ios, min_ios_version_supported
+platform :ios, '14.0'  # For core features only
# OR
+platform :ios, '15.0'  # If using paywalls created in the paywall builder

Quy tắc backup Android (Cấu hình Auto Backup)

Một số SDK (bao gồm Adapty) đi kèm với cấu hình Android Auto Backup riêng. Nếu bạn sử dụng nhiều SDK có đị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)

Những thay đổi này cần được thực hiện trong thư mục platform Android của bạn (thường nằm trong thư mục android/ của dự án).

Để khắc phục, bạn cần:

  • Yêu cầu manifest merger sử dụng các 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, hãy đảm bảo thẻ gốc <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 các 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 đã merge

Tạo các file XML trong thư mục res/xml/ của dự án Android, 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 OS, 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 sử dụng AppsFlyer làm SDK bên thứ ba mẫu. 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"/>

    

Sau khi thay đổi các file Android gốc, chạy npx cap sync android để Capacitor cập nhật các tài nguyên đã thay đổi nếu bạn tạo lại nền tảng.

Mua hàng thất bại sau khi quay lại từ ứng dụng khác trên Android

Nếu Activity khởi động flow 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 nó 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ả mua hàng bị mất hoặc bị xử lý là đã hủy.

Để đảm bảo mua hàng hoạt động đúng, chỉ sử dụng chế độ khởi chạy standard hoặc singleTop cho Activity khởi động flow mua hàng, và tránh các chế độ khác.

Trong AndroidManifest.xml của bạn, đả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

Khi build ứng dụng Capacitor cho iOS, bạn có thể thấy các lỗi biên dịch Swift 6 trên các pod target của Adapty. Các triệu chứng điển hình bao gồm lỗi không khớp @Sendable trong AdaptyUIBuilderLogic, thiếu conformance Sendable trên các kiểu Adapty, hoặc lỗi cô lập actor.

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 Adapty (Adapty, AdaptyUI, AdaptyUIBuilder, AdaptyLogger, AdaptyPlugin) cần build với Swift 6.

Nguyên nhân phổ biến nhất là hook post_install trong ios/App/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 sửa: Loại trừ các pod target của Adapty khỏi việc 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 npx cap sync ios và build lại.

Để xác minh, mở ios/App/Pods/Pods.xcodeproj, chọn pod target AdaptyBuild SettingsSwift Language Version. Giá trị phải là Swift 6.