Bug in MPPlayableContentManager's reloadData

[[MPPlayableContentManager sharedContentManager]reloadData];


Running above code will not call the below code for the current indexPath if it was called very recently

- (NSInteger)numberOfChildItemsAtIndexPath:(NSIndexPath *)indexPath;


Calling reload data with at least 0.4 seconds of delay will trigger numberOfChildItemsAtIndexPath correctly.


Calling reloadData with delay is not a good solution.


I do not use beginLoadingChildItemsAtIndexPath as it is not usable in my case.

Scenario:

- Show "countries" as a container.

- Touch "countries". (it is already loaded)

- It will show countries.

- It will call beginLoadingChildItemsAtIndexPath for the countries on the screen but I will ignore it because I cannot load detailed information for all of the visible countries as that means lots of data from database. In this case, I can only load them when a call to numberOfChildItemsAtIndexPath is made for the country container I touched. So there is no other way for me than calling my data-loading-methods inside numberOfChildItemsAtIndexPath. While it is loading, I return 0 instantly as the number of child items and as soon as my data-loading-methods load details for the selected country container, it calls reloadData so MPPlayableContentManager can reconstruct everything. This works, but as it does not check number of child items for the current indexPath, it does not refresh current screen. The only solution I found is to call reloadData with 1 second delay, which does not sound good. How can I force the framework to call numberOfChildItesAtIndexPath for the current indexPath too?

Replies

You say that you are using a delay as a workaround. Are you using GCD dispatch after? Like this:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [MPPlayableContentManager.sharedContentManager reloadData];
});

Yes, I use exactly that and if I do not change 0.0 to 0.4, it does not work. (0.3 won't work for example)

After adding other cases, not it now requires 0.6 seconds. I believe I need to find the queue that triggersthe framework to call numberOfChilden for the current indexPath. So, I can dispatch the reloadData call on that queue; though I am not sure if I can find that queue...

I've had nothing but problems trying to keep CarPlay hierarchies in sync. Problems I regularly observe include:


1. reloadData not doing anything (your issue).

2. MPContentItems don't update on screen when their display properties are changed. This leads to users tapping one thing and getting something else since the presentation is stale.

3. MPContentItems that are no longer present continue to display at the end of a list.


The frequency of all these bugs seems to vary by hardware and is least likely to occur in the simulator. Because of that, the arbitrary delay you're using as a workaround may or may not be good enough on other hardware. You *could* beef up your workaround by:


When you need to call reloadData...

1. Start a timer with a reasonable expiration time like 2s? 3s? What's reasonable depends on your app.

2. Call reloadData

2. When numberOfChildItemsAtIndexPath: is executed, cancel the timer if it is running.

3. If the timer expires before numberOfChildItemsAtIndexPath: is executed, repeat at step 1. You'll probably want to set some limit on the number of times you repeat this.