---
title: "Cài đặt & cấu hình iOS SDK"
description: "Hướng dẫn từng bước cài đặt Adapty SDK trên iOS cho các ứng dụng dựa trên gói đăng ký."
---

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

- **Core Adapty**: Module SDK cốt lõi, bắt buộc phải có để Adapty hoạt động đúng trong ứng dụng.
- **AdaptyUI**: Module tùy chọn, cần thiết nếu bạn sử dụng [Adapty Paywall Builder](adapty-paywall-builder) — công cụ no-code thân thiện giúp tạo paywall đa nền tảng dễ dàng.

:::tip
Muốn xem ví dụ thực tế về cách tích hợp Adapty SDK vào ứng dụng? Hãy xem [ứng dụng mẫu](https://github.com/adaptyteam/AdaptySDK-iOS/tree/master/Examples) 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.
:::

Để xem hướng dẫn triển khai đầy đủ, bạn cũng có thể xem các video sau:

<Tabs groupId="current-os" queryString>
<TabItem value="swiftui" label="iOS (SwiftUI)" default>

<div style={{ textAlign: 'center' }}>
<iframe width="560" height="315" src="https://www.youtube.com/embed/cSChHc8k2zA?si=KhNFhqXccIzYwTcm" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div>
</TabItem>
<TabItem value="uikit" label="iOS (UIKit)" default>

<div style={{ textAlign: 'center' }}>
<iframe width="560" height="315" src="https://www.youtube.com/embed/WEUnlaAjSI0?si=sjXKVVb56tEHDKzJ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div>
</TabItem>
</Tabs>

## Yêu cầu \{#requirements\}

Adapty iOS SDK yêu cầu iOS 15.0 trở lên.

:::important
Adapty SDK 3.15.7+ là bắt buộc khi build với Xcode 26.4 trở lên.
:::

---
no_index: true
---
import Callout from '../../../components/Callout.astro';

<Callout type="info">
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](quickstart) sẽ hướng dẫn bạn qua tất cả các bước cần thiết.
</Callout>

## Cài đặt Adapty SDK \{#install-adapty-sdk\}

