From fb4b0616a1a22fb8d6432891c2423c617b7a441c Mon Sep 17 00:00:00 2001 From: Kwangsoo Yeo Date: Wed, 27 Sep 2023 14:13:37 -0700 Subject: [PATCH 1/9] ios v3.0 changes --- binding/ios/Porcupine-iOS.podspec | 4 +- binding/ios/Porcupine.swift | 40 +++++++++++++------ binding/ios/PorcupineAppTest/Podfile | 6 +-- binding/ios/PorcupineAppTest/Podfile.lock | 13 +++--- .../PorcupineAppTestUITests.swift | 18 +++++++++ binding/ios/PorcupineErrors.swift | 13 +++++- demo/ios/ForegroundApp/Podfile | 2 +- demo/ios/ForegroundApp/Podfile.lock | 13 +++--- 8 files changed, 80 insertions(+), 29 deletions(-) diff --git a/binding/ios/Porcupine-iOS.podspec b/binding/ios/Porcupine-iOS.podspec index 2adbce0a8b..b10d78fc9e 100644 --- a/binding/ios/Porcupine-iOS.podspec +++ b/binding/ios/Porcupine-iOS.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'Porcupine-iOS' s.module_name = 'Porcupine' - s.version = '2.2.1' + s.version = '3.0.0' s.license = {:type => 'Apache 2.0'} s.summary = 'iOS SDK for Picovoice\'s Porcupine wake word engine' s.description = @@ -22,7 +22,7 @@ Pod::Spec.new do |s| DESC s.homepage = 'https://github.com/Picovoice/porcupine/tree/master/binding/ios' s.author = { 'Picovoice' => 'hello@picovoice.ai' } - s.source = { :git => "https://github.com/Picovoice/porcupine.git", :tag => "Porcupine-iOS-v2.2.1" } + s.source = { :git => "https://github.com/Picovoice/porcupine.git", :tag => "Porcupine-iOS-v3.0.0" } s.ios.deployment_target = '11.0' s.swift_version = '5.0' s.vendored_frameworks = 'lib/ios/PvPorcupine.xcframework' diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index 4887d553e1..a968809156 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -46,6 +46,7 @@ public class Porcupine { public static let frameLength = UInt32(pv_porcupine_frame_length()) public static let sampleRate = UInt32(pv_sample_rate()) public static let version = String(cString: pv_porcupine_version()) + private var sdk = "ios" /// Constructor. /// @@ -192,6 +193,10 @@ public class Porcupine { } } + public func setSdk(sdk: String) { + self.sdk = sdk + } + /// Process a frame of audio with the wake word engine /// /// - Parameters: @@ -235,33 +240,44 @@ public class Porcupine { if status == PV_STATUS_SUCCESS { return } + var messageStackRef: UnsafeMutablePointer?>? + var messageStackDepth: Int32 = 0 + + let object = UnsafeRawPointer(self.handle) + pv_get_error_stack(object, &messageStackRef, &messageStackDepth) + + var messageStack: [String] = [] + while let s = messageStackRef?.pointee { + messageStack.append(String(cString: s)) + messageStackRef = messageStackRef?.advanced(by: 1) + } switch status { case PV_STATUS_OUT_OF_MEMORY: - throw PorcupineMemoryError(message) + throw PorcupineMemoryError(message, messageStack) case PV_STATUS_IO_ERROR: - throw PorcupineIOError(message) + throw PorcupineIOError(message, messageStack) case PV_STATUS_INVALID_ARGUMENT: - throw PorcupineInvalidArgumentError(message) + throw PorcupineInvalidArgumentError(message, messageStack) case PV_STATUS_STOP_ITERATION: - throw PorcupineStopIterationError(message) + throw PorcupineStopIterationError(message, messageStack) case PV_STATUS_KEY_ERROR: - throw PorcupineKeyError(message) + throw PorcupineKeyError(message, messageStack) case PV_STATUS_INVALID_STATE: - throw PorcupineInvalidStateError(message) + throw PorcupineInvalidStateError(message, messageStack) case PV_STATUS_RUNTIME_ERROR: - throw PorcupineRuntimeError(message) + throw PorcupineRuntimeError(message, messageStack) case PV_STATUS_ACTIVATION_ERROR: - throw PorcupineActivationError(message) + throw PorcupineActivationError(message, messageStack) case PV_STATUS_ACTIVATION_LIMIT_REACHED: - throw PorcupineActivationLimitError(message) + throw PorcupineActivationLimitError(message, messageStack) case PV_STATUS_ACTIVATION_THROTTLED: - throw PorcupineActivationThrottledError(message) + throw PorcupineActivationThrottledError(message, messageStack) case PV_STATUS_ACTIVATION_REFUSED: - throw PorcupineActivationRefusedError(message) + throw PorcupineActivationRefusedError(message, messageStack) default: let pvStatusString = String(cString: pv_status_to_string(status)) - throw PorcupineError("\(pvStatusString): \(message)") + throw PorcupineError("\(pvStatusString): \(message)", messageStack) } } } diff --git a/binding/ios/PorcupineAppTest/Podfile b/binding/ios/PorcupineAppTest/Podfile index 70e55c32cf..69a31aca3c 100644 --- a/binding/ios/PorcupineAppTest/Podfile +++ b/binding/ios/PorcupineAppTest/Podfile @@ -2,13 +2,13 @@ source 'https://cdn.cocoapods.org/' platform :ios, '11.0' target 'PorcupineAppTest' do - pod 'Porcupine-iOS', '~> 2.2.1' + pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' end target 'PorcupineAppTestUITests' do - pod 'Porcupine-iOS', '~> 2.2.1' + pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' end target 'PerformanceTest' do - pod 'Porcupine-iOS', '~> 2.2.1' + pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' end diff --git a/binding/ios/PorcupineAppTest/Podfile.lock b/binding/ios/PorcupineAppTest/Podfile.lock index 2d9839d658..0cac3d9190 100644 --- a/binding/ios/PorcupineAppTest/Podfile.lock +++ b/binding/ios/PorcupineAppTest/Podfile.lock @@ -1,20 +1,23 @@ PODS: - ios-voice-processor (1.1.0) - - Porcupine-iOS (2.2.1): + - Porcupine-iOS (3.0.0): - ios-voice-processor (~> 1.1.0) DEPENDENCIES: - - Porcupine-iOS (~> 2.2.1) + - Porcupine-iOS (from `../../../Porcupine-iOS.podspec`) SPEC REPOS: trunk: - ios-voice-processor - - Porcupine-iOS + +EXTERNAL SOURCES: + Porcupine-iOS: + :path: "../../../Porcupine-iOS.podspec" SPEC CHECKSUMS: ios-voice-processor: 8e32d7f980a06d392d128ef1cd19cf6ddcaca3c1 - Porcupine-iOS: df8e4a63d787b6c16bd5f988fd0f2c29a249a4bd + Porcupine-iOS: 517158e02ac294dda15b713a3c6f74a9e877090c -PODFILE CHECKSUM: e5e0f595115debf272bd322931c87f69c0b53d05 +PODFILE CHECKSUM: 70f38c09353a041d84d56f94757c44b3e268f04a COCOAPODS: 1.11.3 diff --git a/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift b/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift index 385f6dfdd1..b90e934b3f 100644 --- a/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift +++ b/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift @@ -245,4 +245,22 @@ class PorcupineAppTestUITests: BaseTest { XCTAssert(expectedKeyword == keywordDetected) } } + + func testMessageStack() throws { + var first_error: String = "" + do { + let p = try Porcupine.init(accessKey: "invalid", keyword: Porcupine.BuiltInKeyword.porcupine) + XCTAssertNil(p) + } catch { + first_error = "\(error.localizedDescription)" + XCTAssert(first_error.count < 1024) + } + + do { + let p = try Porcupine.init(accessKey: "invalid", keyword: Porcupine.BuiltInKeyword.porcupine) + XCTAssertNil(p) + } catch { + XCTAssert("\(error.localizedDescription)".count == first_error.count) + } + } } diff --git a/binding/ios/PorcupineErrors.swift b/binding/ios/PorcupineErrors.swift index e1f1313803..65be6bdaad 100644 --- a/binding/ios/PorcupineErrors.swift +++ b/binding/ios/PorcupineErrors.swift @@ -9,12 +9,23 @@ public class PorcupineError: LocalizedError { private let message: String + private let messageStack: [String] - public init (_ message: String) { + public init (_ message: String, _ messageStack: [String] = []) { self.message = message + self.messageStack = messageStack } public var errorDescription: String? { + if messageStack.count > 0 { + var i = 0 + let messageString = messageStack.reduce(message) { partial, current in + let reduced = partial + "\n [\(i)] \(current)" + i += 1 + return reduced + } + return messageString + } return message } diff --git a/demo/ios/ForegroundApp/Podfile b/demo/ios/ForegroundApp/Podfile index 06d08a2a5c..bf9628f3ab 100644 --- a/demo/ios/ForegroundApp/Podfile +++ b/demo/ios/ForegroundApp/Podfile @@ -2,5 +2,5 @@ source 'https://cdn.cocoapods.org/' platform :ios, '11.0' target 'PorcupineForegroundAppDemo' do - pod 'Porcupine-iOS', '~> 2.2.1' + pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' end diff --git a/demo/ios/ForegroundApp/Podfile.lock b/demo/ios/ForegroundApp/Podfile.lock index 0569216459..e2830f40ae 100644 --- a/demo/ios/ForegroundApp/Podfile.lock +++ b/demo/ios/ForegroundApp/Podfile.lock @@ -1,20 +1,23 @@ PODS: - ios-voice-processor (1.1.0) - - Porcupine-iOS (2.2.1): + - Porcupine-iOS (3.0.0): - ios-voice-processor (~> 1.1.0) DEPENDENCIES: - - Porcupine-iOS (~> 2.2.1) + - Porcupine-iOS (from `../../../Porcupine-iOS.podspec`) SPEC REPOS: trunk: - ios-voice-processor - - Porcupine-iOS + +EXTERNAL SOURCES: + Porcupine-iOS: + :path: "../../../Porcupine-iOS.podspec" SPEC CHECKSUMS: ios-voice-processor: 8e32d7f980a06d392d128ef1cd19cf6ddcaca3c1 - Porcupine-iOS: df8e4a63d787b6c16bd5f988fd0f2c29a249a4bd + Porcupine-iOS: 517158e02ac294dda15b713a3c6f74a9e877090c -PODFILE CHECKSUM: 70adce58df76651ab08c0f3906df414875213fa2 +PODFILE CHECKSUM: 3d89d6edd11d0b95135f6e58c794a3dcb6534cb6 COCOAPODS: 1.11.3 From 61db9c472862517b6f948c71111e7a8d1570ceed Mon Sep 17 00:00:00 2001 From: Kwangsoo Yeo Date: Tue, 3 Oct 2023 17:38:25 -0700 Subject: [PATCH 2/9] update format --- binding/ios/Porcupine.swift | 78 ++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index a968809156..46ee14cc60 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -46,7 +46,11 @@ public class Porcupine { public static let frameLength = UInt32(pv_porcupine_frame_length()) public static let sampleRate = UInt32(pv_sample_rate()) public static let version = String(cString: pv_porcupine_version()) - private var sdk = "ios" + private static var sdk = "ios" + + public static func setSdk(sdk: String) { + self.sdk = sdk + } /// Constructor. /// @@ -104,7 +108,11 @@ public class Porcupine { keywordPathsArgs.map { UnsafePointer(strdup($0)) }, sensitivitiesArg, &handle) - try checkStatus(status, "Porcupine init failed") + + if status != PV_STATUS_SUCCESS { + let messageStack = getMessageStack() + throw pvStatusToPorcupineError(status, "Porcupine init failed", messageStack) + } } /// Constructor. @@ -193,10 +201,6 @@ public class Porcupine { } } - public func setSdk(sdk: String) { - self.sdk = sdk - } - /// Process a frame of audio with the wake word engine /// /// - Parameters: @@ -215,7 +219,10 @@ public class Porcupine { var result: Int32 = -1 let status = pv_porcupine_process(self.handle, pcm, &result) - try checkStatus(status, "Porcupine process failed") + if status != PV_STATUS_SUCCESS { + let messageStack = getMessageStack() + throw pvStatusToPorcupineError(status, "Porcupine process failed", messageStack) + } return result } @@ -236,48 +243,49 @@ public class Porcupine { "If this is a packaged asset, ensure you have added it to your xcode project.") } - private func checkStatus(_ status: pv_status_t, _ message: String) throws { - if status == PV_STATUS_SUCCESS { - return - } - var messageStackRef: UnsafeMutablePointer?>? - var messageStackDepth: Int32 = 0 - - let object = UnsafeRawPointer(self.handle) - pv_get_error_stack(object, &messageStackRef, &messageStackDepth) - - var messageStack: [String] = [] - while let s = messageStackRef?.pointee { - messageStack.append(String(cString: s)) - messageStackRef = messageStackRef?.advanced(by: 1) - } - + private func pvStatusToPorcupineError(_ status: pv_status_t, _ message: String, _ messageStack: [String]? = []) throws { switch status { case PV_STATUS_OUT_OF_MEMORY: - throw PorcupineMemoryError(message, messageStack) + return PorcupineMemoryError(message, messageStack) case PV_STATUS_IO_ERROR: - throw PorcupineIOError(message, messageStack) + return PorcupineIOError(message, messageStack) case PV_STATUS_INVALID_ARGUMENT: - throw PorcupineInvalidArgumentError(message, messageStack) + return PorcupineInvalidArgumentError(message, messageStack) case PV_STATUS_STOP_ITERATION: - throw PorcupineStopIterationError(message, messageStack) + return PorcupineStopIterationError(message, messageStack) case PV_STATUS_KEY_ERROR: - throw PorcupineKeyError(message, messageStack) + return PorcupineKeyError(message, messageStack) case PV_STATUS_INVALID_STATE: - throw PorcupineInvalidStateError(message, messageStack) + return PorcupineInvalidStateError(message, messageStack) case PV_STATUS_RUNTIME_ERROR: - throw PorcupineRuntimeError(message, messageStack) + return PorcupineRuntimeError(message, messageStack) case PV_STATUS_ACTIVATION_ERROR: - throw PorcupineActivationError(message, messageStack) + return PorcupineActivationError(message, messageStack) case PV_STATUS_ACTIVATION_LIMIT_REACHED: - throw PorcupineActivationLimitError(message, messageStack) + return PorcupineActivationLimitError(message, messageStack) case PV_STATUS_ACTIVATION_THROTTLED: - throw PorcupineActivationThrottledError(message, messageStack) + return PorcupineActivationThrottledError(message, messageStack) case PV_STATUS_ACTIVATION_REFUSED: - throw PorcupineActivationRefusedError(message, messageStack) + return PorcupineActivationRefusedError(message, messageStack) default: let pvStatusString = String(cString: pv_status_to_string(status)) - throw PorcupineError("\(pvStatusString): \(message)", messageStack) + return PorcupineError("\(pvStatusString): \(message)", messageStack) + } + } + + private func getMessageStack() -> [String] { + var messageStackRef: UnsafeMutablePointer?>? + var messageStackDepth: Int32 = 0 + + let object = UnsafeRawPointer(self.handle) + pv_get_error_stack(object, &messageStackRef, &messageStackDepth) + + var messageStack: [String] = [] + while let s = messageStackRef?.pointee { + messageStack.append(String(cString: s)) + messageStackRef = messageStackRef?.advanced(by: 1) } + + return messageStack } } From 0c2feef278b91029ff0103dc30a299e2f3f1c968 Mon Sep 17 00:00:00 2001 From: Ian Lavery Date: Fri, 6 Oct 2023 16:09:28 -0700 Subject: [PATCH 3/9] error stack --- binding/ios/Porcupine.swift | 17 ++++++++++------- .../PorcupineAppTestUITests.swift | 6 +++--- binding/ios/PorcupineErrors.swift | 14 ++++++-------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index 46ee14cc60..4a92ebc8dc 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -1,5 +1,5 @@ // -// Copyright 2021-2022 Picovoice Inc. +// Copyright 2021-2023 Picovoice Inc. // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on @@ -58,7 +58,7 @@ public class Porcupine { /// - accessKey: The AccessKey obtained from Picovoice Console (https://console.picovoice.ai). /// - keywordPaths: Absolute paths to keyword model files. /// - modelPath: Absolute path to file containing model parameters. - /// - sensitivities: Sensitivities for detecting keywords. Each value should be a number within [0, 1]. + /// - sensitivities: Sensitivities for detecting keywords. Each value should be a number within [0, 1]. /// A higher sensitivity results in fewer misses at the cost of increasing the false alarm rate. /// - Throws: PorcupineError public init( @@ -243,7 +243,7 @@ public class Porcupine { "If this is a packaged asset, ensure you have added it to your xcode project.") } - private func pvStatusToPorcupineError(_ status: pv_status_t, _ message: String, _ messageStack: [String]? = []) throws { + private func pvStatusToPorcupineError(_ status: pv_status_t, _ message: String, _ messageStack: [String] = []) throws { switch status { case PV_STATUS_OUT_OF_MEMORY: return PorcupineMemoryError(message, messageStack) @@ -273,19 +273,22 @@ public class Porcupine { } } - private func getMessageStack() -> [String] { + private func getErrorStack() -> [String] { var messageStackRef: UnsafeMutablePointer?>? var messageStackDepth: Int32 = 0 + let status = pv_get_error_stack(self.handle, &messageStackRef, &messageStackDepth) + if status != PV_STATUS_SUCCESS { + throw pvStatusToPorcupineError(status, "Unable to get Porcupine error state") + } - let object = UnsafeRawPointer(self.handle) - pv_get_error_stack(object, &messageStackRef, &messageStackDepth) - var messageStack: [String] = [] while let s = messageStackRef?.pointee { messageStack.append(String(cString: s)) messageStackRef = messageStackRef?.advanced(by: 1) } + pv_free_error_stack(messageStackRef) + return messageStack } } diff --git a/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift b/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift index b90e934b3f..9a9a9e695f 100644 --- a/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift +++ b/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/PorcupineAppTestUITests.swift @@ -1,5 +1,5 @@ // -// Copyright 2022 Picovoice Inc. +// Copyright 2022-2023 Picovoice Inc. // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on @@ -245,7 +245,7 @@ class PorcupineAppTestUITests: BaseTest { XCTAssert(expectedKeyword == keywordDetected) } } - + func testMessageStack() throws { var first_error: String = "" do { @@ -255,7 +255,7 @@ class PorcupineAppTestUITests: BaseTest { first_error = "\(error.localizedDescription)" XCTAssert(first_error.count < 1024) } - + do { let p = try Porcupine.init(accessKey: "invalid", keyword: Porcupine.BuiltInKeyword.porcupine) XCTAssertNil(p) diff --git a/binding/ios/PorcupineErrors.swift b/binding/ios/PorcupineErrors.swift index 65be6bdaad..309ac84886 100644 --- a/binding/ios/PorcupineErrors.swift +++ b/binding/ios/PorcupineErrors.swift @@ -1,5 +1,5 @@ // -// Copyright 2021 Picovoice Inc. +// Copyright 2021-2023 Picovoice Inc. // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on @@ -17,16 +17,14 @@ public class PorcupineError: LocalizedError { } public var errorDescription: String? { + var messageString = message if messageStack.count > 0 { - var i = 0 - let messageString = messageStack.reduce(message) { partial, current in - let reduced = partial + "\n [\(i)] \(current)" - i += 1 - return reduced + messageString += ":" + for i in 0.. Date: Fri, 6 Oct 2023 16:44:49 -0700 Subject: [PATCH 4/9] podfiles --- binding/ios/PorcupineAppTest/Podfile | 6 +++--- binding/ios/PorcupineAppTest/Podfile.lock | 6 +++--- demo/ios/BackgroundService/Podfile | 2 +- demo/ios/BackgroundService/Podfile.lock | 13 ++++++++----- demo/ios/ForegroundApp/Podfile | 2 +- demo/ios/ForegroundApp/Podfile.lock | 6 +++--- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/binding/ios/PorcupineAppTest/Podfile b/binding/ios/PorcupineAppTest/Podfile index 69a31aca3c..09cc896117 100644 --- a/binding/ios/PorcupineAppTest/Podfile +++ b/binding/ios/PorcupineAppTest/Podfile @@ -2,13 +2,13 @@ source 'https://cdn.cocoapods.org/' platform :ios, '11.0' target 'PorcupineAppTest' do - pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' + pod 'Porcupine-iOS', :podspec => 'https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec' end target 'PorcupineAppTestUITests' do - pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' + pod 'Porcupine-iOS', :podspec => 'https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec' end target 'PerformanceTest' do - pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' + pod 'Porcupine-iOS', :podspec => 'https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec' end diff --git a/binding/ios/PorcupineAppTest/Podfile.lock b/binding/ios/PorcupineAppTest/Podfile.lock index 0cac3d9190..60b12a3016 100644 --- a/binding/ios/PorcupineAppTest/Podfile.lock +++ b/binding/ios/PorcupineAppTest/Podfile.lock @@ -4,7 +4,7 @@ PODS: - ios-voice-processor (~> 1.1.0) DEPENDENCIES: - - Porcupine-iOS (from `../../../Porcupine-iOS.podspec`) + - Porcupine-iOS (from `https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec`) SPEC REPOS: trunk: @@ -12,12 +12,12 @@ SPEC REPOS: EXTERNAL SOURCES: Porcupine-iOS: - :path: "../../../Porcupine-iOS.podspec" + :podspec: https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec SPEC CHECKSUMS: ios-voice-processor: 8e32d7f980a06d392d128ef1cd19cf6ddcaca3c1 Porcupine-iOS: 517158e02ac294dda15b713a3c6f74a9e877090c -PODFILE CHECKSUM: 70f38c09353a041d84d56f94757c44b3e268f04a +PODFILE CHECKSUM: de7c831cba4f716e69f257669fad1956c7ee900b COCOAPODS: 1.11.3 diff --git a/demo/ios/BackgroundService/Podfile b/demo/ios/BackgroundService/Podfile index d92410ef53..7a71259742 100644 --- a/demo/ios/BackgroundService/Podfile +++ b/demo/ios/BackgroundService/Podfile @@ -2,6 +2,6 @@ source 'https://cdn.cocoapods.org/' platform :ios, '11.0' target 'PorcupineBackgroundServiceDemo' do - pod 'Porcupine-iOS', '~> 2.2.1' + pod 'Porcupine-iOS', :podspec => 'https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec' pod 'SwiftySound' end diff --git a/demo/ios/BackgroundService/Podfile.lock b/demo/ios/BackgroundService/Podfile.lock index 1d47c255fc..bdc5568b72 100644 --- a/demo/ios/BackgroundService/Podfile.lock +++ b/demo/ios/BackgroundService/Podfile.lock @@ -1,24 +1,27 @@ PODS: - ios-voice-processor (1.1.0) - - Porcupine-iOS (2.2.1): + - Porcupine-iOS (3.0.0): - ios-voice-processor (~> 1.1.0) - SwiftySound (1.2.0) DEPENDENCIES: - - Porcupine-iOS (~> 2.2.1) + - Porcupine-iOS (from `https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec`) - SwiftySound SPEC REPOS: trunk: - ios-voice-processor - - Porcupine-iOS - SwiftySound +EXTERNAL SOURCES: + Porcupine-iOS: + :podspec: https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec + SPEC CHECKSUMS: ios-voice-processor: 8e32d7f980a06d392d128ef1cd19cf6ddcaca3c1 - Porcupine-iOS: df8e4a63d787b6c16bd5f988fd0f2c29a249a4bd + Porcupine-iOS: 517158e02ac294dda15b713a3c6f74a9e877090c SwiftySound: 9eb28bb14edb601b40027e44319e0ef8383f88bf -PODFILE CHECKSUM: d37186b09c1e0853cbe460db0bbb3618858e6592 +PODFILE CHECKSUM: 28977669b185aa3a95aa3654db491562cca25bd3 COCOAPODS: 1.11.3 diff --git a/demo/ios/ForegroundApp/Podfile b/demo/ios/ForegroundApp/Podfile index bf9628f3ab..16ddcfe1be 100644 --- a/demo/ios/ForegroundApp/Podfile +++ b/demo/ios/ForegroundApp/Podfile @@ -2,5 +2,5 @@ source 'https://cdn.cocoapods.org/' platform :ios, '11.0' target 'PorcupineForegroundAppDemo' do - pod 'Porcupine-iOS', :path => '../../../Porcupine-iOS.podspec' + pod 'Porcupine-iOS', :podspec => 'https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec' end diff --git a/demo/ios/ForegroundApp/Podfile.lock b/demo/ios/ForegroundApp/Podfile.lock index e2830f40ae..b67cca0e34 100644 --- a/demo/ios/ForegroundApp/Podfile.lock +++ b/demo/ios/ForegroundApp/Podfile.lock @@ -4,7 +4,7 @@ PODS: - ios-voice-processor (~> 1.1.0) DEPENDENCIES: - - Porcupine-iOS (from `../../../Porcupine-iOS.podspec`) + - Porcupine-iOS (from `https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec`) SPEC REPOS: trunk: @@ -12,12 +12,12 @@ SPEC REPOS: EXTERNAL SOURCES: Porcupine-iOS: - :path: "../../../Porcupine-iOS.podspec" + :podspec: https://raw.githubusercontent.com/Picovoice/porcupine/v3.0-ios/binding/ios/Porcupine-iOS.podspec SPEC CHECKSUMS: ios-voice-processor: 8e32d7f980a06d392d128ef1cd19cf6ddcaca3c1 Porcupine-iOS: 517158e02ac294dda15b713a3c6f74a9e877090c -PODFILE CHECKSUM: 3d89d6edd11d0b95135f6e58c794a3dcb6534cb6 +PODFILE CHECKSUM: 783e79b39a3251a402d7c4f12561db4ae8d721b6 COCOAPODS: 1.11.3 From 1ad2ee2ec47fa5c77a842c003aa00c2f36e81843 Mon Sep 17 00:00:00 2001 From: Ian Lavery Date: Fri, 6 Oct 2023 17:15:34 -0700 Subject: [PATCH 5/9] fix --- binding/ios/Porcupine.swift | 65 ++++++++++--------- .../PorcupineAppTest/ViewController.swift | 8 +-- .../PorcupineAppTestUITests/BaseTest.swift | 6 +- 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index 4a92ebc8dc..0d7a904653 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -110,7 +110,7 @@ public class Porcupine { &handle) if status != PV_STATUS_SUCCESS { - let messageStack = getMessageStack() + let messageStack = try getMessageStack() throw pvStatusToPorcupineError(status, "Porcupine init failed", messageStack) } } @@ -220,7 +220,7 @@ public class Porcupine { var result: Int32 = -1 let status = pv_porcupine_process(self.handle, pcm, &result) if status != PV_STATUS_SUCCESS { - let messageStack = getMessageStack() + let messageStack = try getMessageStack() throw pvStatusToPorcupineError(status, "Porcupine process failed", messageStack) } return result @@ -243,40 +243,43 @@ public class Porcupine { "If this is a packaged asset, ensure you have added it to your xcode project.") } - private func pvStatusToPorcupineError(_ status: pv_status_t, _ message: String, _ messageStack: [String] = []) throws { + private func pvStatusToPorcupineError( + _ status: pv_status_t, + _ message: String, + _ messageStack: [String] = []) -> PorcupineError { switch status { - case PV_STATUS_OUT_OF_MEMORY: - return PorcupineMemoryError(message, messageStack) - case PV_STATUS_IO_ERROR: - return PorcupineIOError(message, messageStack) - case PV_STATUS_INVALID_ARGUMENT: - return PorcupineInvalidArgumentError(message, messageStack) - case PV_STATUS_STOP_ITERATION: - return PorcupineStopIterationError(message, messageStack) - case PV_STATUS_KEY_ERROR: - return PorcupineKeyError(message, messageStack) - case PV_STATUS_INVALID_STATE: - return PorcupineInvalidStateError(message, messageStack) - case PV_STATUS_RUNTIME_ERROR: - return PorcupineRuntimeError(message, messageStack) - case PV_STATUS_ACTIVATION_ERROR: - return PorcupineActivationError(message, messageStack) - case PV_STATUS_ACTIVATION_LIMIT_REACHED: - return PorcupineActivationLimitError(message, messageStack) - case PV_STATUS_ACTIVATION_THROTTLED: - return PorcupineActivationThrottledError(message, messageStack) - case PV_STATUS_ACTIVATION_REFUSED: - return PorcupineActivationRefusedError(message, messageStack) - default: - let pvStatusString = String(cString: pv_status_to_string(status)) - return PorcupineError("\(pvStatusString): \(message)", messageStack) + case PV_STATUS_OUT_OF_MEMORY: + return PorcupineMemoryError(message, messageStack) + case PV_STATUS_IO_ERROR: + return PorcupineIOError(message, messageStack) + case PV_STATUS_INVALID_ARGUMENT: + return PorcupineInvalidArgumentError(message, messageStack) + case PV_STATUS_STOP_ITERATION: + return PorcupineStopIterationError(message, messageStack) + case PV_STATUS_KEY_ERROR: + return PorcupineKeyError(message, messageStack) + case PV_STATUS_INVALID_STATE: + return PorcupineInvalidStateError(message, messageStack) + case PV_STATUS_RUNTIME_ERROR: + return PorcupineRuntimeError(message, messageStack) + case PV_STATUS_ACTIVATION_ERROR: + return PorcupineActivationError(message, messageStack) + case PV_STATUS_ACTIVATION_LIMIT_REACHED: + return PorcupineActivationLimitError(message, messageStack) + case PV_STATUS_ACTIVATION_THROTTLED: + return PorcupineActivationThrottledError(message, messageStack) + case PV_STATUS_ACTIVATION_REFUSED: + return PorcupineActivationRefusedError(message, messageStack) + default: + let pvStatusString = String(cString: pv_status_to_string(status)) + return PorcupineError("\(pvStatusString): \(message)", messageStack) } } - private func getErrorStack() -> [String] { - var messageStackRef: UnsafeMutablePointer?>? + private func getMessageStack() throws -> [String] { + var messageStackRef: UnsafeMutablePointer?>? var messageStackDepth: Int32 = 0 - let status = pv_get_error_stack(self.handle, &messageStackRef, &messageStackDepth) + let status = pv_get_error_stack(&messageStackRef, &messageStackDepth) if status != PV_STATUS_SUCCESS { throw pvStatusToPorcupineError(status, "Unable to get Porcupine error state") } diff --git a/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift b/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift index 8e615640eb..0d87e60971 100644 --- a/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift +++ b/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift @@ -9,10 +9,4 @@ import UIKit -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - } - -} +class ViewController: UIViewController { } diff --git a/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/BaseTest.swift b/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/BaseTest.swift index e3a09e7301..e12250dc81 100644 --- a/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/BaseTest.swift +++ b/binding/ios/PorcupineAppTest/PorcupineAppTestUITests/BaseTest.swift @@ -1,5 +1,5 @@ // -// Copyright 2022 Picovoice Inc. +// Copyright 2022-2023 Picovoice Inc. // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on @@ -20,10 +20,6 @@ class BaseTest: XCTestCase { continueAfterFailure = false } - override func tearDown() { - super.tearDown() - } - func processFile(p: Porcupine, testAudioURL: URL) throws -> [Int32] { let data = try Data(contentsOf: testAudioURL) let frameLengthBytes = Int(Porcupine.frameLength) * 2 From 6dbdbbcca05a17fb47f427c9545faa8a5002f051 Mon Sep 17 00:00:00 2001 From: Ian Lavery Date: Fri, 6 Oct 2023 17:17:16 -0700 Subject: [PATCH 6/9] style --- binding/ios/Porcupine.swift | 50 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index 0d7a904653..5b0560a89d 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -248,31 +248,31 @@ public class Porcupine { _ message: String, _ messageStack: [String] = []) -> PorcupineError { switch status { - case PV_STATUS_OUT_OF_MEMORY: - return PorcupineMemoryError(message, messageStack) - case PV_STATUS_IO_ERROR: - return PorcupineIOError(message, messageStack) - case PV_STATUS_INVALID_ARGUMENT: - return PorcupineInvalidArgumentError(message, messageStack) - case PV_STATUS_STOP_ITERATION: - return PorcupineStopIterationError(message, messageStack) - case PV_STATUS_KEY_ERROR: - return PorcupineKeyError(message, messageStack) - case PV_STATUS_INVALID_STATE: - return PorcupineInvalidStateError(message, messageStack) - case PV_STATUS_RUNTIME_ERROR: - return PorcupineRuntimeError(message, messageStack) - case PV_STATUS_ACTIVATION_ERROR: - return PorcupineActivationError(message, messageStack) - case PV_STATUS_ACTIVATION_LIMIT_REACHED: - return PorcupineActivationLimitError(message, messageStack) - case PV_STATUS_ACTIVATION_THROTTLED: - return PorcupineActivationThrottledError(message, messageStack) - case PV_STATUS_ACTIVATION_REFUSED: - return PorcupineActivationRefusedError(message, messageStack) - default: - let pvStatusString = String(cString: pv_status_to_string(status)) - return PorcupineError("\(pvStatusString): \(message)", messageStack) + case PV_STATUS_OUT_OF_MEMORY: + return PorcupineMemoryError(message, messageStack) + case PV_STATUS_IO_ERROR: + return PorcupineIOError(message, messageStack) + case PV_STATUS_INVALID_ARGUMENT: + return PorcupineInvalidArgumentError(message, messageStack) + case PV_STATUS_STOP_ITERATION: + return PorcupineStopIterationError(message, messageStack) + case PV_STATUS_KEY_ERROR: + return PorcupineKeyError(message, messageStack) + case PV_STATUS_INVALID_STATE: + return PorcupineInvalidStateError(message, messageStack) + case PV_STATUS_RUNTIME_ERROR: + return PorcupineRuntimeError(message, messageStack) + case PV_STATUS_ACTIVATION_ERROR: + return PorcupineActivationError(message, messageStack) + case PV_STATUS_ACTIVATION_LIMIT_REACHED: + return PorcupineActivationLimitError(message, messageStack) + case PV_STATUS_ACTIVATION_THROTTLED: + return PorcupineActivationThrottledError(message, messageStack) + case PV_STATUS_ACTIVATION_REFUSED: + return PorcupineActivationRefusedError(message, messageStack) + default: + let pvStatusString = String(cString: pv_status_to_string(status)) + return PorcupineError("\(pvStatusString): \(message)", messageStack) } } From 0a9d085ec5c48d30675c00f2b9ef4d2f7355c1f4 Mon Sep 17 00:00:00 2001 From: Ian Lavery Date: Tue, 10 Oct 2023 12:24:30 -0700 Subject: [PATCH 7/9] fix message stack --- binding/ios/Porcupine.swift | 55 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index 5b0560a89d..aa9205f55b 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -248,31 +248,31 @@ public class Porcupine { _ message: String, _ messageStack: [String] = []) -> PorcupineError { switch status { - case PV_STATUS_OUT_OF_MEMORY: - return PorcupineMemoryError(message, messageStack) - case PV_STATUS_IO_ERROR: - return PorcupineIOError(message, messageStack) - case PV_STATUS_INVALID_ARGUMENT: - return PorcupineInvalidArgumentError(message, messageStack) - case PV_STATUS_STOP_ITERATION: - return PorcupineStopIterationError(message, messageStack) - case PV_STATUS_KEY_ERROR: - return PorcupineKeyError(message, messageStack) - case PV_STATUS_INVALID_STATE: - return PorcupineInvalidStateError(message, messageStack) - case PV_STATUS_RUNTIME_ERROR: - return PorcupineRuntimeError(message, messageStack) - case PV_STATUS_ACTIVATION_ERROR: - return PorcupineActivationError(message, messageStack) - case PV_STATUS_ACTIVATION_LIMIT_REACHED: - return PorcupineActivationLimitError(message, messageStack) - case PV_STATUS_ACTIVATION_THROTTLED: - return PorcupineActivationThrottledError(message, messageStack) - case PV_STATUS_ACTIVATION_REFUSED: - return PorcupineActivationRefusedError(message, messageStack) - default: - let pvStatusString = String(cString: pv_status_to_string(status)) - return PorcupineError("\(pvStatusString): \(message)", messageStack) + case PV_STATUS_OUT_OF_MEMORY: + return PorcupineMemoryError(message, messageStack) + case PV_STATUS_IO_ERROR: + return PorcupineIOError(message, messageStack) + case PV_STATUS_INVALID_ARGUMENT: + return PorcupineInvalidArgumentError(message, messageStack) + case PV_STATUS_STOP_ITERATION: + return PorcupineStopIterationError(message, messageStack) + case PV_STATUS_KEY_ERROR: + return PorcupineKeyError(message, messageStack) + case PV_STATUS_INVALID_STATE: + return PorcupineInvalidStateError(message, messageStack) + case PV_STATUS_RUNTIME_ERROR: + return PorcupineRuntimeError(message, messageStack) + case PV_STATUS_ACTIVATION_ERROR: + return PorcupineActivationError(message, messageStack) + case PV_STATUS_ACTIVATION_LIMIT_REACHED: + return PorcupineActivationLimitError(message, messageStack) + case PV_STATUS_ACTIVATION_THROTTLED: + return PorcupineActivationThrottledError(message, messageStack) + case PV_STATUS_ACTIVATION_REFUSED: + return PorcupineActivationRefusedError(message, messageStack) + default: + let pvStatusString = String(cString: pv_status_to_string(status)) + return PorcupineError("\(pvStatusString): \(message)", messageStack) } } @@ -285,9 +285,8 @@ public class Porcupine { } var messageStack: [String] = [] - while let s = messageStackRef?.pointee { - messageStack.append(String(cString: s)) - messageStackRef = messageStackRef?.advanced(by: 1) + for i in 0.. Date: Tue, 10 Oct 2023 12:47:06 -0700 Subject: [PATCH 8/9] style --- binding/ios/Porcupine.swift | 50 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/binding/ios/Porcupine.swift b/binding/ios/Porcupine.swift index aa9205f55b..031b18de9e 100644 --- a/binding/ios/Porcupine.swift +++ b/binding/ios/Porcupine.swift @@ -248,31 +248,31 @@ public class Porcupine { _ message: String, _ messageStack: [String] = []) -> PorcupineError { switch status { - case PV_STATUS_OUT_OF_MEMORY: - return PorcupineMemoryError(message, messageStack) - case PV_STATUS_IO_ERROR: - return PorcupineIOError(message, messageStack) - case PV_STATUS_INVALID_ARGUMENT: - return PorcupineInvalidArgumentError(message, messageStack) - case PV_STATUS_STOP_ITERATION: - return PorcupineStopIterationError(message, messageStack) - case PV_STATUS_KEY_ERROR: - return PorcupineKeyError(message, messageStack) - case PV_STATUS_INVALID_STATE: - return PorcupineInvalidStateError(message, messageStack) - case PV_STATUS_RUNTIME_ERROR: - return PorcupineRuntimeError(message, messageStack) - case PV_STATUS_ACTIVATION_ERROR: - return PorcupineActivationError(message, messageStack) - case PV_STATUS_ACTIVATION_LIMIT_REACHED: - return PorcupineActivationLimitError(message, messageStack) - case PV_STATUS_ACTIVATION_THROTTLED: - return PorcupineActivationThrottledError(message, messageStack) - case PV_STATUS_ACTIVATION_REFUSED: - return PorcupineActivationRefusedError(message, messageStack) - default: - let pvStatusString = String(cString: pv_status_to_string(status)) - return PorcupineError("\(pvStatusString): \(message)", messageStack) + case PV_STATUS_OUT_OF_MEMORY: + return PorcupineMemoryError(message, messageStack) + case PV_STATUS_IO_ERROR: + return PorcupineIOError(message, messageStack) + case PV_STATUS_INVALID_ARGUMENT: + return PorcupineInvalidArgumentError(message, messageStack) + case PV_STATUS_STOP_ITERATION: + return PorcupineStopIterationError(message, messageStack) + case PV_STATUS_KEY_ERROR: + return PorcupineKeyError(message, messageStack) + case PV_STATUS_INVALID_STATE: + return PorcupineInvalidStateError(message, messageStack) + case PV_STATUS_RUNTIME_ERROR: + return PorcupineRuntimeError(message, messageStack) + case PV_STATUS_ACTIVATION_ERROR: + return PorcupineActivationError(message, messageStack) + case PV_STATUS_ACTIVATION_LIMIT_REACHED: + return PorcupineActivationLimitError(message, messageStack) + case PV_STATUS_ACTIVATION_THROTTLED: + return PorcupineActivationThrottledError(message, messageStack) + case PV_STATUS_ACTIVATION_REFUSED: + return PorcupineActivationRefusedError(message, messageStack) + default: + let pvStatusString = String(cString: pv_status_to_string(status)) + return PorcupineError("\(pvStatusString): \(message)", messageStack) } } From d2f7556180dc64bcc408781f69d7b6b354b2fd93 Mon Sep 17 00:00:00 2001 From: Ian Lavery Date: Tue, 10 Oct 2023 13:57:39 -0700 Subject: [PATCH 9/9] improve error message --- .../ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift | 2 +- .../PorcupineBackgroundServiceDemo/ViewController.swift | 2 +- .../PorcupineForegroundAppDemo/ViewController.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift b/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift index 0d87e60971..f37763087d 100644 --- a/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift +++ b/binding/ios/PorcupineAppTest/PorcupineAppTest/ViewController.swift @@ -1,5 +1,5 @@ // -// Copyright 2022 Picovoice Inc. +// Copyright 2022-2023 Picovoice Inc. // You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE" // file accompanying this source. // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on diff --git a/demo/ios/BackgroundService/PorcupineBackgroundServiceDemo/ViewController.swift b/demo/ios/BackgroundService/PorcupineBackgroundServiceDemo/ViewController.swift index ea51631af4..3b15635cfb 100644 --- a/demo/ios/BackgroundService/PorcupineBackgroundServiceDemo/ViewController.swift +++ b/demo/ios/BackgroundService/PorcupineBackgroundServiceDemo/ViewController.swift @@ -85,7 +85,7 @@ class ViewController: UIViewController, UITextViewDelegate { startButton.setTitle("STOP", for: UIControl.State.normal) } catch let error as PorcupineInvalidArgumentError { - showErrorAlert(message: "\(error.localizedDescription)\nEnsure your accessKey '\(accessKey)' is valid") + showErrorAlert(message: "\(error.localizedDescription)") } catch is PorcupineActivationError { showErrorAlert(message: "AccessKey activation error") } catch is PorcupineActivationRefusedError { diff --git a/demo/ios/ForegroundApp/PorcupineForegroundAppDemo/ViewController.swift b/demo/ios/ForegroundApp/PorcupineForegroundAppDemo/ViewController.swift index a82282ae56..2bbb8b7e86 100644 --- a/demo/ios/ForegroundApp/PorcupineForegroundAppDemo/ViewController.swift +++ b/demo/ios/ForegroundApp/PorcupineForegroundAppDemo/ViewController.swift @@ -164,7 +164,7 @@ class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSo isListening = true startButton.setTitle("STOP", for: UIControl.State.normal) } catch let error as PorcupineInvalidArgumentError { - showErrorAlert("\(error.localizedDescription)\nEnsure your accessKey '\(accessKey)' is valid") + showErrorAlert("\(error.localizedDescription)") } catch is PorcupineActivationError { showErrorAlert("AccessKey activation error") } catch is PorcupineActivationRefusedError {