微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI中的Admob原生广告

如何解决SwiftUI中的Admob原生广告

让Admob原生广告与SwiftUI配合使用并不是一件好事。我尝试使用此处找到的代码https://github.com/googleads/googleads-mobile-ios-examples/blob/master/Swift/admob/NativeAdvancedExample/NativeAdvancedExample/ViewController.swift 这是我最终得到的确切代码,因为该链接中的许多代码无法正常工作。

import GoogleMobileAds
import UIKit

class ViewController: UIViewController {
    
    /// The view that holds the native ad.
    @IBOutlet var nativeAdplaceholder: UIView!
    
    /// The height constraint applied to the ad view,where necessary.
    var heightConstraint: NSLayoutConstraint?
    
    /// The ad loader. You must keep a strong reference to the GADAdLoader during the ad loading
    /// process.
    var adLoader: GADAdLoader!
    
    /// The native ad view that is being presented.
    var nativeAdView: GADUnifiednativeAdView!
    
    /// The ad unit ID.
    let adUnitID = "ca-app-pub-3940256099942544/3986624511"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        guard
            let nibObjects = Bundle.main.loadNibNamed("UnifiednativeAdView",owner: nil,options: nil),let adView = nibObjects.first as? GADUnifiednativeAdView
            else {
                assert(false,"Could not load nib file for adView")
        }
        setAdView(adView)
        refreshAd(nil)
    }
    
    func setAdView(_ adView: GADUnifiednativeAdView) {
        // Remove the prevIoUs ad view.
        nativeAdView = adView
        nativeAdplaceholder = UIView()
        nativeAdplaceholder.addSubview(nativeAdView)
        nativeAdView.translatesAutoresizingMaskIntoConstraints = false
        
        // Layout constraints for positioning the native ad view to stretch the entire width and height
        // of the nativeAdplaceholder.
        let viewDictionary = ["_nativeAdView": nativeAdView!]
        nativeAdplaceholder.addConstraints(
          NSLayoutConstraint.constraints(
            withVisualFormat: "H:|[_nativeAdView]|",options: NSLayoutConstraint.FormatOptions(rawValue: 0),metrics: nil,views: viewDictionary)
        )
        nativeAdplaceholder.addConstraints(
          NSLayoutConstraint.constraints(
            withVisualFormat: "V:|[_nativeAdView]|",views: viewDictionary)
        )
        
    }
    
    // MARK: - Actions
    
    /// Refreshes the native ad.
    @IBAction func refreshAd(_ sender: AnyObject!) {
        adLoader = GADAdLoader(
            adUnitID: adUnitID,rootViewController: self,adTypes: [.unifiednative],options: nil)
        adLoader.delegate = self
        adLoader.load(GADRequest())
    }
    
}


extension ViewController: GADUnifiednativeAdLoaderDelegate {
    func adLoader(_ adLoader: GADAdLoader,didFailToReceiveAdWithError error: GADRequestError) {
        print("fail")
    }
    
    
    func adLoader(_ adLoader: GADAdLoader,didReceive nativeAd: GADUnifiednativeAd) {
        
        // Set ourselves as the native ad delegate to be notified of native ad events.
        nativeAd.delegate = self
        
        // Deactivate the height constraint that was set when the prevIoUs video ad loaded.
        heightConstraint?.isActive = false
        
        // Populate the native ad view with the native ad assets.
        // The headline and mediaContent are guaranteed to be present in every native ad.
        (nativeAdView.headlineView as? UILabel)?.text = nativeAd.headline
        nativeAdView.mediaView?.mediaContent = nativeAd.mediaContent
        
        
        // This app uses a fixed width for the GADMediaView and changes its height to match the aspect
        // ratio of the media it displays.
        if let mediaView = nativeAdView.mediaView,nativeAd.mediaContent.aspectRatio > 0 {
            heightConstraint = NSLayoutConstraint(
                item: mediaView,attribute: .height,relatedBy: .equal,toItem: mediaView,attribute: .width,multiplier: CGFloat(1 / nativeAd.mediaContent.aspectRatio),constant: 0)
            heightConstraint?.isActive = true
        }
        
        // These assets are not guaranteed to be present. Check that they are before
        // showing or hiding them.
        (nativeAdView.bodyView as? UILabel)?.text = nativeAd.body
        nativeAdView.bodyView?.isHidden = nativeAd.body == nil
        
        (nativeAdView.callToActionView as? UIButton)?.setTitle(nativeAd.callToAction,for: .normal)
        nativeAdView.callToActionView?.isHidden = nativeAd.callToAction == nil
        
        (nativeAdView.iconView as? UIImageView)?.image = nativeAd.icon?.image
        nativeAdView.iconView?.isHidden = nativeAd.icon == nil
        
        nativeAdView.starratingView?.isHidden = true
        
        (nativeAdView.storeView as? UILabel)?.text = nativeAd.store
        nativeAdView.storeView?.isHidden = nativeAd.store == nil
        
        (nativeAdView.priceView as? UILabel)?.text = nativeAd.price
        nativeAdView.priceView?.isHidden = nativeAd.price == nil
        
        (nativeAdView.advertiserView as? UILabel)?.text = nativeAd.advertiser
        nativeAdView.advertiserView?.isHidden = nativeAd.advertiser == nil
        
        // In order for the SDK to process touch events properly,user interaction should be disabled.
        nativeAdView.callToActionView?.isUserInteractionEnabled = false
        
        // Associate the native ad view with the native ad object. This is
        // required to make the ad clickable.
        // Note: this should always be done after populating the ad views.
        nativeAdView.nativeAd = nativeAd
        
    }
}

