How can I make the rows for an audio app in CarPlay tappable?

Viewed 938

I'm new to CarPlay and understand it's similar to UITableViewController but slightly different and not able to make the rows capable of being tapped to run a function/code. Not much info online on this, no samples. Apple engineer told me they will provide a sample for audio apps soon on their developer site. So far I have everything running and that's all I believe I'm missing. I have entitlements from Apple, added what's needed in plist. Everything displays fine in actual CarPlay device. I have two tabs with sample items in them, one I need to run function for streaming live media when tapped, and the other to a podcast list, need to load list and make them tappable to run functions for that.

This is what I've been testing so far:

protocol MPPlayableContentDelegate {
    func dataReceived(data: String)
}


//Check data:       indexPath.count == 2 && indexPath[0] == 0 && indexPath[1] == 0
class CarplayDataSource: NSObject, MPPlayableContentDataSource, MPPlayableContentDelegate {

    let dataStore = NSObject()
    var dataHelper: DataHelper!
    var podcastData = [PodcastObject]()

    var podcastItem = PlayerViewController()

    var delegate: MPPlayableContentDelegate! = nil

    func dataReceived(data: String) {
        delegate?.dataReceived(data:"data received")
    }

    override init() {
        super.init()
        print("CARPLAY: init")
        self.dataReceived(data: "data is now received")
    }

    func numberOfChildItems(at indexPath: IndexPath) -> Int {
        print("CARPLAY: number of items")

        if indexPath.indices.count == 0 {
            print("CARPLAY: number of items > indices.count == 0 > return 2")
            return 2
        } else if indexPath.indices.count == 1 {
            print("CARPLAY: number of items > indices.count == 1 > return 1")
            return 1
        }
        return 1
    }


    func contentItem(at indexPath: IndexPath) -> MPContentItem? {
        print("CARPLAY: contentItem at indexpath")

        let indexCount = indexPath.count
        let tabIndex = indexPath[0]
        if indexCount == 1 {

            if tabIndex == 0 {
                let item = MPContentItem(identifier: "Tab \(tabIndex)")

                item.title = "Radio"
                item.isContainer = true
                item.isPlayable = false
                item.artwork = MPMediaItemArtwork(image: #imageLiteral(resourceName: "radio-carplay"))
                return item
            } else {

                let item = MPContentItem(identifier: "Tab \(tabIndex)")
                item.title = "Podcasts"
                item.isContainer = true
                item.isPlayable = false
                item.artwork = MPMediaItemArtwork(image: #imageLiteral(resourceName: "recordings-carplay"))
                return item
            }
        } else if indexCount == 2 {

            if tabIndex == 0 {
                let item = MPContentItem(identifier: "Tab \(tabIndex) Item")
                item.title = "Listen Live" //= "Tab \(tabIndex) Item"
                item.subtitle = "Radio Subtitle!"
                item.isPlayable = true
                item.artwork = MPMediaItemArtwork(image: #imageLiteral(resourceName: "menulogo"))

                if #available(iOS 10.0, *) {
                    item.isStreamingContent = true
                }
                return item
            } else {
                let item = MPContentItem(identifier: "Tab \(tabIndex) Item")
                item.title = "Coming Soon!" //for now since I don't now how to bring the list in
                item.isPlayable = true
                return item
            }

        }
        return nil

    }

    func contentItem(forIdentifier identifier: String, completionHandler: @escaping (MPContentItem?, Error?) -> Swift.Void){
    }

}
1 Answers

Have you tried to use:

- (void)playableContentManager:(MPPlayableContentManager *)contentManager initiatePlaybackOfContentItemAtIndexPath:(NSIndexPath *)indexPath completionHandler:(void (^)(NSError * _Nullable))completionHandler;

It's part of MPPlayableContentDelegate. From there I just call the regular play methods from my app. Hope this helps.

Related