Flutter_native_admob admob ios adk 8.0

SDK 8.0有大量的api修改,Flutter_native_admob会报错。

修改两个文件:

NatvieAdmobController.swift

//

// NativeAdmobController.swift

// flutter_native_admob

//

// Created by Dao Duy Duong on 3/14/20.

//

import GoogleMobileAds

class NativeAdmobController: NSObject {

enum CallMethod: String {

case setAdUnitID

case reloadAd

case setNonPersonalizedAds

}

enum LoadState: String {

case loading, loadError, loadCompleted

}

let id: String

let channel: FlutterMethodChannel

var nativeAdChanged: ((GADNativeAd?) -> Void)?

var nativeAd: GADNativeAd? {

didSet { invokeLoadCompleted() }

}

private var adLoader: GADAdLoader?

private var adUnitID: String?

private var nonPersonalizedAds: Bool = false

init(id: String, channel: FlutterMethodChannel) {

self.id = id

self.channel = channel

super.init()

channel.setMethodCallHandler(handle)

}

private func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {

guard let callMethod = CallMethod(rawValue: call.method) else { return result(FlutterMethodNotImplemented) }

let params = call.arguments as? [String: Any]

switch callMethod {

case .setAdUnitID:

guard let adUnitID = params?[“adUnitID”] as? String else {

return result(nil)

}

let isChanged = adUnitID != self.adUnitID

self.adUnitID = adUnitID

if adLoader == nil || isChanged {

let numberAds: Int = params?[“numberAds”] as? Int ?? 1

let multipleAdsOptions = GADMultipleAdsAdLoaderOptions()

if numberAds != nil && numberAds > 1 {

multipleAdsOptions.numberOfAds = numberAds

}

adLoader = GADAdLoader(

adUnitID: adUnitID,

rootViewController: nil,

adTypes: [.native],

options: [multipleAdsOptions]

)

adLoader?.delegate = self

}

if nativeAd == nil || isChanged {

loadAd()

} else {

invokeLoadCompleted()

}

case .reloadAd:

let forceRefresh = params?[“forceRefresh”] as? Bool ?? false

if forceRefresh || nativeAd == nil {

loadAd()

} else {

invokeLoadCompleted()

}

case .setNonPersonalizedAds:

if let nonPersonalizedAds = params?[“nonPersonalizedAds”] as? Bool {

self.nonPersonalizedAds = nonPersonalizedAds

}

return result(nil)

}

result(nil)

}

private func loadAd() {

channel.invokeMethod(LoadState.loading.rawValue, arguments: nil)

let request = GADRequest()

if self.nonPersonalizedAds {

let extras = GADExtras()

extras.additionalParameters = [“npa”: “1”]

request.register(extras)

}

adLoader?.load(request)

}

private func invokeLoadCompleted() {

nativeAdChanged?(nativeAd)

channel.invokeMethod(LoadState.loadCompleted.rawValue, arguments: nil)

}

}

extension NativeAdmobController: GADNativeAdLoaderDelegate {

func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) {

print(“NativeAdmob: failed to load with error: \(error.localizedDescription)”)

channel.invokeMethod(LoadState.loadError.rawValue, arguments: nil)

}

func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {

self.nativeAd = nativeAd

}

}

class NativeAdmobControllerManager {

static let shared = NativeAdmobControllerManager()

private var controllers: [NativeAdmobController] = []

private init() {}

func createController(forID id: String, binaryMessenger: FlutterBinaryMessenger) {

if getController(forID: id) == nil {

let methodChannel = FlutterMethodChannel(name: id, binaryMessenger: binaryMessenger)

let controller = NativeAdmobController(id: id, channel: methodChannel)

controllers.append(controller)

}

}

func getController(forID id: String) -> NativeAdmobController? {

return controllers.first(where: { $0.id == id })

}

func removeController(forID id: String) {

if let index = controllers.firstIndex(where: { $0.id == id }) {

controllers.remove(at: index)

}

}

}

NativeAdview.swift

//

// NativeAdView.swift

// flutter_native_admob

//

// Created by Dao Duy Duong on 3/8/20.

//

import UIKit

import GoogleMobileAds

enum NativeAdmobType: String {

case banner, full

}

class NativeAdView: GADNativeAdView {

let adLabelLbl: UILabel = {

let label = UILabel()

label.font = UIFont.systemFont(ofSize: 12)

label.textColor = .white

label.text = “Ad”

label.numberOfLines = 1

return label

}()

lazy var adLabelView: UIView = {

let view = UIView()

view.backgroundColor = .fromHex(“FFCC66”)

view.layer.cornerRadius = 3

view.clipsToBounds = true

view.addSubview(adLabelLbl)

adLabelLbl.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: 1, left: 3, bottom: 1, right: 3))

