iOS SDK Initialization
Initialization Timing
The UjuAd SDK must be initialized in the didFinishLaunchingWithOptions method of AppDelegate to ensure initialization is completed at app launch, preparing for subsequent ad loading.
The iOS SDK uses a two-phase initialization mechanism to meet privacy compliance requirements:
- Phase 1 (
initialize): Synchronously saves configuration. No network/device operations, no privacy data collection. - Phase 2 (
start): Asynchronously executes initialization, collects device information and fetches strategies, then calls backlistenerupon completion.
Basic Initialization
1. Complete Two-Phase Initialization in AppDelegate
import UIKit
import UjuAdCore
@main
final class AppDelegate: UIResponder, UIApplicationDelegate {
private let initListener = AppInitListener()
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 阶段 1:构造配置 + initialize(同步,无网络/设备操作,可安全在主线程调用)
let config = UjuAdInitConfig.create(
appId: "YOUR_APP_ID", // 必填,优聚智汇平台分配
appKey: "YOUR_APP_KEY", // 必填,RSA 公钥(后台分配,原样传入)
channel: "AppStore", // 渠道,默认 AppStore
isDebug: true, // 调试模式,发布前改为 false
region: .domestic, // 服务区域:.domestic(国内)/ .singapore(海外)
rsaPublicKey: "YOUR_RSA_PUBLIC_KEY" // For server-side communication encryption (optional, empty means no encryption)
)
UjuAdCore.shared.initialize(application, config: config)
// 阶段 2:异步启动 SDK(内部按多步骤执行,完成后回调 listener)
UjuAdCore.shared.start(initListener)
return true
}
}
// MARK: - InitListener
final class AppInitListener: BaseInitListener, @unchecked Sendable {
func onInitSuccess() {
// SDK 启动成功,可以开始加载广告
print("SDK 初始化成功(version=\(UjuAdCore.shared.getVersion()))")
}
func onInitFailed(error: UjuException) {
// SDK 初始化失败
print("SDK 初始化失败: \(error.description)")
}
}Callback Thread
onInitSuccess / onInitFailed are called on the MainActor (main thread) and can safely update UI.
2. Configuration Parameters (UjuAdInitConfig.create)
UjuAdInitConfig's init is private. You must construct it via the create(...) factory method.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
appId | String | Yes | — | App ID, obtained from the UjuAd backend |
appKey | String | Yes | — | RSA public key, obtained from the backend, pass as-is, do not modify |
channel | String | No | "AppStore" | Channel identifier, used for analytics and revenue sharing |
subChannel | String | No | "" | Sub-channel |
isDebug | Bool | No | false | Debug mode, recommended during development (outputs SDK internal NSLog) |
wxAppId | String? | No | nil | WeChat AppId, used for Deeplink attribution |
privacyConfig | UjuPrivacyConfig | No | UjuPrivacyConfig() | Privacy authorization configuration |
personalization | UjuPersonalizedConfig | No | UjuPersonalizedConfig() | Personalized recommendation configuration |
presetStrategyFileName | String? | No | nil | Preset strategy file name, e.g. "placement_config.json" |
region | UjuAdRegion | No | .domestic | Service region; the SDK derives service hosts based on this |
rsaPublicKey | String | No | "" | RSA public key (PEM), used for server-side communication encryption; empty means no encryption |
loggerBackend | UjuLoggerBackend | No | .nsLog | Log backend type (.nsLog / .osLog / .fileLog / .hybrid) |
debugBidRequest | Bool | No | false | Whether to output BidRequest JSON debug logs (only effective when isDebug=true) |
crashReportingEnabled | Bool | No | true | Whether to enable crash reporting |
region Description
Integrators only need to select region (.domestic for China / .singapore for overseas). All service addresses are automatically derived by the SDK based on region and are not exposed to integrators. Do not attempt to configure server addresses yourself.
3. UjuAdRegion Enum
| Enum Value | Description |
|---|---|
.domestic | China |
.singapore | Overseas |
let region = UjuAdCore.shared.getRegion() // .domestic / .singaporePrivacy Configuration UjuPrivacyConfig
Describes the scope of privacy data the SDK is allowed to collect. All fields default to false (strictest privacy compliance). The integrator must explicitly enable authorization fields.
| Field | Type | Default | Description |
|---|---|---|---|
canUseIDFA | Bool | false | Whether IDFA usage is allowed (requires ATT authorization) |
canUseIDFV | Bool | false | Whether IDFV usage is allowed |
canUseLocation | Bool | false | Whether location usage is allowed |
canUseImei | Bool | false | Whether IMEI usage is allowed (iOS typically does not allow; field retained for compatibility) |
canUseOaid | Bool | false | Whether OAID usage is allowed (iOS has no equivalent; field retained for compatibility) |
canUseMac | Bool | false | Whether MAC address usage is allowed (iOS typically does not allow; field retained for compatibility) |
let privacyConfig = UjuPrivacyConfig(
canUseIDFA: true, // 需 ATT 授权
canUseIDFV: true,
canUseLocation: true
)
let config = UjuAdInitConfig.create(
appId: "YOUR_APP_ID",
appKey: "YOUR_APP_KEY",
privacyConfig: privacyConfig
)Privacy Compliance
It is recommended to enable canUseIDFA / canUseLocation and other authorization fields only after obtaining explicit user consent. When not enabled, the SDK still works, but attribution accuracy may decrease.
Personalization Configuration UjuPersonalizedConfig
Complies with the Personal Information Protection Law. All fields default to false (strictest compliance). The integrator must explicitly enable them.
| Field | Type | Default | Description |
|---|---|---|---|
personalizedRecommend | Bool | false | Whether personalized recommendations are allowed |
programmaticRecommended | Bool | false | Whether programmatic recommendations are allowed |
let personalization = UjuPersonalizedConfig(
personalizedRecommend: true,
programmaticRecommended: true
)
let config = UjuAdInitConfig.create(
appId: "YOUR_APP_ID",
appKey: "YOUR_APP_KEY",
personalization: personalization
)Update Channel Information
After SDK initialization is complete, you can dynamically update the channel and sub-channel via updateChannel:
UjuAdCore.shared.updateChannel(channel: "新渠道", subChannel: "新子渠道")Initialization State Check
// 是否已完成 initialize(第一阶段)
if UjuAdCore.shared.isSdkInitialized() {
// 已完成 init,可调用 start
}
// 获取初始化状态枚举
let state = UjuAdCore.shared.getInitializeState()
switch state {
case .idle: print("未初始化")
case .initializing: print("初始化中")
case .initialized: print("已初始化")
case .failed: print("初始化失败")
}UjuAdInitStatus Enum
| Enum Value | Description |
|---|---|
.idle | Idle state, start() has not been called yet |
.initializing | Initializing, collecting device information and fetching strategies |
.initialized | Initialized, ads can be loaded normally |
.failed | Initialization failed |
SDK Other Public Methods
In addition to initialize / start / updateChannel, UjuAdCore provides the following public methods:
| Method | Return Value | Description |
|---|---|---|
isSdkInitialized() | Bool | Whether initialize (phase 1) has completed |
getInitializeState() | UjuAdInitStatus | Get initialization state enum |
getVersion() | String | Get SDK version number (currently 3.4.2) |
getAppId() | String | Get current app ID |
getRegion() | UjuAdRegion | Get service region |
getIDFA() | String | Get IDFA (returns empty string if unauthorized) |
getIDFV() | String | Get IDFV |
requestAttAuthorization(completion:) | Void | Request ATT authorization |
requestLocation(completion:) | Void | One-time location request |
setIDFA(_:) | Void | Developer-injected IDFA |
setUserInfo(_:) | Void | Inject user information |
setLocation(_:) | Void | Inject location information |
registerAdapterFactory(_:) | Bool | Register a single adapter factory |
destroy() | Void | Release SDK resources |
getConnectionSnapshots() | [ConnectionSnapshot] | Diagnostic: Get gRPC connection pool snapshots (for debugging, not needed for normal integration) |
getConnectionCount() | Int | Diagnostic: Get current connection count |
getRecentConnectionEventLogs(limit:) | [ConnectionEventLog] | Diagnostic: Get recent connection event logs |
// 获取 SDK 版本号
print("SDK 版本: \(UjuAdCore.shared.getVersion())") // 3.4.2Destroy SDK (Optional)
Call when the app exits or when you need to reset the SDK:
UjuAdCore.shared.destroy()Note: After
destroy, if you need to use the SDK again, you must callinitialize+startagain.
FAQ
Q: What to do if initialization fails?
A: Possible causes:
- Whether
appId/appKey(RSA public key) is correct - Whether
regionis selected correctly (.domesticfor China /.singaporefor overseas) - Whether the network connection is normal
- Enable
isDebug = trueand check the console logs for the specific failure reason
Q: Why don't I need to configure server addresses?
A: Integrators only need to select region. All service hosts are automatically derived by the SDK based on region and are not exposed to integrators. This is a fixed internal platform configuration and is not something integrators should decide.
Q: What if IDFA cannot be obtained?
A: iOS 14+ requires ATT user authorization. Please confirm:
Info.plisthasNSUserTrackingUsageDescriptionconfiguredUjuPrivacyConfig.canUseIDFAis set totrue- User has authorized
ATTrackingManager.AuthorizationStatus.authorized - When unauthorized, the SDK still works (uses IDFV as fallback), but attribution accuracy decreases
Best Practices
- Initialize early: Complete two-phase initialization in
didFinishLaunchingWithOptions - Strict two-phase order: Must call
initializefirst, thenstart - Handle failures: Implement
onInitFailedto ensure the app still runs normally when initialization fails - Debug mode: Set
isDebug = trueduring development, change tofalsebefore release - Privacy compliance:
UjuPrivacyConfigdefaults to all false; explicitly enable authorization fields as needed - Resource release: Call
destroy()when the app exits
Next Steps
After completing SDK initialization, you can start integrating specific ad types:
Related Links
- API Reference — Complete API signatures and field descriptions
- Error Codes — SDK error code descriptions
- Preparation — Environment requirements and dependency setup
