Apps Kit SDK logoApps Kit SDK
Tài liệu · Tích hợp iOS

4. Khởi tạo SDK

4.1 AppDelegate

Tạo lớp kế thừa AKSBaseAppDelegate — lớp cơ sở theo mẫu thiết kế Template Method, tự động thiết lập Firebase, khởi tạo AdMob, khởi tạo SDK và nạp cấu hình từ xa, đồng thời cung cấp một số hook open để bạn tùy chỉnh cho ứng dụng.

swift
import UIKit
import AppsKit
import AKSKit

class AppDelegate: AKSBaseAppDelegate {

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        AppsKitSDKAdsManagerIOS.instance.initialize(userHasGivenConsent: true, isCCPAConsent: true)

        // super.application(...) does, in order:
        //   FirebaseApp.configure() -> MobileAds.shared.start() -> setupAdBridge()
        //   -> AppsKitSDK init/setDevMode/setTestMode/saveDefaultConfigJson
        //   -> configureSDK() -> manageRemoteConfigs(...)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    /// Called by the base class during the sequence above. Optional — only needed if your
    /// app has its own ad-loading abstraction layer that needs to be wired up to AKS. If you
    /// call `AppsKitSDKAdsManagerIOS.instance` directly from your own Swift code (§5), leave
    /// this empty.
    override func setupAdBridge() {}

    override func isDevMode() -> Bool { return false } // wire to your own debug flag
    override func isTestMode() -> Bool { return false }

    override func defaultConfigJson() -> String? {
        return "<encrypted-config-json-from-aks-portal>"
    }

    /// Called after dev/test mode flags are applied — use this for anything that needs
    /// to happen after the base setup but before remote config is ready (e.g. initializing
    /// AppLovin MAX directly).
    override func configureSDK() {}

    override func onConfigsReadyToUse() {
        // optional — fires once Firebase Remote Config has been fetched/activated
    }
}

Danh sách đầy đủ các hook open trong AKSBaseAppDelegate: setupAdBridge(), isDevMode() -> Bool (mặc định false), isTestMode() -> Bool (mặc định false), defaultConfigJson() -> String? (mặc định nil), timeToFetchRemoteConfigInSeconds() -> Int (mặc định 3600), onConfigsReadyToUse(), configureSDK().

4.2 Khởi tạo mà không kế thừa AKSBaseAppDelegate

Không bắt buộc phải kế thừa AKSBaseAppDelegate — đây chỉ là lớp bao giúp đơn giản hóa việc tích hợp. Nếu ứng dụng đã có UIApplicationDelegate riêng mà bạn cần giữ lại, hãy gọi trực tiếp các phương thức AppsKitSDK/AKSKit mà lớp này sử dụng nội bộ từ application(_:didFinishLaunchingWithOptions:) của bạn:

swift
import UIKit
import AppsKit   // for makeDefaultIOSAdHandler() — see below
import AKSKit
import FirebaseCore
import FirebaseRemoteConfig
import GoogleMobileAds

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        FirebaseApp.configure()
        MobileAds.shared.start()

        // If your app has its own ad-loading abstraction layer to wire up to AKS, do it
        // around here — most apps don't need this; see §5 to call ad formats directly.

        let sdkInstance = AppsKitSDK.shared
        sdkInstance.setIOSAdHandler(iosAdHandler: makeDefaultIOSAdHandler())
        sdkInstance.initialize(
            context: PlatformContext(delegate: nil),
            application: PlatformApplication(application: UIApplication.shared)
        )

        sdkInstance.setDevMode(value: false) // wire to your own debug flag
        sdkInstance.setTestMode(value: false)
        sdkInstance.setTimeToFetchRemoteConfigInSeconds(intervalToFetchRemoteConfigInSeconds: 3600) // optional, defaults to 3600

        sdkInstance.saveDefaultConfigJson(encryptedJson: "<encrypted-config-json-from-aks-portal>")
        sdkInstance.manageRemoteConfigs(onRemoteConfigReady: RemoteConfigReadyBridge {
            // optional — your own hook into the fetched remote config
        })

        AdsManager.shared.setAppExitTime(appExitTime: 0)
        AKSUtils.shared.cleanCachedData()

        return true
    }
}

// manageRemoteConfigs(onRemoteConfigReady:) takes an OnRemoteConfigAvailable, not a closure —
// AKSBaseAppDelegate has a private adapter for this internally; outside it, write your own:
private class RemoteConfigReadyBridge: NSObject, OnRemoteConfigAvailable {
    private let onReady: () -> Void
    init(_ onReady: @escaping () -> Void) { self.onReady = onReady }
    func onRemoteConfigReadyToFetch(remoteConfig: RemoteConfig) {
        DispatchQueue.main.async { self.onReady() }
    }
}