return view

}()

let adMediaView = GADMediaView()

let adIconView: UIImageView = {

let imageView = UIImageView()

imageView.autoSetDimensions(to: CGSize(width: 40, height: 40))

return imageView

}()

let adHeadLineLbl: UILabel = {

let label = UILabel()

label.font = UIFont.boldSystemFont(ofSize: 16)

label.numberOfLines = 1

return label

}()

let adAdvertiserLbl: UILabel = {

let label = UILabel()

label.font = UIFont.systemFont(ofSize: 14)

label.numberOfLines = 1

return label

}()

let adRatingView = StackLayout().spacing(2)

let adBodyLbl: UILabel = {

let label = UILabel()

label.font = UIFont.systemFont(ofSize: 12)

label.numberOfLines = 2

return label

}()

let adPriceLbl: UILabel = {

let label = UILabel()

label.font = UIFont.systemFont(ofSize: 12)

label.numberOfLines = 1

label.textAlignment = .right

return label

}()

let adStoreLbl: UILabel = {

let label = UILabel()

label.font = UIFont.systemFont(ofSize: 12)

label.numberOfLines = 1

label.textAlignment = .right

return label

}()

let callToActionBtn: UIButton = {

let button = UIButton()

button.setBackgroundImage(.from(color: .fromHex(“#4CBE99”)), for: .normal)

button.setTitleColor(.white, for: .normal)

button.titleLabel?.font = UIFont.systemFont(ofSize: 15)

button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)

button.autoSetDimension(.height, toSize: 30)

return button

}()

var starIcon: StarIcon {

let icon = StarIcon()

icon.autoSetDimensions(to: CGSize(width: 15, height: 15))

return icon

}

var options = NativeAdmobOptions() {

didSet { updateOptions() }

}

let type: NativeAdmobType

init(frame: CGRect, type: NativeAdmobType) {

self.type = type

super.init(frame: frame)

setupView()

}

required init?(coder: NSCoder) {

fatalError(“No support for interface builder”)

}

func setNativeAd(_ nativeAd: GADNativeAd?) {

guard let nativeAd = nativeAd else { return }

self.nativeAd = nativeAd

// Set the mediaContent on the GADMediaView to populate it with available

// video/image asset.

adMediaView.mediaContent = nativeAd.mediaContent

// Populate the native ad view with the native ad assets.

// The headline is guaranteed to be present in every native ad.

adHeadLineLbl.text = nativeAd.headline

adAdvertiserLbl.text = nativeAd.advertiser

if nativeAd.advertiser.isNilOrEmpty {

adAdvertiserLbl.isHidden = true

}

// These assets are not guaranteed to be present. Check that they are before

// showing or hiding them.

adBodyLbl.text = nativeAd.body

if nativeAd.body.isNilOrEmpty {

adBodyLbl.isHidden = true

}

callToActionBtn.setTitle(nativeAd.callToAction, for: .normal)

if nativeAd.callToAction.isNilOrEmpty {

callToActionBtn.isHidden = true

}

adIconView.image = nativeAd.icon?.image

adIconView.isHidden = nativeAd.icon == nil

adRatingView.arrangedSubviews.forEach { view in

view.removeFromSuperview()

}

let numOfStars = Int(truncating: nativeAd.starRating ?? 0)

adRatingView.children(Array(0..<numOfStars).map { _ in

let icon = self.starIcon

icon.color = options.ratingColor

return icon

})

adRatingView.isHidden = nativeAd.starRating == nil

adStoreLbl.text = nativeAd.store

if nativeAd.store.isNilOrEmpty {

adStoreLbl.isHidden = true

}

adPriceLbl.text = nativeAd.price

if nativeAd.price.isNilOrEmpty {

adPriceLbl.isHidden = true

}

layoutIfNeeded()

}

}

private extension NativeAdView {

func setupView() {

self.mediaView = adMediaView

self.headlineView = adHeadLineLbl

self.callToActionView = callToActionBtn

self.iconView = adIconView

self.bodyView = adBodyLbl

self.storeView = adStoreLbl

self.priceView = adPriceLbl

self.starRatingView = adRatingView

self.advertiserView = adAdvertiserLbl

switch type {

case .full: setupFullLayout()

case .banner: setupBannerLayout()

}

}

func setupFullLayout() {

adBodyLbl.numberOfLines = 2

let infoLayout = StackLayout().spacing(5).children([

adIconView,

StackLayout().direction(.vertical).children([

adHeadLineLbl,

StackLayout().children([

adAdvertiserLbl,

adRatingView,

UIView()

]),

]),

])

callToActionBtn.setContentHuggingPriority(.defaultHigh, for: .horizontal)

let actionLayout = StackLayout()

.spacing(5)

.children([

UIView(),

adPriceLbl,

adStoreLbl,

callToActionBtn

])

adBodyLbl.autoSetDimension(.height, toSize: 20, relation: .greaterThanOrEqual)

adLabelLbl.autoSetDimension(.height, toSize: 15, relation: .greaterThanOrEqual)

addSubview(adLabelView)

adLabelView.autoPinEdge(toSuperviewEdge: .top)

adLabelView.autoPinEdge(toSuperviewEdge: .leading)

let contentView = UIView()

addSubview(contentView)

contentView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top)

contentView.autoPinEdge(.top, to: .bottom, of: adLabelView, withOffset: 5)

let layout = StackLayout()

.direction(.vertical)

.spacing(5)

.children([

adMediaView,

infoLayout,

adBodyLbl,

actionLayout

])

layout.isUserInteractionEnabled = false

contentView.addSubview(layout)

layout.autoAlignAxis(toSuperviewAxis: .horizontal)

layout.autoPinEdge(toSuperviewEdge: .leading)

layout.autoPinEdge(toSuperviewEdge: .trailing)

layout.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual)

layout.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0, relation: .greaterThanOrEqual)

}