[![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-iOS.svg?style=flat&logo=apple)](https://github.com/adaptyteam/AdaptySDK-iOS/releases)

Adapty SDK được cài đặt qua Swift Package Manager. Trong Xcode, vào **File** -> **Add Package Dependency...**. Lưu ý rằng các bước thêm package dependency có thể khác nhau tùy phiên bản Xcode, vì vậy hãy tham khảo tài liệu Xcode nếu cần.

1. Nhập URL repository:
   ```
   https://github.com/adaptyteam/AdaptySDK-iOS.git
   ```
2. Chọn phiên bản (khuyến nghị chọn phiên bản ổn định mới nhất) và nhấn **Add Package**.
3. Trong cửa sổ **Choose Package Products**, chọn các module bạn cần:
   - **Adapty** (module cốt lõi)
   - **AdaptyUI** (tùy chọn - chỉ khi bạn dự định sử dụng Paywall Builder)
   :::note
   Lưu ý:
     - Để bật [chế độ Kids](kids-mode), hãy chọn **Adapty_KidsMode** thay vì **Adapty**.
     - Không chọn các package khác trong danh sách – bạn sẽ không cần chúng.
   :::
4. Nhấn **Add Package** để hoàn tất cài đặt.
5. **Kiểm tra cài đặt:** Trong project navigator, bạn sẽ thấy "Adapty" (và "AdaptyUI" nếu đã chọn) dưới mục **Package Dependencies**.

:::important
Adapty iOS SDK 4.0 là phiên bản pre-release. Swift Package Manager không tự động resolve các phiên bản beta qua quy tắc **Up to Next Major Version** (`from:`), vì vậy bạn phải chỉ định chính xác phiên bản. Trong Xcode, đặt **Dependency Rule** thành **Exact Version** và nhập `4.0.0-beta.1`. Trong `Package.swift`, dùng `.exact("4.0.0-beta.1")`. Xem [Migrate Adapty iOS SDK lên v4](migration-to-ios-sdk-v4).
:::

## Kích hoạt module Adapty của Adapty SDK \{#activate-adapty-module-of-adapty-sdk\}

Kích hoạt Adapty SDK trong code của ứng dụng.

:::note
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. Truy cập Adapty Dashboard và điều hướng đến [**App settings → General**](https://app.adapty.io/settings/general).
2. Trong phần **Api keys**, sao chép **Public SDK Key** (KHÔNG phải Secret Key).
3. Thay thế `"YOUR_PUBLIC_SDK_KEY"` trong code.

Hoặc lấy theo cách lập trình, sử dụng [Adapty CLI](developer-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](getting-started-with-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.

<Tabs groupId="current-os" queryString>
<TabItem value="swiftui" label="SwiftUI">

```swift showLineNumbers

@main
struct YourApp: App {
  init() {
    // Configure Adapty SDK
    let configurationBuilder = AdaptyConfiguration
      .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY") // Get from Adapty dashboard

   Adapty.logLevel = .verbose // recommended for development and the first production release

    let config = configurationBuilder.build()

    // Activate Adapty SDK asynchronously
    Task {
      do {
        try await Adapty.activate(with: config)
      } catch {
        // Handle error appropriately for your app
        print("Adapty activation failed: ", error)
      }
    }

    var body: some Scene {
      WindowGroup {
        // Your content view
      }
    }
  }
}
```

</TabItem>
<TabItem value="swift" label="UIKit" default>

```swift showLineNumbers
// In your AppDelegate class:
// If you only use an AppDelegate, place the following code in the
// application(_:didFinishLaunchingWithOptions:) method.

// If you use a SceneDelegate, place the following code in the
// scene(_:willConnectTo:options:) method.

Task {
  do {
    let configurationBuilder = AdaptyConfiguration
      .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY") // Get from Adapty dashboard
      .with(logLevel: .verbose) // recommended for development and the first production release

    let config = configurationBuilder.build()
    try await Adapty.activate(with: config)
  } catch {
    // Handle error appropriately for your app
    print("Adapty activation failed: ", error)
  }
}
```

</TabItem>
</Tabs>

:::important
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 iOS SDK](ios-sdk-call-order) để biết trình tự đầy đủ.
:::

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

- Nếu bạn dùng [Adapty Paywall Builder](adapty-paywall-builder), trước tiên hãy [kích hoạt module AdaptyUI](#activate-adaptyui-module-of-adapty-sdk) bên dưới, sau đó làm theo [hướng dẫn nhanh Paywall Builder](ios-quickstart-paywalls).
- 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](ios-quickstart-manual).

## Kích hoạt module AdaptyUI của Adapty SDK \{#activate-adaptyui-module-of-adapty-sdk\}

Nếu bạn dự định dùng [Paywall Builder](adapty-paywall-builder) và đã [cài đặt module AdaptyUI](sdk-installation-ios#install-adapty-sdk), bạn cũng cần kích hoạt AdaptyUI.

:::important
Trong code, bạn phải kích hoạt module Adapty cốt lõi trước khi kích hoạt AdaptyUI.
:::

<Tabs groupId="current-os" queryString>
<TabItem value="swiftui" label="SwiftUI">

```swift showLineNumbers title="Swift"

@main
struct YourApp: App {
  init() {
    // ...ConfigurationBuilder steps

    // Activate Adapty SDK asynchronously
    Task {
      do {
        try await Adapty.activate(with: config)
        try await AdaptyUI.activate()
      } catch {
        // Handle error appropriately for your app
        print("Adapty activation failed: ", error)
      }
    }

    // main body...
  }
}
```
</TabItem>
<TabItem value="uikit" label="UIKit" default>

```swift showLineNumbers title="UIKit"
// If you only use an AppDelegate, place the following code in the
// application(_:didFinishLaunchingWithOptions:) method.

// If you use a SceneDelegate, place the following code in the
// scene(_:willConnectTo:options:) method.

Task {
   do {
      let configurationBuilder = AdaptyConfiguration
         .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY") // Get from Adapty dashboard
         .with(logLevel: .verbose) // recommended for development

   let config = configurationBuilder.build()
   try await Adapty.activate(with: config)
   try await AdaptyUI.activate()
      } catch {
      // Handle error appropriately for your app
      print("Adapty activation failed: ", error)
   }
}
```
</TabItem>
</Tabs>

:::tip
Tùy chọn, khi kích hoạt AdaptyUI, bạn có thể [ghi đè cài đặt cache mặc định cho paywall](#set-up-media-cache-configuration-for-adaptyui).
:::

## Cài đặt tùy chọn \{#optional-setup\}

### Logging \{#logging\}

#### Thiết lập hệ thống logging \{#set-up-the-logging-system\}

Adapty ghi log các lỗi và thông tin quan trọng khác để giúp bạn hiểu những gì đang xảy ra. Các cấp độ log có sẵn:

| Cấp độ     | Mô tả                                                        |
| ---------- | ------------------------------------------------------------ |
| `error`    | Chỉ ghi log các lỗi                                          |
| `warn`     | Ghi log 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ú ý |
| `info`     | Ghi log các lỗi, cảnh báo và các thông báo thông tin khác nhau |
| `verbose`  | Ghi log mọi thông tin bổ sung có thể hữu ích trong quá trình debug, chẳng hạn như lời gọi hàm, API query, v.v. |

```swift showLineNumbers
 let configurationBuilder = AdaptyConfiguration
         .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY")
         .with(logLevel: .verbose) // recommended for development
```

#### Chuyển hướng thông báo từ hệ thống logging \{#redirect-the-logging-system-messages\}

Nếu bạn cần gửi log của Adapty đến hệ thống của mình hoặc lưu vào file, hãy dùng phương thức `setLogHandler` và triển khai logic logging tùy chỉnh bên trong. Handler này nhận các bản ghi log chứa nội dung thông báo và cấp độ nghiêm trọng.

```swift showLineNumbers title="Swift"
Adapty.setLogHandler { record in
    writeToLocalFile("Adapty \(record.level): \(record.message)")
}
```

### Chính sách dữ liệu \{#data-policies\}

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, nhưng bạn có thể áp dụng thêm các chính sách bảo mật dữ liệu để tuân thủ hướng dẫn của cửa hàng hoặc quy định của từng quốc gia.

#### Tắt thu thập và chia sẻ IDFA \{#disable-idfa-collection-and-sharing\}

Khi kích hoạt module Adapty, đặt `idfaCollectionDisabled` thành `true` để tắt thu thập và chia sẻ IDFA.

Dùng tham số này để tuân thủ App Store Review Guidelines hoặc tránh kích hoạt lời nhắc App Tracking Transparency khi IDFA không cần thiết cho ứng dụng của bạn. Giá trị mặc định là `false`. Để biết thêm chi tiết về thu thập IDFA, tham khảo phần [Tích hợp Analytics](analytics-integration#disable-collection-of-advertising-identifiers).

```swift showLineNumbers
let configurationBuilder =
    AdaptyConfiguration
        .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY")
        .with(idfaCollectionDisabled: true)
```

#### Tắt thu thập và chia sẻ địa chỉ IP \{#disable-ip-collection-and-sharing\}

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 theo 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 các tính năng dựa trên IP không bắt buộc trong ứng dụng của bạn.

```swift showLineNumbers
let configurationBuilder =
    AdaptyConfiguration
        .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY")
        .with(ipAddressCollectionDisabled: true)
```

#### Cấu hình media cache cho paywall trong AdaptyUI \{#set-up-media-cache-configuration-for-adaptyui\}

Lưu ý rằng cấu hình AdaptyUI là tùy chọn. Bạn có thể kích hoạt module AdaptyUI mà không cần config. Tuy nhiên, nếu bạn dùng config, tất cả các tham số đều bắt buộc.

```swift showLineNumbers title="Swift"

// Configure AdaptyUI
        let adaptyUIConfiguration = AdaptyUI.Configuration(
            mediaCacheConfiguration: .init(
                memoryStorageTotalCostLimit: 100 * 1024 * 1024,
                memoryStorageCountLimit: .max,
                diskStorageSizeLimit: 100 * 1024 * 1024
            )
        )

        // Activate AdaptyUI
        AdaptyUI.activate(configuration: adaptyUIConfiguration)
```
Tham số:

| Tham số                     | Bắt buộc | Mô tả                                                        |
| :-------------------------- | :------- | :----------------------------------------------------------- |
| memoryStorageTotalCostLimit | bắt buộc | Tổng giới hạn chi phí lưu trữ tính bằng byte.               |
| memoryStorageCountLimit     | bắt buộc | Giới hạn số lượng item của bộ nhớ lưu trữ.                  |
| diskStorageSizeLimit        | bắt buộc | Giới hạn kích thước file trên đĩa của bộ nhớ lưu trữ tính bằng byte. Giá trị 0 nghĩa là không giới hạn. |

### Hành vi hoàn tất giao dịch \{#transaction-finishing-behavior\}

:::info
Tính năng này có sẵn từ SDK phiên bản 3.12.0 trở lên.
:::

Mặc định, Adapty tự động hoàn tất giao dịch sau khi xác thực thành công. Tuy nhiên, nếu bạn cần xác thực giao dịch nâng cao (như xác thực receipt phía server, phát hiện gian lận hoặc logic nghiệp vụ tùy chỉnh), bạn có thể cấu hình SDK để hoàn tất giao dịch thủ công.

```swift showLineNumbers title="Swift"
let configurationBuilder = AdaptyConfiguration
    .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY")
    .with(transactionsFinishBehavior: .manual) // .auto is the default
```

Xem thêm chi tiết về cách hoàn tất giao dịch trong [hướng dẫn](ios-transaction-management).

### Xóa dữ liệu khi khôi phục từ backup \{#clear-data-on-backup-restore\}

Khi `clearDataOnBackup` được đặt thành `true`, SDK sẽ 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 trữ cục bộ, bao gồm thông tin hồ sơ người dùng được 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`.

:::note
Chỉ xóa cache SDK cục bộ. Lịch sử giao dịch với Apple và dữ liệu người dùng trên server Adapty vẫn được giữ nguyên.
:::

```swift showLineNumbers
let configurationBuilder = AdaptyConfiguration
    .builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY")
    .with(clearDataOnBackup: true) // default – false
```

## Xử lý sự cố \{#troubleshooting\}

#### Lỗi Swift 6 concurrency với Tuist \{#swift-6-concurrency-error-with-tuist\}

Khi build với [Tuist](https://tuist.dev/), bạn có thể gặp lỗi biên dịch Swift 6 strict concurrency. Triệu chứng điển hình bao gồm lỗi không khớp thuộc tính `@Sendable` trong `AdaptyUIBuilderLogic` hoặc các lỗi Sendability cross-module tương tự.

Nguyên nhân là Tuist tạo project Xcode từ các SPM package nhưng không giữ lại cài đặt `swift-tools-version: 6.0`. Kết quả là một số target Adapty (`Adapty`, `AdaptyUI`, `AdaptyUIBuilder`) biên dịch với quy tắc Swift 5 trong khi các target khác dùng Swift 6, tạo ra lỗi `@Sendable` cross-module.

**Cách khắc phục**: Nâng cấp lên Adapty SDK **3.15.5** trở lên, phiên bản này giải quyết vấn đề bất kể phiên bản ngôn ngữ Swift hỗn hợp.

**Cách tạm thời**: Nếu bạn không thể nâng cấp, hãy đặt rõ Swift 6 cho cả ba target Adapty trong cấu hình Tuist:

```swift showLineNumbers
targetSettings: [
  "Adapty": .init().swiftVersion("6"),
  "AdaptyUI": .init().swiftVersion("6"),
  "AdaptyUIBuilder": .init().swiftVersion("6"),
]
```