0

I'm using MoPub in my iOS app to display native adverts in a UITableView. I'm hitting an issue where I'm getting fatal error: Array index out of range errors and I understand why but I can't figure out how to fix it.

MoPub inserts rows into the UITableView and as a result, the indexPath parameter to editActionsForRowAtIndexPath includes the rows containing adverts. However, the array of data for the table does not include these rows and therefore for each advert that is inserted, the indexPath of the row showing the data is +1 when compared to the index in the data array for that row. See the editActionsForRowAtIndexPath method below.

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
    // fetch the data for the currently selected row
    let currentDictionary = xmlParser.arrParsedData[indexPath.row] as Dictionary<String, String>
    self.shareURL = currentDictionary["link"]!

    var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "Share" , handler: { 
        (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in

        NSLog("indexPath:%d", indexPath.row)

    })

    return [shareAction]
}

For example, if I have an advert in the third row (index = 2), swiping on the non-MoPub advert rows, I get the following output:

indexPath:0
indexPath:1
indexPath:3
indexPath:4

So the MoPub advert is being counted in the indexPath parameter but since that row doesn't exist in my datasource array for the tableView, the indexPath parameters are now out of sync.

How can I make sure that the indexes of the data array and the rows of the table are kept in sync?

conorgriffin
  • 4,282
  • 7
  • 51
  • 88
  • Hey Conor, If you use [MPTableViewAdPlacer](https://github.com/mopub/mopub-ios-sdk/wiki/Native-Ads-Integration#place-ads-in-a-uitableview) and the respective mp replacements for the UITableView Method calls as defined in MoPub's iOS Documentation 'Native Ads Integration', this will fix your index sync issues. – Edward Jul 13 '15 at 13:18
  • Yeah I am using all of the ones I believe I need to – conorgriffin Jul 13 '15 at 13:18
  • Best thing is probably to make a small sample project to demo the issue – conorgriffin Jul 13 '15 at 13:22
  • Hey Conor, Can you implement something like this? `let indexPath = self.tableView.mp_indexPathForSelectedRow` mp_indexPathForSelectedRow returns the original index path for the selected row, as if no ads have been inserted. – Edward Jul 13 '15 at 21:19
  • I tried that but when you swipe left on a row to trigger the `editActionsForRowAtIndexPath` method, this doesn't select the row. So the selected row will be nil if no row was already selected or it will be another row if a row had already been selected. Neither is any good – conorgriffin Jul 13 '15 at 21:21

1 Answers1

2

You can get the cell at the current indexPath within editActionsForRowAtIndexPath. With this cell, we can get the appropriate indexPath without including the ads indices with mp_indexPathForCell.

Since editActionsForRowAtIndexPath takes in IndexPath, which is not the same when ads are included, we have to have a way to edit indexPath to the correct parameters.

let cell = cellForRowAtIndexPath(indexPath)
let indexPath = mp_indexPathForCell(cell)

The above code replaces the indexPath with the modified indexPath without the ad indices included.

Edward
  • 251
  • 1
  • 4