Reputation: 880
We have followed Google's example for Ads in a TableView:
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
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:
Just show a reused collection view cell with an advertisement.
Upvotes: 1