5. استدعاء تنسيقات الإعلانات
لا يزال كل استدعاء يتلقى سلسلة نصية تمثل معرّف موضع الإعلان مُعدّة في بوابة AKS — ويحوّلها AKS أثناء التشغيل إلى شبكة إعلانية وقائمة شبكات بديلة تُستخدم عند الفشل.
5.1 نمط الربط
أنواع ردود النداء للإعلانات في AKS (AdsCallback وBannerCallback وNativeCallback وRewardedAdCallbacks وAppOpenAdCallbacks) هي أصناف ترث منها وتعيد تعريف أساليبها باستخدام override — وليست تعبيرات إغلاق (closures). النمط المتّبع (في جميع المكوّنات التي تستخدم AppsKitSDKAdsManagerIOS) هو إنشاء صنف مُحوِّل صغير وخاص لكل تنسيق، يتولى ما يلي:
- يرث من نوع رد النداء في AKS ويستدعي
super.init(). - يمرّر كل حدث من أحداث دورة الحياة إلى ما تحتاجه طبقة واجهة المستخدم لديك.
- بالنسبة إلى إعلانات البانر والإعلانات المدمجة مع المحتوى والإعلانات بمكافأة، ينفّذ بنفسه تسلسل التحميل ثم العرض — أي إن إعادة تعريف
onBannerLoaded()/onNativeLoaded()/onRewardedLoaded()في المُحوِّل هي التي تُطلق استدعاءshow...المقابل، مع إعادة استخدامselfبوصفه رد النداء لخطوة العرض أيضًا.
private class BannerCallbackAdapter: BannerCallback {
private let onLoaded: () -> Void
private let onFailed: (String) -> Void
private weak var container: UIView?
private let placeholder: String
init(container: UIView, placeholder: String, onLoaded: @escaping () -> Void, onFailed: @escaping (String) -> Void) {
self.container = container
self.placeholder = placeholder
self.onLoaded = onLoaded
self.onFailed = onFailed
super.init()
}
override func onBannerLoaded() {
onLoaded()
guard let vc = UIApplication.topViewController(), let view = container else {
onFailed("No active view controller found")
return
}
AppsKitSDKAdsManagerIOS.instance.showBanner(from: vc, placeholder: placeholder, container: view, callback: self)
}
override func onBannerFailedToLoad() { onFailed("") }
override func onBannerClicked() {}
override func onBannerShown() {}
override func onBannerSizeChanged(bannerSizes: BannerSizes) {}
override func setBannerSize(width: Double, height: Double) {}
}ينطلق UIApplication.topViewController() (الذي يوفّره AppsKit.xcframework كامتداد لـ UIApplication) من متحكّم العرض الجذري للنافذة الرئيسية، ويمرّ عبر أي متحكّم معروض أو متحكّم تنقّل أو متحكّم علامات تبويب للوصول إلى الشاشة الموجودة فعليًا في المقدّمة — ستحتاج إليه كلما تطلّب استدعاءٌ متحكّمَ عرض بينما لا يتوفر لديك سوى UIView، أو لا يتوفر لديك أي سياق لواجهة المستخدم.
الإعلانات البينية
// Load only
AppsKitSDKAdsManagerIOS.instance.loadInterstitial(from: viewController, placeholder: placeholder, callback: adapter)
// Show a previously loaded interstitial
AppsKitSDKAdsManagerIOS.instance.showInterstitial(from: viewController, placeholder: placeholder, callback: adapter)يرث adapter من AdsCallback:
private class InterstitialCallbackAdapter: AdsCallback {
private let onAdLoaded: () -> Void
private let onAdFailed: () -> Void
init(onAdLoaded: @escaping () -> Void, onAdFailed: @escaping () -> Void) {
self.onAdLoaded = onAdLoaded
self.onAdFailed = onAdFailed
super.init()
}
override func onLoaded() { onAdLoaded() }
override func onFailedToLoad() { onAdFailed() }
override func onAdShown() {}
override func onAdDismissed() {}
override func onAdFailedToShow() {}
}الإعلانات بمكافأة
// Separate load/show — chain load→show in your adapter's onRewardedLoaded(), same pattern as banner/native
AppsKitSDKAdsManagerIOS.instance.loadRewarded(from: viewController, placeholder: placeholder, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showRewarded(from: viewController, placeholder: placeholder, callback: adapter)يرث adapter من RewardedAdCallbacks ويربط onRewardedLoaded() مباشرةً بـ showRewarded، مع إعادة استخدام self بوصفه رد النداء لخطوة العرض:
private class RewardedAdCallbackAdapter: RewardedAdCallbacks {
private let placeholder: String
private let onUserEarnedReward: () -> Void
private let onFailed: (String) -> Void
init(placeholder: String, onUserEarnedReward: @escaping () -> Void, onFailed: @escaping (String) -> Void) {
self.placeholder = placeholder
self.onUserEarnedReward = onUserEarnedReward
self.onFailed = onFailed
super.init()
}
override func onRewardedLoaded() {
guard let vc = UIApplication.topViewController() else {
onFailed("No active view controller found")
return
}
AppsKitSDKAdsManagerIOS.instance.showRewarded(from: vc, placeholder: placeholder, callback: self)
}
override func onAdRewarded() { onUserEarnedReward() }
override func onRewardedCompleted() { onUserEarnedReward() }
override func onAdRewardedAdDismissed() {}
override func onRewardedAdLoadFailure() { onFailed("Failed to load rewarded ad") }
override func onRewardedFailedToShow() { onFailed("Failed to show rewarded ad") }
}يوفّر AKS أيضًا
loadAndShowRewarded(from:placeholder:callback:)علىAppsKitSDKAdsManagerIOSلتنفيذ التحميل والعرض باستدعاء واحد، ويتلقىRewardedLoadAndShowCallback— وهو بروتوكول لا يضم سوىonRewardedAdSuccess()/onRewardedAdFailed()(لا حاجة إلىsuper.init()لأنه بروتوكول وليس صنفًا مجرّدًا). استخدم الاستدعاءين المنفصلينloadRewarded/showRewardedأعلاه عندما تحتاج إلى التحميل مسبقًا والعرض لاحقًا؛ واستخدمloadAndShowRewardedعندما تعرض الإعلان دائمًا بعد تحميله مباشرةً.
إعلانات فتح التطبيق
AppsKitSDKAdsManagerIOS.instance.loadAppOpen(placeholder: placeholder, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showAppOpen(from: viewController, placeholder: placeholder, callback: adapter)يرث adapter من AppOpenAdCallbacks:
private class AppOpenCallbackAdapter: AppOpenAdCallbacks {
private let onAdLoaded: () -> Void
private let onAdFailed: () -> Void
init(onAdLoaded: @escaping () -> Void, onAdFailed: @escaping () -> Void) {
self.onAdLoaded = onAdLoaded
self.onAdFailed = onAdFailed
super.init()
}
override func onLoaded() { onAdLoaded() }
override func onFailedToLoad() { onAdFailed() }
override func onAdShown() {}
override func onDismiss() {}
override func onAdFailToShow() {}
}هذا هو المسار اليدوي لإعلانات فتح التطبيق — للاستفادة من المعالجة التلقائية التي يوفّرها AKS على مستوى التطبيق وتتحكم فيها الإعدادات عن بُعد، استخدم بدلًا منه التدفق المدمج في
AKSBaseAppDelegate(§4.6).
إعلانات البانر
AppsKitSDKAdsManagerIOS.instance.loadBanner(from: viewController, placeholder: placeholder, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showBanner(from: viewController, placeholder: placeholder, container: bannerContainerView, callback: adapter)يرث adapter من BannerCallback — راجع التعريف الكامل لـ BannerCallbackAdapter في §5.1 أعلاه، والذي يربط onBannerLoaded() مباشرةً بـ showBanner.
BannerSizes: BANNER (320×50)، LARGE_BANNER (320×100)، MEDIUM_RECTANGLE (300×250)، FULL_BANNER (468×60).
الإعلانات المدمجة مع المحتوى
AppsKitSDKAdsManagerIOS.instance.loadNative(from: viewController, placeholder: placeholder, isShowInScrollView: true, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showNative(
from: viewController, container: nativeContainerView, placeholder: placeholder,
res: nil, isShowInScrollView: true, callback: adapter
)يرث adapter من NativeCallback ويربط onNativeLoaded() مباشرةً بـ showNative، باتّباع النمط نفسه المستخدم في BannerCallbackAdapter:
private class NativeCallbackAdapter: NativeCallback {
private weak var container: UIView?
private let placeholder: String
private let onAdLoaded: () -> Void
private let onAdFailed: (String) -> Void
init(container: UIView, placeholder: String, onAdLoaded: @escaping () -> Void, onAdFailed: @escaping (String) -> Void) {
self.container = container
self.placeholder = placeholder
self.onAdLoaded = onAdLoaded
self.onAdFailed = onAdFailed
super.init()
}
override func onNativeLoaded() {
onAdLoaded()
guard let vc = UIApplication.topViewController(), let view = container else {
onAdFailed("No active view controller found")
return
}
AppsKitSDKAdsManagerIOS.instance.showNative(
from: vc, container: view, placeholder: placeholder,
res: nil, isShowInScrollView: true, callback: self
)
}
override func onNativeFailedToLoad() { onAdFailed("") }
override func onNativeClicked() {}
override func onNativeShown() {}
}الترويج للميزات
يوفّر AppsKitSDKAdsManagerIOS واجهة مغلّفة للترويج للميزات، كما هو الحال مع التنسيقات الأخرى:
// Optional — exclude features the user already has unlocked from being promoted
AppsKitSDKAdsManagerIOS.instance.setFeaturesAvailable(availableFeatures: ["premium_theme", "no_ads"])
AppsKitSDKAdsManagerIOS.instance.showFeaturePromotion(
from: viewController,
placeholder: placeholder,
callback: adapter
)يتوافق adapter مع OnFeaturePromotionClicked — وهو بروتوكول وليس صنفًا مجرّدًا، لذا لا حاجة إلى super.init():
private class FeaturePromotionAdapter: NSObject, OnFeaturePromotionClicked {
private let onClicked: (String) -> Void
private let onFailed: (String) -> Void
init(onClicked: @escaping (String) -> Void, onFailed: @escaping (String) -> Void) {
self.onClicked = onClicked
self.onFailed = onFailed
}
func onFeaturePromotionClicked(targetScreen: String) { onClicked(targetScreen) }
func onFailToShowFeaturePromotion(errorMessage: String) { onFailed(errorMessage) }
}