setIOSAdHandler(iosAdHandler:) cần một triển khai cụ thể của IOSPlatformAdHandler — triển khai mà AKSBaseAppDelegate sử dụng nội bộ (khởi tạo mediation AdMob/IronSource/MAX, gửi báo cáo AppsFlyer/Adjust) là một kiểu nội bộ của SDK, nên SDK cung cấp makeDefaultIOSAdHandler() để dùng chính trong trường hợp này.

Khi không kế thừa AKSBaseAppDelegate, bạn sẽ mất luồng tự động "quảng cáo App Open ở cấp ứng dụng" (§4.6) — requestSplashAppOpenAd/disableAppOpenSplashCallback/showAppOpenAdIfAvailable là các phương thức instance của chính AKSBaseAppDelegate, không được cung cấp trên đối tượng AppsKitSDK thuần. Cơ chế theo dõi trạng thái foreground/background để điều khiển các phương thức này cũng nằm trong các phương thức ghi đè applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive của AKSBaseAppDelegate. Nếu vẫn muốn hiển thị quảng cáo App Open, hãy tự gọi AppsKitSDKAdsManagerIOS.instance.loadAppOpen/showAppOpen (§5, App Open) tại thời điểm phù hợp trong luồng khởi động của bạn.

4.3 Điểm khởi chạy ứng dụng SwiftUI

Nếu ứng dụng sử dụng giao thức App của SwiftUI thay vì storyboard, hãy kết nối với AppDelegate bằng @UIApplicationDelegateAdaptor — đây chính là cơ chế khiến application(_:didFinishLaunchingWithOptions:) được thực thi:

swift
import SwiftUI

@main
struct YourApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Toàn bộ trình tự khởi tạo ở §4.1 chạy đồng bộ trong didFinishLaunchingWithOptions, trước khi WindowGroup được render — vì vậy cầu nối quảng cáo và SDK đã sẵn sàng trước khi bất kỳ giao diện nào xuất hiện.

4.4 Sự đồng ý của người dùng và khởi tạo quảng cáo

swift
AppsKitSDKAdsManagerIOS.instance.initialize(userHasGivenConsent: true, isCCPAConsent: true)

Bản tích hợp tham khảo gán cứng cả hai cờ thành true — chưa tích hợp luồng xin sự đồng ý UMP/CMP ở bất kỳ đâu. Đây là phần còn thiếu, không phải cách làm được khuyến nghị: nếu ứng dụng thuộc phạm vi áp dụng của GDPR/CCPA, hãy triển khai luồng xin sự đồng ý của riêng bạn (UMP SDK của Google đã có sẵn dưới dạng dependency bắc cầu thông qua Google-Mobile-Ads-SDK, §1.2 — bạn chỉ cần gọi SDK này) hoặc dùng CMP tùy chỉnh, rồi truyền lựa chọn thực tế của người dùng vào lời gọi này thay vì gán cứng true. Kết hợp với hộp thoại xin quyền ATT ở §3.3 nếu bạn cũng cần IDFA.

4.5 Tắt quảng cáo / kiểm soát theo IAP

swift
AppsKitSDK.shared.setRemoveAdsStatus(status: true)   // call after a successful purchase/restore
AppsKitSDK.shared.getRemoveAdsStatus()               // check current status

Mọi lời gọi tải/hiển thị quảng cáo đều đã kiểm tra trạng thái này ở bên trong — bạn không cần tự thêm điều kiện chặn. Lưu ý cách truy cập trong Swift: tất cả các kiểu manager này đều được cung cấp dưới dạng lớp với thuộc tính truy cập tĩnh .shared (AppsKitSDK.shared, AKSLogManager.shared, PreferencesManager.shared, v.v.) — bạn sẽ gặp cách truy cập này xuyên suốt SDK.

4.6 Quảng cáo App Open ở cấp ứng dụng

AKSBaseAppDelegate tự động theo dõi việc chuyển đổi giữa foreground/background (applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive) và sẽ hiển thị quảng cáo App Open khi ứng dụng được mở lại từ nền (warm start) nếu cấu hình trên cổng AKS đã bật isAppOpenAtApplicationLvl. Có ba phương thức dành cho luồng màn hình khởi động (splash) của bạn:

swift
// Call from your splash screen — requests and shows an app-open ad
(appDelegate as? AKSBaseAppDelegate)?.requestSplashAppOpenAd(callbacks: myCallbacks, waitTimeInSeconds: 5)

// Stop the splash screen's callback from firing again on subsequent app-open events
(appDelegate as? AKSBaseAppDelegate)?.disableAppOpenSplashCallback()

// Manually trigger "show if one's already loaded and ready" — used internally on resume
(appDelegate as? AKSBaseAppDelegate)?.showAppOpenAdIfAvailable()