func setupBannerLayout() {

adBodyLbl.numberOfLines = 2

callToActionBtn.setContentHuggingPriority(.defaultHigh, for: .horizontal)

adLabelLbl.autoSetDimension(.height, toSize: 15, relation: .greaterThanOrEqual)

addSubview(adLabelView)

adLabelView.autoPinEdge(toSuperviewEdge: .top)

adLabelView.autoPinEdge(toSuperviewEdge: .leading)

let contentView = UIView()

addSubview(contentView)

contentView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top)

contentView.autoPinEdge(.top, to: .bottom, of: adLabelView, withOffset: 5)

let layout = StackLayout().spacing(5).children([

adIconView,

StackLayout().direction(.vertical).children([

adHeadLineLbl,

adBodyLbl,

StackLayout().children([

adAdvertiserLbl,

adRatingView,

UIView()

]),

]),

callToActionBtn

])

layout.isUserInteractionEnabled = false

contentView.addSubview(layout)

layout.autoAlignAxis(toSuperviewAxis: .horizontal)

layout.autoPinEdge(toSuperviewEdge: .leading)

layout.autoPinEdge(toSuperviewEdge: .trailing)

layout.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual)

layout.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0, relation: .greaterThanOrEqual)

}

func updateOptions() {

adMediaView.isHidden = !options.showMediaContent

adLabelLbl.textColor = options.adLabelTextStyle.color

adLabelLbl.font = UIFont.systemFont(ofSize: options.adLabelTextStyle.fontSize)

adLabelView.backgroundColor = options.adLabelTextStyle.backgroundColor ?? .fromHex(“FFCC66”)

adLabelView.isHidden = !options.adLabelTextStyle.isVisible

adHeadLineLbl.textColor = options.headlineTextStyle.color

adHeadLineLbl.font = UIFont.systemFont(ofSize: options.headlineTextStyle.fontSize)

adHeadLineLbl.isHidden = !options.headlineTextStyle.isVisible

adAdvertiserLbl.textColor = options.advertiserTextStyle.color

adAdvertiserLbl.font = UIFont.systemFont(ofSize: options.advertiserTextStyle.fontSize)

adAdvertiserLbl.isHidden = !options.advertiserTextStyle.isVisible

adBodyLbl.textColor = options.bodyTextStyle.color

adBodyLbl.font = UIFont.systemFont(ofSize: options.bodyTextStyle.fontSize)

adBodyLbl.isHidden = !options.bodyTextStyle.isVisible

adStoreLbl.textColor = options.storeTextStyle.color

adStoreLbl.font = UIFont.systemFont(ofSize: options.storeTextStyle.fontSize)

adStoreLbl.isHidden = !options.storeTextStyle.isVisible

adPriceLbl.textColor = options.priceTextStyle.color

adPriceLbl.font = UIFont.systemFont(ofSize: options.priceTextStyle.fontSize)

adPriceLbl.isHidden = !options.priceTextStyle.isVisible

callToActionBtn.setTitleColor(options.callToActionStyle.color, for: .normal)

callToActionBtn.titleLabel?.font = UIFont.systemFont(ofSize: options.callToActionStyle.fontSize)

if let bgColor = options.callToActionStyle.backgroundColor {

callToActionBtn.setBackgroundImage(.from(color: bgColor), for: .normal)

}

callToActionBtn.isHidden = !options.callToActionStyle.isVisible

starIcon.color = options.ratingColor

}

}