// MARK: - GADUnifiednativeAdDelegate implementation
extension ViewController: GADUnifiednativeAdDelegate {
    
    func nativeAdDidRecordClick(_ nativeAd: GADUnifiednativeAd) {
        print("\(#function) called")
    }
    
    func nativeAdDidRecordImpression(_ nativeAd: GADUnifiednativeAd) {
        print("\(#function) called")
    }
    
    func nativeAdWillPresentScreen(_ nativeAd: GADUnifiednativeAd) {
        print("\(#function) called")
    }
    
    func nativeAdWilldismissScreen(_ nativeAd: GADUnifiednativeAd) {
        print("\(#function) called")
    }
    
    func nativeAdDiddismissScreen(_ nativeAd: GADUnifiednativeAd) {
        print("\(#function) called")
    }
    
    func nativeAdWillLeaveApplication(_ nativeAd: GADUnifiednativeAd) {
        print("\(#function) called")
    }
}

我做了这个结构。

import SwiftUI
import UIKit

struct NativeViewController: UIViewControllerRepresentable {

func makeUIViewController(context: Context) -> UIViewController {
    let picker = ViewController()
    return picker
}

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

}

但是当我像这样在身体中放置NativeViewController时

var body: some View {
    NativeViewController()
}

我没有错误,但也没有显示广告。

任何方向将不胜感激。

解决方法

您可以尝试将广告视图(例如GADBannerView)包装在UIViewControllerRepresentable中:

import GoogleMobileAds
import SwiftUI
import UIKit

final private class BannerVC: UIViewControllerRepresentable  {

    func makeUIViewController(context: Context) -> UIViewController {
        let view = GADBannerView(adSize: kGADAdSizeBanner)

        let viewController = UIViewController()
        view.adUnitID = bannerID
        view.rootViewController = viewController
        viewController.view.addSubview(view)
        viewController.view.frame = CGRect(origin: .zero,size: kGADAdSizeBanner.size)
        view.load(GADRequest())

        return viewController
    }

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

struct Banner: View {
    var body: some View{
        BannerVC()
            .frame(width: 320,height: 50,alignment: .center)
    }
}

您可以在此处找到更多说明:

,

答案是使用self.view而不是占位符代码

    // Remove the previous ad view.
    nativeAdView = adView
    self.view.addSubview(nativeAdView)
    nativeAdView.translatesAutoresizingMaskIntoConstraints = false
    
    // Layout constraints for positioning the native ad view to stretch the entire width and height
    // of the nativeAdPlaceholder.
    let viewDictionary = ["_nativeAdView": nativeAdView!]
    self.view.addConstraints(
      NSLayoutConstraint.constraints(
        withVisualFormat: "H:|[_nativeAdView]|",options: NSLayoutConstraint.FormatOptions(rawValue: 0),metrics: nil,views: viewDictionary)
    )
    self.view.addConstraints(
      NSLayoutConstraint.constraints(
        withVisualFormat: "V:|[_nativeAdView]|",views: viewDictionary)
    )
,

最好的方法是创建一个委托类,其实例位于将显示 AD 的视图中。

创建委托(此处使用虚拟测试广告):

let interstitialID:String = "/6499/example/interstitial"

final class InterstitialDelegate: NSObject,GADInterstitialDelegate {
    
    var interstitial: DFPInterstitial!
    
    override init() {
        super.init()
        interstitial = createAndLoadInterstitial()
    }
    
    func createAndLoadInterstitial() -> DFPInterstitial {
        interstitial = DFPInterstitial(adUnitID: interstitialID)
        interstitial.delegate = self
        interstitial.load(DFPRequest())
        return interstitial
    }
    
    func showAd() {
        print("Request to show AD")
        if self.interstitial.isReady {
            let root = UIApplication.shared.windows.first?.rootViewController
            self.interstitial.present(fromRootViewController: root!)
            print("AD presented")
        } else {
            print("AD not ready")
        }
    }
    
    private func interstitialDidDismissScreen(_ ad: DFPInterstitial) {
        interstitial = createAndLoadInterstitial()
    }
}

然后在应显示广告的视图中创建上述委托的实例:

struct MainView: View {
        
    var interstitial : InterstitialDelegate

    init() {
        interstitial = InterstitialDelegate()
    }

}

然后在这个视图中通过调用请求一个广告

interstitial.showAd() 

例如在用户听完音乐之后。

致谢:https://medium.com/@michaelbarneyjr/how-to-integrate-admob-ads-in-swiftui-fbfd3d774c50 在上面@pawello2222 的回答中也提到了他,然后我用来自 Google's Mobile Ads SDK 的信息更新了它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。