如何在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
相关产品推荐
相关产品推荐

