fix(node): prevent iOS VoiceWake crash
This commit is contained in:
@@ -82,7 +82,7 @@ actor BridgeClient {
|
||||
var line = Data()
|
||||
line.append(data)
|
||||
line.append(0x0A)
|
||||
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
|
||||
try await withCheckedThrowingContinuation(isolation: nil) { (cont: CheckedContinuation<Void, Error>) in
|
||||
connection.send(content: line, completion: .contentProcessed { err in
|
||||
if let err { cont.resume(throwing: err) } else { cont.resume(returning: ()) }
|
||||
})
|
||||
@@ -104,7 +104,7 @@ actor BridgeClient {
|
||||
}
|
||||
|
||||
private func receiveChunk(over connection: NWConnection) async throws -> Data {
|
||||
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Data, Error>) in
|
||||
try await withCheckedThrowingContinuation(isolation: nil) { (cont: CheckedContinuation<Data, Error>) in
|
||||
connection.receive(minimumIncompleteLength: 1, maximumLength: 64 * 1024) { data, _, isComplete, error in
|
||||
if let error {
|
||||
cont.resume(throwing: error)
|
||||
|
||||
@@ -19,8 +19,9 @@ final class BridgeDiscoveryModel: ObservableObject {
|
||||
func start() {
|
||||
if self.browser != nil { return }
|
||||
let params = NWParameters.tcp
|
||||
params.includePeerToPeer = true
|
||||
let browser = NWBrowser(
|
||||
for: .bonjour(type: ClawdisBonjour.bridgeServiceType, domain: nil),
|
||||
for: .bonjour(type: ClawdisBonjour.bridgeServiceType, domain: ClawdisBonjour.bridgeServiceDomain),
|
||||
using: params)
|
||||
|
||||
browser.stateUpdateHandler = { [weak self] state in
|
||||
|
||||
@@ -111,7 +111,7 @@ actor BridgeSession {
|
||||
var line = Data()
|
||||
line.append(data)
|
||||
line.append(0x0A)
|
||||
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
|
||||
try await withCheckedThrowingContinuation(isolation: nil) { (cont: CheckedContinuation<Void, Error>) in
|
||||
connection.send(content: line, completion: .contentProcessed { err in
|
||||
if let err { cont.resume(throwing: err) } else { cont.resume(returning: ()) }
|
||||
})
|
||||
@@ -134,7 +134,7 @@ actor BridgeSession {
|
||||
|
||||
private func receiveChunk() async throws -> Data {
|
||||
guard let connection = self.connection else { return Data() }
|
||||
return try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Data, Error>) in
|
||||
return try await withCheckedThrowingContinuation(isolation: nil) { (cont: CheckedContinuation<Data, Error>) in
|
||||
connection.receive(minimumIncompleteLength: 1, maximumLength: 64 * 1024) { data, _, isComplete, error in
|
||||
if let error {
|
||||
cont.resume(throwing: error)
|
||||
|
||||
@@ -57,7 +57,7 @@ final class ScreenController: ObservableObject {
|
||||
if let maxWidth {
|
||||
config.snapshotWidth = NSNumber(value: Double(maxWidth))
|
||||
}
|
||||
let image: UIImage = try await withCheckedThrowingContinuation { (cont: CheckedContinuation<UIImage, Error>) in
|
||||
let image: UIImage = try await withCheckedThrowingContinuation { cont in
|
||||
self.webView.takeSnapshot(with: config) { image, error in
|
||||
if let error {
|
||||
cont.resume(throwing: error)
|
||||
|
||||
@@ -96,9 +96,8 @@ final class VoiceWakeManager: NSObject, ObservableObject {
|
||||
inputNode.removeTap(onBus: 0)
|
||||
|
||||
let recordingFormat = inputNode.outputFormat(forBus: 0)
|
||||
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { [weak self] buffer, _ in
|
||||
guard let self else { return }
|
||||
self.recognitionRequest?.append(buffer)
|
||||
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { [request] buffer, _ in
|
||||
request.append(buffer)
|
||||
}
|
||||
|
||||
self.audioEngine.prepare()
|
||||
@@ -169,22 +168,18 @@ final class VoiceWakeManager: NSObject, ObservableObject {
|
||||
try session.setActive(true, options: [])
|
||||
}
|
||||
|
||||
private static func requestMicrophonePermission() async -> Bool {
|
||||
await withCheckedContinuation { cont in
|
||||
private nonisolated static func requestMicrophonePermission() async -> Bool {
|
||||
await withCheckedContinuation(isolation: nil) { cont in
|
||||
AVAudioApplication.requestRecordPermission { ok in
|
||||
Task { @MainActor in
|
||||
cont.resume(returning: ok)
|
||||
}
|
||||
cont.resume(returning: ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func requestSpeechPermission() async -> Bool {
|
||||
await withCheckedContinuation { cont in
|
||||
private nonisolated static func requestSpeechPermission() async -> Bool {
|
||||
await withCheckedContinuation(isolation: nil) { cont in
|
||||
SFSpeechRecognizer.requestAuthorization { status in
|
||||
Task { @MainActor in
|
||||
cont.resume(returning: status == .authorized)
|
||||
}
|
||||
cont.resume(returning: status == .authorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ actor BridgeConnectionHandler {
|
||||
var line = Data()
|
||||
line.append(data)
|
||||
line.append(0x0A) // \n
|
||||
let _: Void = try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
|
||||
let _: Void = try await withCheckedThrowingContinuation { cont in
|
||||
self.connection.send(content: line, completion: .contentProcessed { err in
|
||||
if let err {
|
||||
cont.resume(throwing: err)
|
||||
|
||||
@@ -24,13 +24,14 @@ actor BridgeServer {
|
||||
self.store = store
|
||||
|
||||
let params = NWParameters.tcp
|
||||
params.includePeerToPeer = true
|
||||
let listener = try NWListener(using: params, on: .any)
|
||||
|
||||
let name = Host.current().localizedName ?? ProcessInfo.processInfo.hostName
|
||||
listener.service = NWListener.Service(
|
||||
name: "\(name) (Clawdis)",
|
||||
type: ClawdisBonjour.bridgeServiceType,
|
||||
domain: nil,
|
||||
domain: ClawdisBonjour.bridgeServiceDomain,
|
||||
txtRecord: nil)
|
||||
|
||||
listener.newConnectionHandler = { [weak self] connection in
|
||||
|
||||
Reference in New Issue
Block a user