5. استدعاء أشكال الإعلانات
يظل كل استدعاء يتلقى سلسلة نصية تمثل موضعًا إعلانيًا (placeholder) مُعدًّا في بوابة 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
)
// Show the native ad using the design you created for this placeholder in the
// AKS portal, instead of an XIB — see below.
AppsKitSDKAdsManagerIOS.instance.showTemplatedNative(
from: viewController, container: nativeContainerView, placeholder: placeholder,
isShowInScrollView: true, callback: adapter
)يُستخدم showTemplatedNative للمواضع الإعلانية التي جرى تصميم مظهر إعلانها المدمج مع المحتوى وتعيينه على بوابة AKS بدلًا من داخل تطبيقك — ولا يتضمن المعامل res إطلاقًا، لأنك لست من يزوّده بالتخطيط. يحدد AKS قالب البوابة المرتبط بهذا الموضع الإعلاني، ويجلبه (مع تخزينه مؤقتًا بعد أول جلب)، ثم يعرض الإعلان المدمج مع المحتوى باستخدامه عبر مسار التحميل والعرض نفسه الذي يستخدمه showNative. إذا لم يُعيَّن قالب للموضع الإعلاني، أو تعذر جلبه، يعود AKS إلى تصميمه الافتراضي المدمج للإعلانات المدمجة مع المحتوى بدلًا من إفشال الإعلان — لذا يمكن استدعاؤه بأمان دائمًا، حتى قبل إعداد قالب على البوابة.
يرث 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) }
}