4. Khởi tạo SDK
4.1 AppDelegate
Tạo lớp kế thừa AKSBaseAppDelegate — một 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.
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 của 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 không cần kế thừa AKSBaseAppDelegate
Không bắt buộc phải kế thừa AKSBaseAppDelegate — đây chỉ là lớp bọc 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 không thể thay thế, 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:
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 đối tượng triển khai cụ thể của IOSPlatformAdHandler — đối tượng mà AKSBaseAppDelegate sử dụng nội bộ (khởi tạo mediation AdMob/IronSource/MAX, gửi báo cáo AppsFlyer/Adjust) thuộc một kiểu nội bộ của SDK, nên SDK cung cấp makeDefaultIOSAdHandler() để lấy đối tượng này cho đúng trường hợp trên.
Khi không kế thừa AKSBaseAppDelegate, bạn sẽ không có 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 của chính đối tượng AKSBaseAppDelegate, không được cung cấp trên đối tượng AppsKitSDK thuần túy. Logic 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 mong muốn trong luồng khởi động của ứng dụng.
4.3 Điểm vào ứng dụng SwiftUI
Nếu ứng dụng sử dụng protocol 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 gọi:
import SwiftUI
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Toàn bộ quy trình khởi tạo trong §4.1 chạy đồng bộ bên trong didFinishLaunchingWithOptions, trước khi WindowGroup được kết xuất — 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 hiển thị.
4.4 Sự đồng ý của người dùng và khởi tạo quảng cáo
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— không có luồng xin sự đồng ý UMP/CMP nào được tích hợp. Đâ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 chịu sự điều chỉnh của GDPR/CCPA, hãy triển khai luồng xin sự đồng ý riêng (UMP SDK của Google đã có sẵn dưới dạng phụ thuộc bắc cầu thông quaGoogle-Mobile-Ads-SDK, §1.2 — bạn chỉ cần gọi SDK này) hoặc sử 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ứngtrue. Kết hợp với hộp thoại yêu cầu quyền ATT trong §3.3 nếu bạn cũng cần IDFA.
4.5 Tắt quảng cáo / Kiểm soát quảng cáo theo IAP
AppsKitSDK.shared.setRemoveAdsStatus(status: true) // call after a successful purchase/restore
AppsKitSDK.shared.getRemoveAdsStatus() // check current statusMọ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 kiểm soát. 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 có 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 các lần 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 thông tin AKS của bạn bật isAppOpenAtApplicationLvl. Có ba phương thức dành cho luồng màn hình khởi động (splash):
// 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()