Как исправить размер адаптивного рекламного баннера в мультиплатформенной версии для iOS?IOS

Программируем под IOS
Ответить
Anonymous
 Как исправить размер адаптивного рекламного баннера в мультиплатформенной версии для iOS?

Сообщение Anonymous »

Пытаюсь интегрировать адаптивную рекламу для iOS в свой мультиплатформенный проект.
Я следил за этими материалами:
Парень из Medium: https://medium.com/@diegoturchi95/admob ... de75b2f67c
Официальный документ Google: https://developers.google.com/admob/ios/banner
В результате моя реализация выглядит так:
Swift-коды:
ComposeView

Код: Выделить всё

import UIKit
import SwiftUI
import ComposeApp
import GoogleMobileAds

struct ComposeView: UIViewControllerRepresentable {

//init() {
//   MainViewControllerKt.IOSBanner = { () -> UIViewController in
//let width = UIScreen.main.bounds.width
//let adSize = currentOrientationAnchoredAdaptiveBanner(width: width)
//let bannerView =  BannerAdView(adSize).frame(height: adSize.size.height)
//   let bannerView =  BannerAdView()
//     return UIHostingController(rootView: bannerView)
//  }
//}

init() {
MainViewControllerKt.IOSBanner = {
let width = UIScreen.main.bounds.width
// This is what your Kotlin code calls when it needs the banner
let adSize = currentOrientationAnchoredAdaptiveBanner(width: width)
//let bannerView =  BannerAdView(adSize).frame(height: adSize.size.height)
let bannerView = AdViewBanner()
.frame(height: adSize.size.height)
//.frame(height: 90) // Safe fallback - adaptive size will override

return UIHostingController(rootView: bannerView)
}
}

func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController()
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
}

struct ContentView: View {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some View {
ComposeView()
.ignoresSafeArea()
}
}
GoogleMobileAdsConsentManager:

Код: Выделить всё

import Foundation
import GoogleMobileAds
import UserMessagingPlatform

@MainActor
final class GoogleMobileAdsConsentManager: NSObject {
static let shared = GoogleMobileAdsConsentManager()
private var isMobileAdsStarted = false

var canRequestAds: Bool {
ConsentInformation.shared.canRequestAds
}

func gatherConsent(completion: @escaping (Error?) -> Void) async {
let params = RequestParameters()
let debugSettings = DebugSettings()
// debugSettings.geography = .EEA // Uncomment to test consent form
params.debugSettings = debugSettings

do {
try await ConsentInformation.shared.requestConsentInfoUpdate(with: params)
try await ConsentForm.loadAndPresentIfRequired(from: nil)
completion(nil)
} catch {
completion(error)
}
}

func startGoogleMobileAdsSDK() {
guard canRequestAds, !isMobileAdsStarted else { return }
isMobileAdsStarted = true
MobileAds.shared.start(completionHandler: nil)
}
}
Баннер AdMob:

Код: Выделить всё

//
//  AdMobBanner.swift
//  iosApp
//

import SwiftUI
import UIKit
import GoogleMobileAds
import ComposeApp  // Your generated KMP module

// MARK: - Adaptive BannerAdView (SwiftUI wrapper)
struct AdViewBanner: UIViewRepresentable {
private let adUnitID = "ca-app-pub-3940256099942544/2435281174" // Test ID - change in production

func makeUIView(context: Context) ->  BannerView {
let banner = BannerView()
banner.translatesAutoresizingMaskIntoConstraints = false
banner.adUnitID = adUnitID
banner.delegate = context.coordinator

// Required: set rootViewController so ads can present modals
banner.rootViewController = UIApplication.shared.topMostViewController()

// Use Google's recommended adaptive size
let width = UIScreen.main.bounds.width
let adaptiveSize = currentOrientationAnchoredAdaptiveBanner(width: width)
banner.adSize = adaptiveSize
banner.load(Request())

return banner
}

func updateUIView(_ uiView: BannerView, context: Context) {
// Handle rotation properly
let width = UIScreen.main.bounds.width
let newSize = currentOrientationAnchoredAdaptiveBanner(width: width)
if !isAdSizeEqualToSize(size1: uiView.adSize, size2: newSize) {
uiView.adSize = newSize
uiView.load(Request())
}
}

func makeCoordinator() -> Coordinator {
Coordinator()
}

class Coordinator: NSObject, BannerViewDelegate {
func bannerViewDidReceiveAd(_ bannerView: BannerView) {
print("Banner ad loaded successfully")
}

func bannerView(_ bannerView: BannerView, didFailToReceiveAdWithError error: Error) {
print("Banner ad failed: \(error.localizedDescription)")
}
}
}

// MARK: - UIApplication extension to get top VC
extension UIApplication {
func topMostViewController() -> UIViewController? {
let keyWindow = connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first(where: { $0.isKeyWindow })

var top = keyWindow?.rootViewController
while let presented = top?.presentedViewController {
top = presented
}
return top ?? UIViewController()
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
iOSApp

Код: Выделить всё

import SwiftUI

@main
struct iOSApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
AppDelegate

Код: Выделить всё

import SwiftUI
import Foundation
import GoogleMobileAds

class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
Task { @MainActor in
await GoogleMobileAdsConsentManager.shared.gatherConsent { error in
if let error = error {
print("Consent error: \(error.localizedDescription)")
}
GoogleMobileAdsConsentManager.shared.startGoogleMobileAdsSDK()
}
}
return true
}
}
Часть Kotlin:

Код: Выделить всё

lateinit var IOSBanner: () -> UIViewController

fun generateIOSBanner(): UIViewController {
return IOSBanner()
}

fun MainViewController(): UIViewController {

return ComposeUIViewController {
MainApp {
UIKitView(
modifier = Modifier,
factory = { generateIOSBanner().view }
)
}
}
}
MainApp выглядит так:

Код: Выделить всё

@Composable
fun MainApp(bannerContext: @Composable (String) -> Unit) {

Platform.initDataStore()

AppTheme(mainModel = mainModel) {

var route by rememberSaveableString()
val controller = rememberNavController { value -> route = value }
Column(
content = {
Box(modifier = Modifier.weight(weight = 1f)) {
MainGraph(controller = controller, mainModel = mainModel)
}

bannerContext.invoke(route)
},
modifier = Modifier.animContentSize().background(color = background())
)
}
}
}
У меня работает, но не так, как ожидалось. Оно выглядит увеличенным:
Изображение

Я также попробовал реализовать без функции адаптивного размера, в результате чего получилось полноэкранное объявление, а не баннер.
Я ожидаю, что оно будет выглядеть так, как на Android (androidMain):
Изображение

В чем проблема и как ее исправить?
Спасибо.

Подробнее здесь: https://stackoverflow.com/questions/798 ... rm-for-ios
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»