Создайте список для CarPlay

Поэтому в настоящее время мне приходится вручную добавлять новые станции в наше приложение CarPlay. Однако у нас есть JSON, который наше приложение использует для iPhone и iPad. Поэтому мне интересно, как мне создать список, который использует эту информацию, вместо того, чтобы создавать ее вручную.

func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) {
   
    
    let DRN1 = CPListItem(text: "DRN1", detailText: "Perth's No.1 Online Station.")
    let Hits = CPListItem(text: "DRN1 Hits", detailText: "Top 40 songs and yesturdays hits.")
    let United = CPListItem(text: "DRN1 United", detailText: "Perth's Dedicated LGBTIQA+ Station.")
    let Dance = CPListItem(text: "DRN1 Dance", detailText: "Playing the hottest dance tracks.")
    
   
    
    if #available(iOS 14.0, *) {
        let nowplay = CPNowPlayingTemplate.shared
        
        DRN1.setImage(UIImage(imageLiteralResourceName:"DRN1Logo"))
        DRN1.handler = { item, completion in
            print("selected DRN1")
            AdStichrApi.station = "DRN1"
            MusicPlayer.shared.startBackgroundMusic(url:"https://api.example.com.au:9000/station/DRN1", type: "radio")
            Nowplayinginfo().getsong()
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.00) {
                interfaceController.pushTemplate(nowplay, animated: true,completion:nil)
                completion()
            }
        }
        
        Hits.setImage(UIImage(imageLiteralResourceName:"DRN1Hits"))
        Hits.handler = { item, completion in
            print("selected Hits")
            MusicPlayer.shared.player?.pause()
            AdStichrApi.station = "DRN1Hits"
            MusicPlayer.shared.startBackgroundMusic(url:"https://api.example.com.au:9000/station/DRN1Hits", type: "radio")
            Nowplayinginfo().getsong()
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.00) {
               
                //interfaceController.presentTemplate(nowplay, animated: false)
                interfaceController.pushTemplate(nowplay, animated: true,completion:nil)
                completion()
                
            }
        }
        
        United.setImage(UIImage(imageLiteralResourceName:"DRN1United"))
        United.handler = { item, completion in
            print("selected United")
            AdStichrApi.station = "DRN1United"
            MusicPlayer.shared.startBackgroundMusic(url:"https://api.example.com.au:9000/station/DRN1United", type: "radio")
              // do work in the UI thread here
            Nowplayinginfo().getsong()
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.00) {
                interfaceController.pushTemplate(nowplay, animated: true,completion:nil)
                completion()
            }
            
            
            
        }
        
        Dance.setImage(UIImage(imageLiteralResourceName:"DRN1Dance"))
        Dance.handler = { item, completion in
            print("selected Dance")
            AdStichrApi.station = "dance"
            MusicPlayer.shared.startBackgroundMusic(url:"https://api.example.com.au:9000/station/dance", type: "radio")
            Nowplayinginfo().getsong()
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.00) {
                completion()
                interfaceController.pushTemplate(nowplay, animated: true,completion:nil)
            }
        }
        
        
        
        
    } else {
        // Fallback on earlier versions
    }
    
    
    
    let listTemplate = CPListTemplate(title: "Select a Station", sections: [CPListSection(items:[DRN1,United,Hits,Dance])])
   
   

Однако в моем приложении для iOS я просто использую

Api().getStations { (stations) in
                       self.stations = stations
        }

Который извлекает JSON из бэкэнда и предоставляет мне каждую доступную станцию.

Мне интересно, как я могу создать CPList, используя эту информацию.

Пример: Я нашел этот пример, но он извлекает локальные данные, и в настоящее время мне не нужна панель вкладок.

https://github.com/T0yBoy/CarPlayTutorial/дерево/мастер/CarPlayTutorial

Насколько я понимаю, все, что мне нужно сделать, это создать список

for station in (radios) {
            let item = CPListItem(text: station.name, detailText: station.name)
            item.accessoryType = .disclosureIndicator
            item.setImage(UIImage(named: station.imageurl))
            item.handler = { [weak self] item, completion in
                guard let strongSelf = self else { return }
               // strongSelf.favoriteAlert(radio: radio, completion: completion)
            }
            radioItems.append(item)
        
        }

Я знаю, что мне нужно сделать что-то вроде


        Api().getStations { (stations) in
            self.radios = stations
            
            INSERT THE STATIONS INTO A LIST for 

let listTemplate = CPListTemplate(title: "Select a Station", sections: [CPListSection(items:stations)])
        }

Вот как это все еще должно выглядеть после создания списка из API Создайте список для CarPlay

Является ли шаблон списка первым представлением, которое пользователь должен увидеть со списком станций? И ваш вопрос отображает только список или отображает список после того, как API отправил ответ?

Shawn Frank 29.03.2022 07:13

