Thelouras
Thelouras

Reputation: 880

iOS Google Ads Slowing down app's performance

We have followed Google's example for Ads in a TableView:

https://github.com/googleads/googleads-mobile-ios-examples/blob/master/Swift/advanced/BannerTableViewExample/BannerTableViewExample/TableViewController.swift

To integrate google advertisements on an iOS project. When we use the demo ad unit id(/6499/example/banner) everything works fine.

However, when we switch to production ads our devices start to overheat and the app lags significantly.

The ads are displayed in a Collection View. We are caching the ads the same way with Google's example

class AdvertisementManager{
     static let TAG_A = 1
     static let TAG_B = 2
     static let TAG_C = 3
     static let TAG_D = 4
     static let TAG_E = 5
     static let TAG_F = 6
     // .............
}

struct GoogleAdvertisementMetadata {
    weak var delegate: GADBannerViewDelegate?
    weak var adSizeDelegate: GADAdSizeDelegate?
    weak var rootViewController: UIViewController?
    let validAdSizes: AdSizesOption
    let targetingMetadata: AdTargetingMetadata
}

private func preLoadAdvertisements() {
    let targetingVals = interactor?.getTargetingValues()
    let targetingMetadata = AdTargetingMetadata(targetingValues: targetingVals)
    let googleAdvertisementMetadata = GoogleAdvertisementMetadata(
    delegate: self,
    adSizeDelegate: self,
    rootViewController: attachedView,
    validAdSizes: advertisementSizes,
    targetingMetadata: targetingMetadata)
    googleMetadata = googleAdvertisementMetadata
    cachedAdvertisements.removeAll()
    cachedAdvertisements = 
    advertisementManager.createAdvertismentsForSections(googleAdvertisementMetadata)
}
func createAdvertismentsForSections(_ googleAdvertisementMetadata: GoogleAdvertisementMetadata) -> [String: GAMBannerView] {
      var cachedAdvertisements: [String: GAMBannerView] = [:]
      let adA = AdvertisementConstants.FeedAdvertisementSectionA
      let adB = AdvertisementConstants.FeedAdvertisementSectionB
      let adC = AdvertisementConstants.FeedAdvertisementSectionC
      let adD = AdvertisementConstants.FeedAdvertisementSectionD
      let adE = AdvertisementConstants.FeedAdvertisementSectionE
      cachedAdvertisements[adA + "\(tagA)"] = createAdvertisement(with: adA, tag: tagA, metadata: googleAdvertisementMetadata)
     cachedAdvertisements[adB + "\(tagB)"] = createAdvertisement(with: adB, tag: tagB, metadata: googleAdvertisementMetadata)
     cachedAdvertisements[adC + "\(tagC)"] = createAdvertisement(with: adC, tag: tagC, metadata: googleAdvertisementMetadata)
     cachedAdvertisements[adD + "\(tagD)"] = createAdvertisement(with: adD, tag: tagD, metadata: googleAdvertisementMetadata)
     cachedAdvertisements[adE + "\(tagE)"] = createAdvertisement(with: adE, tag: tagE, metadata: googleAdvertisementMetadata)
     return cachedAdvertisements
}

private func createAdvertisement(with adID: String, tag: Int, metadata: GoogleAdvertisementMetadata) -> GAMBannerView {
   let view = GAMBannerView(adSize: GADAdSizeMediumRectangle)
   view.adUnitID = adID
   view.tag = tag
   view.delegate = metadata.delegate
   view.adSizeDelegate = metadata.adSizeDelegate
   view.rootViewController = metadata.rootViewController
   view.validAdSizes = getAdSizes(sizeOption: metadata.validAdSizes)
   let request = GAMRequest()
request.customTargeting = AdTargetingManager().makeCustomAdTargetingDictionary(metadata: metadata.targetingMetadata)
view.load(request)
  return view
 }

func setupAdvertisements() {
      datasource = datasource.filter({($0 as? AdvertisementCellConfigurator) == nil})
      let adA = AdvertisementModel(adId: AdvertisementConstants.FeedAdvertisementSectionA, tagCell: AdvertisementManager.TAG_A)
      let adB = AdvertisementModel(adId: AdvertisementConstants.FeedAdvertisementSectionB, tagCell: AdvertisementManager.TAG_B)
      let adC = AdvertisementModel(adId: AdvertisementConstants.FeedAdvertisementSectionC, tagCell: AdvertisementManager.TAG_C)
      let adD = AdvertisementModel(adId: AdvertisementConstants.FeedAdvertisementSectionD, tagCell: AdvertisementManager.TAG_D)
      let adE = AdvertisementModel(adId: AdvertisementConstants.FeedAdvertisementSectionE, tagCell: AdvertisementManager.TAG_E)
datasource.addAdvertisments(firstAdPosition: 3, frequency: 5, ads: [adA, adB, adC, adD, adE])
      let adCount = datasource.count(where: {$0 is AdvertisementCellConfigurator})
      if adCount > AdvertisementManager.TAG_E {
            datasource = datasource.filter({($0 as? AdvertisementCellConfigurator) == nil})
          var advertisements = [adA, adB, adC, adD, adE]
          for counter in (AdvertisementManager.TAG_E + 1)...adCount {
          let adE = AdvertisementConstants.FeedAdvertisementSectionE
          advertisements.append(AdvertisementModel(adId: adE, tagCell: counter))
          if counter > cachedAdvertisements.count {
             cachedAdvertisements[adE + "\(counter)" ] = advertisementManager.requestRepeatingAdvertisement(with: adE, metadata: googleMetadata)
         }
        }
       datasource.addAdvertisments(firstAdPosition: 3, frequency: 5, ads: advertisements)
     }
}

Upvotes: 5

Views: 417

Answers (1)

lzouloumis
lzouloumis

Reputation: 26

Caching advertisements while scrolling, means that while scrolling you are constantly increasing the memory footprint of the application.

You should try an interim solution. Try caching only the distinct advertisements. For example cache advertisements from A to E. Then you should leverage the reuse mechanism of the collection view. Mark for instance advertisements that have loaded with a boolean value and prevent the reloading of the advertisements.

The cache should look like this and please follow closer the demo from google (You don't have to use a tag, just cache the view in a dictionary):

let cache = [AdvertismentA, AdvertismentB, AdvertismentC, AdvertismentD, AdvertismentE]

var hasLoaded: [GADBannerView: Bool]

NOTE: The collectionView cell should not make network call cause you will get banned from google.

If the user scrolls further from AdvertisementE do not:

  • Load again the advertisement (API spam)
  • Cache with different tag the same advertisement (Memory overloading)

Just show a reused collection view cell with an advertisement.

Upvotes: 1

Related Questions