В SwiftUI отображение межстраничного объявления AdMob нарушает объекты NavigationLink – что я делаю не так?
У меня есть простое приложение с домашним представлением, представлением контента и представлением настроек. Я пытаюсь показать межстраничное объявление AdMob при переходе из главного представления в представление контента. Навигация между представлениями осуществляется с помощью комбинации NavigationStack и Navigation Links. Все работает нормально, когда я не показываю рекламу. Когда я показываю объявление, все навигационные ссылки перестают отвечать.
использование SwiftUI 5.0 на iOS 17.0 в XCode 15
Ожидаемый поток: ГЛАВНАЯ >> ОБЪЯВЛЕНИЕ >> СОДЕРЖИМОЕ >> НАСТРОЙКИ При показе объявления ГЛАВНАЯ >> ОБЪЯВЛЕНИЕ >> СОДЕРЖИМОЕ >> нет ответа (кнопка «Назад» работает, ссылка «СОДЕРЖАНИЕ» не работает)
Исходный код приведен ниже (чтобы попробовать, вам придется установить библиотеку GoogleMobileAds и добавить необходимые поля plist). Чтобы воспроизвести, запустите это приложение (подождите секунду, пока загрузится реклама) и нажмите ссылку «К контенту». Должно появиться тестовое объявление. Когда вы отклоните его, вы увидите представление содержимого. Нажмите «В настройки», и ссылка не работает. Нажмите «Назад», и ссылка «К содержимому» больше не работает.
Схема приложения: ГЛАВНАЯ >> CONTENTVIEW (с рекламой) >> SETTINGSVIEW.
[ОБНОВЛЕНО С УПРОЩЕННЫМ КОДОМ]
Код приложения:
import SwiftUI
import GoogleMobileAds
@main
struct AdsTestApp: App {
let adManager = InterstitialAdsManager.shared
init(){
initMobileAds()
}
var body: some Scene {
WindowGroup {
HomeView()
}
}
func initMobileAds() {
GADMobileAds.sharedInstance().start(completionHandler: nil)
GADMobileAds.sharedInstance().disableSDKCrashReporting()
InterstitialAdsManager.shared.loadInterstitialAd()
}
}
ГлавнаяПросмотреть код
import SwiftUI
struct HomeView: View {
@State var showAd: Bool = true
var body: some View {
NavigationStack{
VStack {
NavigationLink(destination: ContentView(showAd: $showAd)){
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("To Content")
}
}
.padding()
}
}
}
#Preview {
HomeView()
}
Код представления содержимого
import SwiftUI
struct ContentView: View {
@Binding var showAd: Bool
let adsManager = InterstitialAdsManager.shared
var body: some View {
ZStack() {
NavigationLink {
SettingsView()
} label: {
Label("To Settings", systemImage: "slider.horizontal.3")
.font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
.frame(maxWidth: .infinity, maxHeight: .infinity )
}
}
.background(.yellow)
.onAppear(){
if(showAd){
adsManager.displayInterstitialAd()
}
showAd.toggle()
}
}
}
НастройкиПросмотреть код
import SwiftUI
struct SettingsView: View {
var body: some View {
VStack() {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
.font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
.frame(maxWidth: .infinity, maxHeight: .infinity )
.padding(.all)
}
.background(.green)
}
}
#Preview {
SettingsView()
}
Код межстраничного AdManager
import Foundation
import GoogleMobileAds
class InterstitialAdsManager: NSObject, GADFullScreenContentDelegate, ObservableObject {
// Properties
@Published var interstitialAdLoaded:Bool = false
var interstitialAd:GADInterstitialAd?
static let shared = InterstitialAdsManager()
override init() {
super.init()
}
func loadInterstitialAd(){
GADInterstitialAd.load(withAdUnitID: "ca-app-pub-3940256099942544/4411468910", request: GADRequest()) { [weak self] add, error in
guard let self = self else {return}
if let error = error{
print(": \(error.localizedDescription)")
self.interstitialAdLoaded = false
return
}
#if DEBUG
print(": Ad Loading succeeded")
#endif
self.interstitialAdLoaded = true
self.interstitialAd = add
self.interstitialAd?.fullScreenContentDelegate = self
}
}
func displayInterstitialAd(){
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
guard let root = window?.rootViewController else {
return
}
if let ad = interstitialAd{
ad.present(fromRootViewController: root)
self.interstitialAdLoaded = false
}else{
print(": Ad not ready")
self.interstitialAdLoaded = false
self.loadInterstitialAd()
}
}
// Failure notification
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
#if DEBUG
print(": Failed to display interstitial ad: \(error.localizedDescription)")
#endif
self.loadInterstitialAd()
}
// Indicate notification
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
#if DEBUG
print(": Displayed an interstitial ad")
#endif
self.interstitialAdLoaded = false
}
// Close notification
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
#if DEBUG
print(": Interstitial ad closed")
#endif
self.loadInterstitialAd()
}
}