前语

上面文章说到了我做的Mac客户端Ai Chat – 你问我答。恰好我的开发机子是19款的Macbook Pro (苹果最后一款支撑Touch Bar的机器)。你们有多久没用过这个Bar了?本着捣鼓的精神,我研究了怎么使用它以及在此实时回来GPT的回来内容,完成了一个跑马灯作用,以下是完成计划,作用如下

完成计划

  • 怎么回来一个自定义的TouchBar

TouchBar的开发实际上只要遵从苹果App Kit固定的API,能够非常简略的完成你想要的自定义Toubar。

榜首步在ViewController 或者 Window下面重写makeTouchBar办法,新建你的TouchBar。


open override func makeTouchBar() -> NSTouchBar? {
let touchBar = NSTouchBar()
touchBar.delegate = self
touchBar.customizationIdentifier = .customBar
touchBar.defaultItemIdentifiers = [.textFieldItem]
return touchBar
}

然后重写public func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem?办法,构建你Toubar的UI,代码如下,因为Mac开发与iOS开发本质上没有太大差异,所以布局还是直接用SnapKit即可。


public func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
switch identifier {
case NSTouchBarItem.Identifier.textFieldItem:
let item = NSCustomTouchBarItem(identifier: .textFieldItem)
let textField = NSTextField(labelWithString: " Say Something")
self.textField = textField
textField.isEditable = false
textField.isBordered = false
textField.textColor = .white
textField.maximumNumberOfLines = 1
textField.backgroundColor = NSColor.clear
textField.alignment = .center
let scrollView = NSScrollView()
scrollView.documentView = textField
scrollView.hasHorizontalRuler = true
self.scrollView = scrollView
item.view = scrollView
scrollView.snp.makeConstraints { make in
make.left.equalTo(item.view.snp.left).offset(0)
make.top.equalTo(item.view.snp.top).offset(0)
make.bottom.equalTo(item.view.snp.bottom).offset(0)
make.right.equalTo(item.view.snp.right).offset(0)
}
textField.snp.makeConstraints { make in
make.left.equalTo(item.view.snp.left).offset(0)
make.top.equalTo(item.view.snp.top).offset(0)
make.bottom.equalTo(item.view.snp.bottom).offset(0)
}
return item
case NSTouchBarItem.Identifier.buttonItem:
let item = NSCustomTouchBarItem(identifier: identifier)
let button = NSButton(title: "Send Message", target: self, action: #selector(sendButtonTapped(_:)))
button.bezelColor = NSColor.systemBlue
item.view = button
return item
default:
return nil
}
}

同意榜首呼应


open override var acceptsFirstResponder: Bool {
return true
}

就这样咱们发动Mac应用咱们的自定义Toubar就构建好了,默认它会回来一句内容️ Say Something

  • 怎么完成承受GPT流信息,并完成跑马灯作用

Open AI,GPT流式回来我不多赘述,很多文章都有说到Flutter怎么完成OpenAi流式回来,我的Mac客户端是Flutter编写,只需要把OpenAi的接口设置为流接口,然后HttpClient使用流的方式回来即可。然后自定义一个插件,从Flutter回来流信息到Mac原生刷新TouchBar。

跑马灯作用其实完成起来和iOS原生是一样的,我是基于一个ScrollView无限长度的Label,然后核算Label的宽 如果大于TouchBar的最大宽度,每次刷新文本时分,主动滚到Label的末尾来做的 代码如下。

从插件更新文本


OpenAiStreamResPlugin.shareInstance.responseStreamText = { [weak flutterViewController] text in
autoreleasepool {
flutterViewController?.addText(text: text)
}
}

跑马灯作用


func addText(text: String) {
if text.count == 0 {
self.textField?.stringValue = " Say Something"
self.scrollView?.contentView()?.scroll(NSPoint(x: 0, y: 0))
return
}
var newText = text.trimmingCharacters(in: .whitespacesAndNewlines)
newText = newText.replacingOccurrences(of: "\n", with: "")
self.textField?.stringValue = newText
if let scrollView = self.scrollView {
self.textField?.sizeToFit()
let textF = self.textField!
if textF.frame.size.width > scrollView.frame.size.width {
self.scrollView?.contentView()?.scroll(NSPoint(x: textF.frame.size.width, y: 0))
}
}
}

就这样一个支撑GPT完成回来信息的跑马灯TouchBar就完成了,是不是很简略?