在 iOS 8 上使用私有语音识别框架
Work with private Speech Recognition Frameworks on iOS 8
我需要为个人项目的应用程序添加语音识别。
我需要 iOS built-in 语音识别框架,因为它快速、准确,还可以识别您的联系人姓名和其他有关您自己的信息。
到目前为止,我想我已经找到了包含 headers 的框架,用于 iOS 8 上的语音识别: SAObjects.framework
我得到了 Github 的 headers 并在我的 Xcode 项目中成功添加了它们。
目前我试过的 headers 是这些:
<SAObjects/SASRecognition.h>
<SAObjects/SASStartSpeechDictation.h>
<SAObjects/SASSpeechRecognized.h>
但是,我不确定如何与他们合作。例如,有两种可能的方法可以触发语音识别:
SASStartSpeechDictation *object1 = [SASStartSpeechDictation startSpeechDictation];
SASSpeechRecognized *object2 = [SASSpeechRecognized speechRecognized];
不过,当我调试它时,我在这些 objects 中找不到任何字符串。所以,显然出了点问题。 也许我需要设置一个通知观察者?
另一个解决方案可能是开始听写(通过键盘)
到隐藏的文本字段(不显示键盘)。
就像越狱设备的 Activator 操作一样,如果您熟悉的话。
但是没找到可以启动Keyboard听写的方法,或者Activator动作源码找找看。
也许有人试验过这些东西可以给我一些帮助?
如果您需要有关此问题的更多信息,请告诉我:)
非常感谢!
所以,我设法自己找到了答案。我幸运地找到了一个包含一些有用代码的 Github 仓库:https://github.com/erica/useful-things
我找到的代码在appstore unsafepack/DictationHelper目录下。此代码有助于使用 UIDictationController 并启动和停止听写,并获取文本值。 当然,没有任何文本字段...
重要提示:为了让它工作,你需要有 headers UIKit 框架,link 目标框架和在项目中导入它们!
但是,我稍微修改了代码,因为示例代码只能在特定时间段内使用。我需要按一个按钮停止说话。
这是修改后的代码,供以后有兴趣的人参考:
DicationHelper.h:
/*
Erica Sadun, http://ericasadun.com
NOT APP STORE SAFE BUT HANDY
Siri-ready devices only. Will not work in simulator.
Example:
[SpeechHelper speakModalString:@"Please say something"];
[[DictationHelper sharedInstance] dictateWithDuration:5.0f completion:^(NSString *dictationString) {
if (dictationString)
NSLog(@"You said:'%@'", dictationString);
else
NSLog(@"No response");}];
//-> OR: (My modification)
[SpeechHelper speakModalString:@"Please say something"];
[[DictationHelper sharedInstance] startDictation:0 completion:^(NSString *dictationString) {
if (dictationString)
NSLog(@"You said:'%@'", dictationString);
else
NSLog(@"No response");}];
// Then you need to call this to stop the Dictation: [[DictationHelper sharedInstance] stopDictation]
*/
#import <UIKit/UIKit.h>
//#import <Foundation/Foundation.h>
extern NSString *const DictationStringResults;
typedef void (^DictationBlock)(NSString *dictationString);
@interface DictationHelper : NSObject
+ (instancetype) sharedInstance;
- (void) dictateWithDuration: (CGFloat) duration;
- (void) dictateWithDuration: (CGFloat) duration completion:(DictationBlock) completionBlock;
-(void) startDictation:(CGFloat) whatever completion:(DictationBlock) completionBlock;
-(void) stopDictationWithFallback;
@property (nonatomic, readonly) BOOL inUse;
@end
DictationHelper.m
/*
Erica Sadun, http://ericasadun.com
NOT APP STORE SAFE BUT HANDY
Siri-ready devices only. Will not work in simulator.
*/
#import "DictationHelper.h"
#define MAKELIVE(_CLASSNAME_) Class _CLASSNAME_ = NSClassFromString((NSString *)CFSTR(#_CLASSNAME_));
NSString *const DictationStringResults = @"Dictation String Results";
static DictationHelper *sharedInstance = nil;
@class UIDictationController;
@interface UIDictationController
+ (UIDictationController *) sharedInstance;
- (void) startDictation;
- (void) stopDictation;
- (void) preheatIfNecessary;
@end;
@interface DictationHelper () <UITextFieldDelegate>
@end
@implementation DictationHelper
{
UITextField *secretTextField;
id dictationController;
DictationBlock completion;
BOOL handled;
}
- (void) preheat
{
if (!secretTextField)
{
secretTextField = [[UITextField alloc] initWithFrame:CGRectZero];
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[window addSubview:secretTextField];
secretTextField.inputView = [[UIView alloc] init];
secretTextField.delegate = self;
}
if (!dictationController)
{
MAKELIVE(UIDictationController);
dictationController = [UIDictationController sharedInstance];
[dictationController preheatIfNecessary];
}
}
+ (instancetype) sharedInstance
{
if (!sharedInstance)
{
sharedInstance = [[self alloc] init];
[sharedInstance preheat];
}
return sharedInstance;
}
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *tftext = textField.text;
tftext = [tftext stringByReplacingCharactersInRange:range withString:string];
[[NSNotificationCenter defaultCenter] postNotificationName:DictationStringResults object:tftext];
if (completion) completion(tftext);
// Treat this dictation as handled
handled = YES;
_inUse = NO;
completion = nil;
// Resign first responder
[textField resignFirstResponder];
return YES;
}
- (void) fallback
{
// 1. Test completion
if (!completion) return;
// 2. Check for handled
if (handled)
{
_inUse = NO;
handled = NO;
return;
}
// 3. Assume the dictation didn't work
completion(nil);
// 4. Reset everything
handled = NO;
_inUse = NO;
completion = nil;
// 5. Resign first responder
[secretTextField resignFirstResponder];
}
-(void) startDictation:(CGFloat) whatever completion:(DictationBlock) completionBlock{
if (completionBlock) completion = completionBlock;
if (_inUse)
{
NSLog(@"Error: Dictation Helper already in use");
return;
}
_inUse = YES;
handled = NO;
secretTextField.text = @"";
[secretTextField becomeFirstResponder];
[[UIDevice currentDevice] playInputClick];
[dictationController startDictation];
}
- (void) dictateWithDuration: (CGFloat) numberOfSeconds
{
if (_inUse)
{
NSLog(@"Error: Dictation Helper already in use");
return;
}
_inUse = YES;
handled = NO;
secretTextField.text = @"";
[secretTextField becomeFirstResponder];
[[UIDevice currentDevice] playInputClick];
[dictationController startDictation];
[self performSelector:@selector(stopDictation) withObject:nil afterDelay:numberOfSeconds];
[self performSelector:@selector(fallback) withObject:nil afterDelay:numberOfSeconds + 1.0f];
}
- (void) dictateWithDuration: (CGFloat) duration completion:(DictationBlock) completionBlock
{
if (completionBlock) completion = completionBlock;
[self dictateWithDuration:duration];
}
- (void) stopDictation
{
[dictationController stopDictation];
}
- (void) stopDictationWithFallback
{
[self performSelector:@selector(stopDictation) withObject:nil afterDelay:0.0];
[self performSelector:@selector(fallback) withObject:nil afterDelay:1.0f];
}
@end
#undef MAKELIVE
我需要为个人项目的应用程序添加语音识别。
我需要 iOS built-in 语音识别框架,因为它快速、准确,还可以识别您的联系人姓名和其他有关您自己的信息。
到目前为止,我想我已经找到了包含 headers 的框架,用于 iOS 8 上的语音识别: SAObjects.framework 我得到了 Github 的 headers 并在我的 Xcode 项目中成功添加了它们。 目前我试过的 headers 是这些:
<SAObjects/SASRecognition.h>
<SAObjects/SASStartSpeechDictation.h>
<SAObjects/SASSpeechRecognized.h>
但是,我不确定如何与他们合作。例如,有两种可能的方法可以触发语音识别:
SASStartSpeechDictation *object1 = [SASStartSpeechDictation startSpeechDictation];
SASSpeechRecognized *object2 = [SASSpeechRecognized speechRecognized];
不过,当我调试它时,我在这些 objects 中找不到任何字符串。所以,显然出了点问题。 也许我需要设置一个通知观察者?
另一个解决方案可能是开始听写(通过键盘) 到隐藏的文本字段(不显示键盘)。 就像越狱设备的 Activator 操作一样,如果您熟悉的话。 但是没找到可以启动Keyboard听写的方法,或者Activator动作源码找找看。
也许有人试验过这些东西可以给我一些帮助?
如果您需要有关此问题的更多信息,请告诉我:)
非常感谢!
所以,我设法自己找到了答案。我幸运地找到了一个包含一些有用代码的 Github 仓库:https://github.com/erica/useful-things
我找到的代码在appstore unsafepack/DictationHelper目录下。此代码有助于使用 UIDictationController 并启动和停止听写,并获取文本值。 当然,没有任何文本字段...
重要提示:为了让它工作,你需要有 headers UIKit 框架,link 目标框架和在项目中导入它们!
但是,我稍微修改了代码,因为示例代码只能在特定时间段内使用。我需要按一个按钮停止说话。 这是修改后的代码,供以后有兴趣的人参考:
DicationHelper.h:
/*
Erica Sadun, http://ericasadun.com
NOT APP STORE SAFE BUT HANDY
Siri-ready devices only. Will not work in simulator.
Example:
[SpeechHelper speakModalString:@"Please say something"];
[[DictationHelper sharedInstance] dictateWithDuration:5.0f completion:^(NSString *dictationString) {
if (dictationString)
NSLog(@"You said:'%@'", dictationString);
else
NSLog(@"No response");}];
//-> OR: (My modification)
[SpeechHelper speakModalString:@"Please say something"];
[[DictationHelper sharedInstance] startDictation:0 completion:^(NSString *dictationString) {
if (dictationString)
NSLog(@"You said:'%@'", dictationString);
else
NSLog(@"No response");}];
// Then you need to call this to stop the Dictation: [[DictationHelper sharedInstance] stopDictation]
*/
#import <UIKit/UIKit.h>
//#import <Foundation/Foundation.h>
extern NSString *const DictationStringResults;
typedef void (^DictationBlock)(NSString *dictationString);
@interface DictationHelper : NSObject
+ (instancetype) sharedInstance;
- (void) dictateWithDuration: (CGFloat) duration;
- (void) dictateWithDuration: (CGFloat) duration completion:(DictationBlock) completionBlock;
-(void) startDictation:(CGFloat) whatever completion:(DictationBlock) completionBlock;
-(void) stopDictationWithFallback;
@property (nonatomic, readonly) BOOL inUse;
@end
DictationHelper.m
/*
Erica Sadun, http://ericasadun.com
NOT APP STORE SAFE BUT HANDY
Siri-ready devices only. Will not work in simulator.
*/
#import "DictationHelper.h"
#define MAKELIVE(_CLASSNAME_) Class _CLASSNAME_ = NSClassFromString((NSString *)CFSTR(#_CLASSNAME_));
NSString *const DictationStringResults = @"Dictation String Results";
static DictationHelper *sharedInstance = nil;
@class UIDictationController;
@interface UIDictationController
+ (UIDictationController *) sharedInstance;
- (void) startDictation;
- (void) stopDictation;
- (void) preheatIfNecessary;
@end;
@interface DictationHelper () <UITextFieldDelegate>
@end
@implementation DictationHelper
{
UITextField *secretTextField;
id dictationController;
DictationBlock completion;
BOOL handled;
}
- (void) preheat
{
if (!secretTextField)
{
secretTextField = [[UITextField alloc] initWithFrame:CGRectZero];
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[window addSubview:secretTextField];
secretTextField.inputView = [[UIView alloc] init];
secretTextField.delegate = self;
}
if (!dictationController)
{
MAKELIVE(UIDictationController);
dictationController = [UIDictationController sharedInstance];
[dictationController preheatIfNecessary];
}
}
+ (instancetype) sharedInstance
{
if (!sharedInstance)
{
sharedInstance = [[self alloc] init];
[sharedInstance preheat];
}
return sharedInstance;
}
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *tftext = textField.text;
tftext = [tftext stringByReplacingCharactersInRange:range withString:string];
[[NSNotificationCenter defaultCenter] postNotificationName:DictationStringResults object:tftext];
if (completion) completion(tftext);
// Treat this dictation as handled
handled = YES;
_inUse = NO;
completion = nil;
// Resign first responder
[textField resignFirstResponder];
return YES;
}
- (void) fallback
{
// 1. Test completion
if (!completion) return;
// 2. Check for handled
if (handled)
{
_inUse = NO;
handled = NO;
return;
}
// 3. Assume the dictation didn't work
completion(nil);
// 4. Reset everything
handled = NO;
_inUse = NO;
completion = nil;
// 5. Resign first responder
[secretTextField resignFirstResponder];
}
-(void) startDictation:(CGFloat) whatever completion:(DictationBlock) completionBlock{
if (completionBlock) completion = completionBlock;
if (_inUse)
{
NSLog(@"Error: Dictation Helper already in use");
return;
}
_inUse = YES;
handled = NO;
secretTextField.text = @"";
[secretTextField becomeFirstResponder];
[[UIDevice currentDevice] playInputClick];
[dictationController startDictation];
}
- (void) dictateWithDuration: (CGFloat) numberOfSeconds
{
if (_inUse)
{
NSLog(@"Error: Dictation Helper already in use");
return;
}
_inUse = YES;
handled = NO;
secretTextField.text = @"";
[secretTextField becomeFirstResponder];
[[UIDevice currentDevice] playInputClick];
[dictationController startDictation];
[self performSelector:@selector(stopDictation) withObject:nil afterDelay:numberOfSeconds];
[self performSelector:@selector(fallback) withObject:nil afterDelay:numberOfSeconds + 1.0f];
}
- (void) dictateWithDuration: (CGFloat) duration completion:(DictationBlock) completionBlock
{
if (completionBlock) completion = completionBlock;
[self dictateWithDuration:duration];
}
- (void) stopDictation
{
[dictationController stopDictation];
}
- (void) stopDictationWithFallback
{
[self performSelector:@selector(stopDictation) withObject:nil afterDelay:0.0];
[self performSelector:@selector(fallback) withObject:nil afterDelay:1.0f];
}
@end
#undef MAKELIVE