В настоящее время я разрабатываю очень простое приложение для Mac OSX Live Scores для личного использования, в котором я показываю несколько ярлыков (баллов) на сенсорной панели.Чего я пытаюсь достичь, выполнив несколько шагов:
- Каждые 30 секунд извлекайте результаты футбольных матчей из стороннего API
- Анализируйте результаты и делайте их на ярлыки
- Обновите сенсорную панель новыми счетами
[Обратите внимание, что это приложение нигде не будет опубликовано и предназначено только для личного использования.Мне известно о том, что Apple строго советует против такого типа контента на сенсорной панели.]
Вот код, который я написал после базового учебника по сенсорной панели от RW (https://www.raywenderlich.com/883-how-to-use-nstouchbar-on-macos). Скелет моего кода выбран из учебника RW:
- В
WindowController
(точка входа в StoryBoard), переопределите makeTouchBar
, например:
override func makeTouchBar() -> NSTouchBar? {
guard let viewController = contentViewController as? ViewController else {
return nil
}
return viewController.makeTouchBar()
}
В
ViewController
, который также является делегатом сенсорной панели, реализуется
makeTouchBar
fn:
override func makeTouchBar() -> NSTouchBar? {
let touchBar = NSTouchBar()
touchBar.delegate = self
touchBar.customizationIdentifier = .scoresBar
touchBar.defaultItemIdentifiers = [.match1, .flexibleSpace, .match2, ... , .match10]
return touchBar
}
NSTouchBarDelegate
в
ViewController
.
scores
- это место, где я храню свои полученные результаты (см. 5).Я возвращаю
nil
за просмотры, если результаты еще не получены:
extension ViewController: NSTouchBarDelegate {
func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
if (<scores not fetched yet>) {
return nil
}
// matchNum is the match number for which I am showing scores for
let customViewItem = NSCustomTouchBarItem(identifier: identifier)
customViewItem.view = NSTextField(labelWithString: self.scores[matchNum ?? 0])
return customViewItem
}
}
Чтобы периодически получать оценки, я запускаю таймер запланированного задания в
viewDidLoad()
моего viewcontroller, например:
_ = Timer.scheduledTimer(timeInterval: 30.0, target: self, selector: #selector(ViewController.fetchScores), userInfo: nil, repeats: true)
И, наконец, это моя функция
fetchScores
, которая также выполняет вызов для обновления сенсорной панели:
@objc func fetchScores() {
let url = "<scores api end point>"
Alamofire.request(url).responseJSON { response in
if let json = response.result.value {
// update self.scores here and fill it with latest scores
if #available(OSX 10.12.2, *) {
//self.touchBar = nil
self.touchBar = self.makeTouchBar() // This is where I am calling makeTouchBar again to update Touch Bar content dynamically
}
}
}
Насколько я понимаю из приведенного выше кода, когда я звонюmakeTouchBar
in fetchScores
и назначить его свойству touchBar
моего viewcontroller, в идеале он должен вызвать функцию делегата touchBar(:makeItemForIdentifier)
для обновления представления Touch Bar (поток SO в этом ).Но в моем случае touchBar(:makeItemForIdentifier)
никогда не вызывается.Единственный раз, когда вызывается touchBar(:makeItemForIdentifier)
, это первый раз, когда makeTouchBar
вызывается из моего WindowController (см. Пункт 1 выше).А поскольку результаты еще не получены, моя сенсорная панель остается пустой.