@ShawnFrank, так что это первое представление, да. Я пытаюсь понять, как заставить его загружаться в CarPlay. Я знаю, что мне нужно сделать что-то вроде примера, который я опубликовал выше.

Russell Harrower 29.03.2022 07:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
43
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте это:

// In some function in the CarPlaySceneDelegate
Api().getStations { (stations) in
    
    var stationItems: [CPListItem] = []
    
    self.radios = stations
    
    for station in stations {
        
        let item = CPListItem(text: station.name, 
                              detailText: station.description
                              image: station.image)
        
        item.handler = { [weak self] item, completion in
            
            // manage what should happen on tap
            // like navigate to NowPlayingView
            
        }
        
        stationItems.append(item)
    }
    
    loadList(withStations: stationItems)
}

// Load the list template
private func loadList(withStations stations: [CPListItem]) {
    
    let section = CPListSection(items: stations)
    let listTemplate = CPListTemplate(title: "Select a station",
                                      sections: [section])
    
    // Set the root template of the CarPlay interface
    // to the list template with a completion handler
    interfaceController?.setRootTemplate(listTemplate,
                                         animated: true) { success, error in
        
        // add anything you want after setting the root template
    }
}

Цикл for для добавления станций в массив CPListItem можно заменить функцией map, но я сделал это для ясности.

Обновлять

В своем class CarPlaySceneDelegate исправьте написание от

var interfactController: CPInterfaceController?

к

var interfaceController: CPInterfaceController?

В своем templateApplicationScene didConnect комментарии interfactController?.setRootTemplate(listTemplate, animated: false) на данный момент

и добавьте к нему эту строку self.interfaceController = interfaceController

Итак, обновленная функция выглядит так:

func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene,
                              didConnect interfaceController: CPInterfaceController) {
    
    // Add this
    self.interfaceController = interfaceController
    
    Api().getStations { (stations) in
        
        var stationItems: [CPListItem] = []
        
        self.stations = stations
        
        for station in stations {
            
            let item = CPListItem(text: station.name,
                                  detailText: station.name
                                  // image: imageLiteralResourceName:"DRN1Logo")
            )
            
            item.handler = { [weak self] item, completion in
                
                // manage what should happen on tap
                // like navigate to NowPlayingView
                print(item)
            }
            
            stationItems.append(item)
        }
        
        self.loadList(withStations: stationItems)
    }
}

Вы видите лучшие результаты?

Я получаю Не могу найти 'interfaceController' в области видимости

Russell Harrower 29.03.2022 08:01

Я загрузил проект Xcode github.com/redimongo/iOS-радио-приложение Не уверен, что это поможет

Russell Harrower 29.03.2022 08:16

@RussellHarrower - я просмотрел ваш репозиторий на github и обновил свой ответ, см. Раздел Обновлять

Shawn Frank 29.03.2022 08:30

спасибо - это работает :) Только сейчас нужно разобраться, как отправить listenURL: station.listenlive внутри CPListItem - кажется, вы не можете добавлять дополнительные аргументы

Russell Harrower 29.03.2022 08:39

@RussellHarrower - Рад, что у тебя все получилось! Не уверен, что я полностью понял вторую часть вопроса, однако вы, вероятно, могли бы открыть новый вопрос с этим, если вы не можете понять это и поделиться со мной ссылкой здесь, я попытаюсь взглянуть на это. Если этот ответ помог вам получить то, что вы хотите, рассмотрите возможность пометить его как ответ - это поможет мне и другим :)

Shawn Frank 29.03.2022 08:44

Это было легко, просто нужно было сделать, если пусть listenNow = station.first(where: {$0.name == item.text}) { внутри item.handler = {[weak self] item, завершение в

Russell Harrower 29.03.2022 08:46

Ах, хорошо, я понимаю, что вы имеете в виду. Я помню, что когда только начинал, у меня были трудности с пониманием CarPlay, но приятно видеть, что вы разбираетесь в этом быстрее.

Shawn Frank 29.03.2022 08:50

Просто интересно, знаете ли вы, как преобразовать строковое URL-изображение в UIImage для этого?

Russell Harrower 29.03.2022 09:09

@RussellHarrower — вы можете использовать Data(contentsOf: url), чтобы получить представление данных изображения из URL-адреса. Тогда вы можете использовать UIImage(data: data). Однако вам также может понадобиться управлять временем загрузки с помощью асинхронных вызовов. Взгляните на: hackingwithswift.com/example-code/uikit/…

Shawn Frank 29.03.2022 09:18

Да, определенно загружайте их асинхронно и кешируйте. У нас есть фрагмент с удобным инициализатором для элемента списка (gist.github.com/fruitcoder/…). Если вам нужна дополнительная информация о том, как она используется, вы можете найти ее здесь medium.com/br-следующий/….

fruitcoder 29.03.2022 09:34

Другие вопросы по теме