user7219266
user7219266

Reputation:

iOS - How to init and insert UICollectionViewCell programmatically when data is ready?

I would like to add Ads in my App, like Native Ads or Parallax.

The App is mainly an UICollectionView with many cells displaying different information.

I am using an SDK in order to load the Ad Object.

I have made a custom UICollectionViewCell class in order to init the cell and load the Native Ad as a cell in my UICollectionView.

@objc class AdsCollectionViewCell: BaseCollectionViewCell, AdapterAdsDelegate {

    @IBOutlet var outletNativeTitle: UILabel!
    @IBOutlet var outletImageNative: UIImageView!
    @IBOutlet var outletButtonAction: UIButton!
    @IBOutlet var clickableView: UIView!
    @IBOutlet var mediaContainer: UIView!
    @IBOutlet var bottomView: UIView!

    var adFactory = AdsSDKFactory()
    var adObject = AdsObject()

    @objc func initCell(viewController: HomeViewController) {

        DispatchQueue.main.async {
            self.isHidden = true
        }

        // Set some properties for the Ads SDK
        adFactory.nativeDelegate = self
        adObject.viewController = viewController

        adFactory.placementId = "154569"

        // method from the SDK to request the Ad  
        adFactory.loadAds()
    }

It is working but my main issue is that I am displaying an empty cell and the content is displayed when I got the delegate response method from the Ad SDK with the Ad Object.

Here is the delegate method I receive in my AdsCollectionViewCell.

func adObjectDidLoad(adView: AdsObject!) {

    self.adObject = adView
    self.updateCellOutlets() // my method to update labels from the adView
    self.setNeedsDisplay()

    self.delegate.tileCellDidSucceed!(self)
}

I would like to first init and make the call to the adFactory.loadAds in my HomeViewController, so that when I got the delegate response and the adObject, I don't updateCellOutlets directly but I can self.delegate.tileCellDidSucceed!(self) which is the delegate from my BaseCollectionViewCell in order to notify my HomeViewController that the cell is ready.

How can init a cell outside of the cellForRow method to dynamically insert it when the Ad is loaded ?

EDIT: I have followed the advices and create a Singleton AdsLoader class, that set all the parameters to request the ad, and also make the load request. I set my HomeViewController as delegate so that I can get the view ad as response directly in my HomeViewController.

My issue now is to insertObject in the collectionView at the right indexPath. Which object should I insert?

Upvotes: 0

Views: 388

Answers (1)

Ganesh Somani
Ganesh Somani

Reputation: 2360

I am unable to get a clear picture of the code and specific requirements of your AdSDK. So i will go ahead and write a pseudo code as per my understanding of what needs to be done. Here is what I purpose, instead of calling adFactory.loadAds() into the UICollectionViewCell object, you can perform this task into a different class object. Let say AdLoader

So your add loader should be something like this.

class Adloader {

var adFactory = AdsSDKFactory()

typealias adLoadCompletionHandler = (adView: AdsObject) -> Void

var loadCompletion
 func initLoader() {
   //Set some properties for the Ads SDK
    adFactory.nativeDelegate = self

   // method from the SDK to request the Ad  
    adFactory.loadAds()
  }
}

Once the ad is loaded, you can use a completion handler to get update the collection view.

func adObjectDidLoad(adView: AdsObject!) {
    adLoadCompletionHandler(adView)
}

So your code can be something like this.

if (needToInsertAd) {
   var newAd = Adloader.initLoader()
   newAd.adLoadCompletionHandler {
       //Code to insert cell at indexpath
   }
}

Hope this helps you.

Upvotes: 1

Related Questions