You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI项目中接入Admob Native Ads原生广告?

SwiftUI接入AdMob原生广告实现方案

第一步:创建自定义原生广告渲染视图

首先继承GADNativeAdView实现自定义的广告渲染视图,可根据自身产品设计调整样式和控件组合:

import GoogleMobileAds

class CustomNativeAdView: GADNativeAdView {
    // 广告标题标签
    let headlineLabel: UILabel = {
        let label = UILabel()
        label.font = .systemFont(ofSize: 16, weight: .bold)
        label.numberOfLines = 1
        return label
    }()
    
    // 广告主体描述标签
    let bodyLabel: UILabel = {
        let label = UILabel()
        label.font = .systemFont(ofSize: 14)
        label.numberOfLines = 2
        return label
    }()
    
    // 广告图标
    let iconImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFit
        iv.clipsToBounds = true
        return iv
    }()
    
    // 行动号召按钮
    let callToActionButton: UIButton = {
        let btn = UIButton(type: .system)
        btn.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        btn.backgroundColor = .systemBlue
        btn.setTitleColor(.white, for: .normal)
        btn.layer.cornerRadius = 4
        return btn
    }()
    
    // 广告标识标签
    let advertiserLabel: UILabel = {
        let label = UILabel()
        label.font = .systemFont(ofSize: 12)
        label.textColor = .secondaryLabel
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupSubviews()
        bindViewProperties()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupSubviews() {
        backgroundColor = .systemBackground
        layer.cornerRadius = 8
        layer.borderWidth = 1
        layer.borderColor = UIColor.separator.cgColor
        
        let subviews = [headlineLabel, bodyLabel, iconImageView, callToActionButton, advertiserLabel]
        subviews.forEach {
            $0.translatesAutoresizingMaskIntoConstraints = false
            addSubview($0)
        }
        
        NSLayoutConstraint.activate([
            iconImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
            iconImageView.topAnchor.constraint(equalTo: topAnchor, constant: 12),
            iconImageView.widthAnchor.constraint(equalToConstant: 40),
            iconImageView.heightAnchor.constraint(equalToConstant: 40),
            
            headlineLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, constant: 12),
            headlineLabel.topAnchor.constraint(equalTo: topAnchor, constant: 12),
            headlineLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
            
            advertiserLabel.leadingAnchor.constraint(equalTo: headlineLabel.leadingAnchor),
            advertiserLabel.topAnchor.constraint(equalTo: headlineLabel.bottomAnchor, constant: 4),
            
            bodyLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
            bodyLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 12),
            bodyLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
            
            callToActionButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
            callToActionButton.topAnchor.constraint(equalTo: bodyLabel.bottomAnchor, constant: 12),
            callToActionButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
            callToActionButton.heightAnchor.constraint(equalToConstant: 40),
            callToActionButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12)
        ])
    }
    
    private func bindViewProperties() {
        // 把自定义控件和GADNativeAdView的对应属性绑定
        self.headlineView = headlineLabel
        self.bodyView = bodyLabel
        self.iconView = iconImageView
        self.callToActionView = callToActionButton
        self.advertiserView = advertiserLabel
    }
    
    // 渲染广告数据
    func renderAd(_ nativeAd: GADNativeAd) {
        self.nativeAd = nativeAd
        headlineLabel.text = nativeAd.headline
        bodyLabel.text = nativeAd.body
        callToActionButton.setTitle(nativeAd.callToAction, for: .normal)
        advertiserLabel.text = nativeAd.advertiser ?? "广告"
        iconImageView.image = nativeAd.icon?.image
    }
}

第二步:封装SwiftUI可用的原生广告组件

通过UIViewControllerRepresentable封装广告加载和渲染逻辑:

struct GADNativeAdView: UIViewControllerRepresentable {
    // 测试用原生广告ID,生产环境替换为自己的ID
    private let adUnitID = "ca-app-pub-3940256099942544/3986624511"
    @State private var nativeAd: GADNativeAd?
    
    func makeUIViewController(context: Context) -> UIViewController {
        let viewController = UIViewController()
        let adLoader = GADAdLoader(
            adUnitID: adUnitID,
            rootViewController: viewController,
            adTypes: [.native],
            options: nil
        )
        adLoader.delegate = context.coordinator
        adLoader.load(GADRequest())
        
        return viewController
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        // 广告加载完成后添加到视图
        uiViewController.view.subviews.forEach { $0.removeFromSuperview() }
        guard let nativeAd = nativeAd else { return }
        
        let adView = CustomNativeAdView()
        adView.translatesAutoresizingMaskIntoConstraints = false
        adView.renderAd(nativeAd)
        uiViewController.view.addSubview(adView)
        
        NSLayoutConstraint.activate([
            adView.leadingAnchor.constraint(equalTo: uiViewController.view.leadingAnchor),
            adView.trailingAnchor.constraint(equalTo: uiViewController.view.trailingAnchor),
            adView.topAnchor.constraint(equalTo: uiViewController.view.topAnchor),
            adView.bottomAnchor.constraint(equalTo: uiViewController.view.bottomAnchor)
        ])
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, GADNativeAdLoaderDelegate {
        let parent: GADNativeAdView
        
        init(_ parent: GADNativeAdView) {
            self.parent = parent
        }
        
        func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
            parent.nativeAd = nativeAd
        }
        
        func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) {
            print("原生广告加载失败: \(error.localizedDescription)")
        }
    }
}

第三步:在SwiftUI视图中调用

struct ContentView: View {
    var body: some View {
        VStack(spacing: 20) {
            Text("其他业务内容区域")
                .font(.title)
            
            Spacer()
            
            // 原生广告组件,高度自适应内容,也可手动指定固定高度
            GADNativeAdView()
                .padding(.horizontal, 16)
            
            Spacer()
        }
    }
}

注意事项

  • 原生广告的样式可根据App设计调整CustomNativeAdView的控件布局和样式,只要保持和GADNativeAdView的属性绑定即可
  • 测试阶段必须使用官方提供的测试广告ID,不要用正式ID请求广告,避免被判定为违规
  • 生产环境替换adUnitID为自己在AdMob后台创建的原生广告单元ID
  • 多广告位场景可将adUnitID作为GADNativeAdView的初始化参数传入,实现组件复用
  • 可根据需求添加媒体视图、星级视图等其他原生广告元素,绑定对应的GADNativeAdView属性即可

内容的提问来源于stack exchange,提问作者drago

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:27:04