mirror of
https://github.com/ZaidElkurdi/AssistantPlus.git
synced 2025-01-22 11:28:31 +00:00
- 1.2.0
This commit is contained in:
parent
1f95829caa
commit
61013b77a1
@ -1 +1 @@
|
||||
1
|
||||
38
|
Binary file not shown.
@ -22,9 +22,17 @@ static BOOL defaultHandling = YES;
|
||||
static AFConnection *currConnection;
|
||||
static APPluginSystem *pluginManager;
|
||||
static BOOL hasLoadedSnippets = NO;
|
||||
static APSession *previousSession;
|
||||
|
||||
BOOL shouldHandleRequest(NSString *text, APSession *currSession) {
|
||||
pluginManager = [[%c(APSpringboardUtils) sharedAPUtils] getPluginManager];
|
||||
if (previousSession && [previousSession isListeningAfterSpeaking]) {
|
||||
NSLog(@"AP: Using previous session");
|
||||
currSession = previousSession;
|
||||
} else {
|
||||
NSLog(@"AP: Creating new session");
|
||||
previousSession = currSession;
|
||||
}
|
||||
NSArray *lowerCaseArr = [[text componentsSeparatedByString: @" "] valueForKey:@"lowercaseString"];
|
||||
NSSet *tokens = [NSSet setWithArray:lowerCaseArr];
|
||||
BOOL pluginWillHandle = [pluginManager handleCommand:text withTokens:tokens withSession:currSession];
|
||||
@ -133,6 +141,14 @@ BOOL shouldHandleRequest(NSString *text, APSession *currSession) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)endSession {
|
||||
if (pluginManager) {
|
||||
[pluginManager assistantWasDismissed];
|
||||
}
|
||||
previousSession = nil;
|
||||
%orig;
|
||||
}
|
||||
|
||||
%end
|
||||
|
||||
%hook AFConnectionClientServiceDelegate
|
||||
@ -151,7 +167,6 @@ BOOL shouldHandleRequest(NSString *text, APSession *currSession) {
|
||||
}
|
||||
|
||||
NSLog(@"AP Starting Speech Query: %@", phraseBuilder);
|
||||
|
||||
AFConnection *connection = MSHookIvar<AFConnection*>(self, "_connection");
|
||||
APSession *currSession = [APSession sessionWithConnection:connection];
|
||||
if (shouldHandleRequest(phraseBuilder, currSession)) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
include theos/makefiles/common.mk
|
||||
|
||||
export ARCHS = armv7 armv7s arm64
|
||||
export TARGET = iphone:clang:latest:8.0
|
||||
export TARGET_IPHONEOS_DEPLOYMENT_VERSION = 8.0
|
||||
export SDKVERSION=8.1
|
||||
export TARGET = iphone:clang:latest:8.4
|
||||
export TARGET_IPHONEOS_DEPLOYMENT_VERSION = 8.4
|
||||
export SDKVERSION=8.4
|
||||
|
||||
TWEAK_NAME = Assistant+
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +1,8 @@
|
||||
include theos/makefiles/common.mk
|
||||
|
||||
export ARCHS = armv7 arm64
|
||||
export TARGET = iphone:clang:latest:8.0
|
||||
export SDKVERSION=8.1
|
||||
export TARGET = iphone:clang:latest:8.4
|
||||
export SDKVERSION=8.4
|
||||
|
||||
APPLICATION_NAME = AssistantPlusApp
|
||||
AssistantPlusApp_FILES = main.m AppDelegate.m MainViewController.m APActivatorListener.m ActivatorListenersViewController.m ListenerDetailViewController.m CustomReplyDetailViewController.m CustomRepliesViewController.m APCustomReply.m PluginsViewController.m CaptureGroupCommandDetailViewController.m CaptureGroupCommandsViewController.m APCaptureGroupCommand.m
|
||||
|
Binary file not shown.
@ -28,6 +28,7 @@
|
||||
|
||||
- (id)initWithFilePath:(NSURL*)filePath andName:(NSString*)name;
|
||||
- (BOOL)handleSpeech:(NSString*)text withTokens:(NSSet*)tokens withSession:(id<APSiriSession>)session;
|
||||
- (void)handleReply:(NSString*)text withTokens:(NSSet*)tokens withSession:(id<APSiriSession>)session;
|
||||
/// Register a command class
|
||||
-(BOOL)registerCommand:(Class)cls;
|
||||
/// Register a snippet class
|
||||
@ -36,4 +37,6 @@
|
||||
- (NSSet*)getRegisteredSnippets;
|
||||
- (NSArray*)getRegisteredCommands;
|
||||
|
||||
- (void)assistantWasDismissed;
|
||||
|
||||
@end
|
||||
|
@ -92,6 +92,24 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)handleReply:(NSString*)text withTokens:(NSSet*)tokens withSession:(id<APSiriSession>)session {
|
||||
for (NSObject<APPluginCommand>* cmd in commands) {
|
||||
if ([cmd respondsToSelector:@selector(handleReply:withTokens:withSession:)]) {
|
||||
[cmd handleReply:text withTokens:tokens withSession:session];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Notifications
|
||||
|
||||
- (void)assistantWasDismissed {
|
||||
for (NSObject<APPluginCommand>* cmd in commands) {
|
||||
if ([cmd respondsToSelector:@selector(assistantWasDismissed)]) {
|
||||
[cmd assistantWasDismissed];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Snippet Presentation
|
||||
|
||||
-(NSObject<APPluginSnippet>*)allocSnippet:(NSString*)snippetClass properties:(NSDictionary *)props {
|
||||
@ -154,5 +172,4 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
@ -16,13 +16,14 @@
|
||||
NSMutableArray *captureGroupCommandsArray;
|
||||
}
|
||||
|
||||
@property (strong, nonatomic) APSession *currSession;
|
||||
@property (strong, nonatomic) APSession *currentSession;
|
||||
|
||||
+ (id)sharedManager;
|
||||
- (BOOL)loadPlugins;
|
||||
- (BOOL)handleCommand:(NSString*)command withTokens:(NSSet*)tokens withSession:(APSession*)currSession;
|
||||
- (void)reloadCustomRepliesPlugin:(NSDictionary*)replies;
|
||||
- (void)reloadActivatorListeners:(NSDictionary*)listeners;
|
||||
- (void)assistantWasDismissed;
|
||||
|
||||
//1.0.1
|
||||
- (void)siriSay:(NSString*)message;
|
||||
|
@ -60,13 +60,24 @@ static NSString *EVENT_PREFIX = @"APListener";
|
||||
}
|
||||
|
||||
- (BOOL)handleCommand:(NSString*)command withTokens:(NSSet*)tokens withSession:(APSession*)currSession {
|
||||
self.currSession = currSession;
|
||||
|
||||
self.currentSession = currSession;
|
||||
//Clean up the command
|
||||
NSString *userCommand = [command lowercaseString];
|
||||
userCommand = [userCommand stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
|
||||
//First check activator listeners
|
||||
//First, check if a plugin is listening
|
||||
if ([currSession isListeningAfterSpeaking] && currSession.currentPlugin) {
|
||||
NSLog(@"AP: Resuming session");
|
||||
if ([currSession.currentPlugin respondsToSelector:@selector(handleReply:withTokens:withSession:)]) {
|
||||
[currSession.currentPlugin handleReply:userCommand withTokens:tokens withSession:currSession];
|
||||
return YES;
|
||||
} else {
|
||||
currSession.currentPlugin = nil;
|
||||
currSession.listenAfterSpeaking = NO;
|
||||
}
|
||||
}
|
||||
|
||||
//Then check activator listeners
|
||||
for (APActivatorListener *currListener in activatorListenersArray) {
|
||||
for (NSRegularExpression *currExpression in currListener.triggers) {
|
||||
NSArray *arrayOfAllMatches = [currExpression matchesInString:userCommand options:0 range:NSMakeRange(0, [userCommand length])];
|
||||
@ -107,12 +118,20 @@ static NSString *EVENT_PREFIX = @"APListener";
|
||||
NSLog(@"AP: Got Command \"%@\"", userCommand);
|
||||
for (APPlugin *currPlugin in plugins) {
|
||||
if ([currPlugin handleSpeech:userCommand withTokens:tokens withSession:currSession]) {
|
||||
currSession.currentPlugin = currPlugin;
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)assistantWasDismissed {
|
||||
for (APPlugin *currPlugin in plugins) {
|
||||
if ([currPlugin respondsToSelector:@selector(assistantWasDismissed)]) {
|
||||
[currPlugin assistantWasDismissed];
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma mark - Message Handlers
|
||||
|
||||
- (NSDictionary*)getInstalledPlugins {
|
||||
@ -152,7 +171,7 @@ static NSString *EVENT_PREFIX = @"APListener";
|
||||
}
|
||||
|
||||
- (void)siriSay:(NSString*)message {
|
||||
[self.currSession sendTextSnippet:message temporary:NO scrollToTop:YES dialogPhase:@"Completion"];
|
||||
[self.currentSession sendTextSnippet:message temporary:NO scrollToTop:YES dialogPhase:@"Completion"];
|
||||
}
|
||||
|
||||
#pragma mark - Activator Methods
|
||||
|
@ -10,8 +10,12 @@
|
||||
#import "AssistantHeaders.h"
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
|
||||
@class APPlugin;
|
||||
|
||||
@interface APSession : NSObject <APSiriSession, CLLocationManagerDelegate>
|
||||
@property (nonatomic, strong) NSString *refId;
|
||||
@property (nonatomic, getter=isListeningAfterSpeaking) BOOL listenAfterSpeaking;
|
||||
@property (nonatomic, strong) APPlugin *currentPlugin;
|
||||
@property (nonatomic, strong) AFConnection *connection;
|
||||
@property (nonatomic, copy) void (^completionHandler)(NSDictionary *locationData);
|
||||
|
||||
@ -19,13 +23,18 @@
|
||||
+(APSession*)sessionWithConnection:(AFConnection*)connection;
|
||||
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase;
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase listenAfterSpeaking:(BOOL)shouldListen;
|
||||
|
||||
-(SOObject*)createTextSnippet:(NSString*)text;
|
||||
|
||||
- (void)sendAddViews:(NSArray*)views;
|
||||
- (void)sendAddViews:(NSArray*)views dialogPhase:(NSString*)dialogPhase scrollToTop:(BOOL)toTop temporary:(BOOL)temporary;
|
||||
-(SOObject*)createSnippet:(NSString*)snippetClass properties:(NSDictionary*)props;
|
||||
|
||||
- (void)sendCustomSnippet:(NSString*)snippetClass withProperties:(NSDictionary*)props;
|
||||
- (void)sendRequestCompleted;
|
||||
-(SOObject*)createSnippet:(NSString*)snippetClass properties:(NSDictionary*)props;
|
||||
-(SOObject*)createAssistantUtteranceView:(NSString*)text;
|
||||
|
||||
- (void)sendRequestCompleted;
|
||||
- (void)getCurrentLocationWithCompletion:(void (^)(NSDictionary *info))completion;
|
||||
|
||||
+(NSString*)generateRandomUUID;
|
||||
|
@ -21,6 +21,7 @@ static NSMutableDictionary *sessionDict;
|
||||
self.refId = [referenceId copy];
|
||||
if (!self.refId) self.refId = [@"00000000-0000-0000-0000-000000000000" copy];
|
||||
self.connection = connection;
|
||||
self.listenAfterSpeaking = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -40,6 +41,10 @@ static NSMutableDictionary *sessionDict;
|
||||
return currSession;
|
||||
}
|
||||
|
||||
- (BOOL)isListeningAfterSpeaking {
|
||||
return _listenAfterSpeaking;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
-(SOObject*)createTextSnippet:(NSString*)text {
|
||||
@ -47,8 +52,12 @@ static NSMutableDictionary *sessionDict;
|
||||
}
|
||||
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase {
|
||||
[self sendTextSnippet:text temporary:temporary scrollToTop:toTop dialogPhase:phase listenAfterSpeaking:NO];
|
||||
}
|
||||
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase listenAfterSpeaking:(BOOL)listen {
|
||||
NSMutableArray* views = [NSMutableArray arrayWithCapacity:1];
|
||||
[views addObject:[self createAssistantUtteranceView:text]];
|
||||
[views addObject:[self createAssistantUtteranceView:text speakableText:text identifier:@"Misc" listenAfterSpeaking:listen]];
|
||||
[self sendAddViews:views dialogPhase:phase scrollToTop:toTop temporary:temporary];
|
||||
}
|
||||
|
||||
@ -57,6 +66,7 @@ static NSMutableDictionary *sessionDict;
|
||||
}
|
||||
|
||||
- (void)sendRequestCompleted {
|
||||
self.listenAfterSpeaking = NO;
|
||||
NSMutableDictionary* dict = [self createAceRequestCompleted];
|
||||
[self sendCommandToConnection:dict];
|
||||
[sessionDict removeObjectForKey:self.refId];
|
||||
@ -68,25 +78,21 @@ static NSMutableDictionary *sessionDict;
|
||||
}
|
||||
|
||||
- (void)sendAddViews:(NSArray*)views {
|
||||
return [self sendAddViews:views dialogPhase:@"Completion" scrollToTop:NO temporary:NO];
|
||||
[self sendAddViews:views dialogPhase:@"Completion" scrollToTop:NO temporary:NO];
|
||||
}
|
||||
|
||||
- (void)sendAddViews:(NSArray*)views dialogPhase:(NSString*)dialogPhase scrollToTop:(BOOL)toTop temporary:(BOOL)temporary {
|
||||
self.listenAfterSpeaking = NO;
|
||||
for (NSDictionary *currView in views) {
|
||||
if ([currView[@"listenAfterSpeaking"] boolValue]) {
|
||||
dialogPhase = @"Clarification";
|
||||
self.listenAfterSpeaking = YES;
|
||||
}
|
||||
}
|
||||
NSMutableDictionary* dict = [self createAceAddViews:views forPhase:dialogPhase scrollToTop:toTop temporary:temporary];
|
||||
// listenAfterSpeaking hack!
|
||||
// for (NSDictionary* view in views)
|
||||
// {
|
||||
// NSDictionary* props = [view objectForKey:@"properties"];
|
||||
// if ([[props objectForKey:@"listenAfterSpeaking"] boolValue])
|
||||
// {
|
||||
// _listenAfterSpeaking = YES;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// send
|
||||
[self sendCommandToConnection:dict];
|
||||
}
|
||||
|
||||
#pragma mark - APLocationDaemon Communication
|
||||
|
||||
- (void)handleMessage:(NSString*)name withInfo:(NSDictionary*)locationData {
|
||||
@ -135,7 +141,7 @@ static NSMutableDictionary *sessionDict;
|
||||
|
||||
// call the original method to handle our new object
|
||||
if (self.connection == nil) { NSLog(@"AP: AFConnection is nil"); return; }
|
||||
|
||||
|
||||
if ([dict[@"$class"] isEqualToString:@"CommandSucceeded"]) {
|
||||
[self.connection sendReplyCommand:obj];
|
||||
} else {
|
||||
@ -171,7 +177,7 @@ static NSMutableDictionary *sessionDict;
|
||||
|
||||
if (properties != nil) {
|
||||
//Only necessary for AceObjects
|
||||
[objDict setObject:@"4.0" forKey:@"$v"];
|
||||
[objDict setObject:@"4.3" forKey:@"$v"];
|
||||
|
||||
for (NSString *currKey in properties.allKeys) {
|
||||
[objDict setObject:properties[currKey] forKey:currKey];
|
||||
@ -213,22 +219,19 @@ static NSMutableDictionary *sessionDict;
|
||||
return [self createAceObjectDictForGroup:@"com.apple.ace.assistant" class:@"AddViews" properties:props];
|
||||
}
|
||||
|
||||
//NSMutableDictionary* SOCreateAceAddViewsUtteranceView(NSString* refId, NSString* text, NSString* speakableText, NSString* dialogPhase, BOOL scrollToTop, BOOL temporary) {
|
||||
// NSMutableArray* views = [NSMutableArray arrayWithCapacity:1];
|
||||
// [views addObject:[self createAssistantUtteranceView:text speakableText:speakableText identifier:@"Misc#ident"]];
|
||||
//
|
||||
// return [self createAceAddViews:views forPhase:dialogPhase scrollToTop:scrollToTop temporary:temporary];
|
||||
//}
|
||||
|
||||
#pragma mark - AssistantUtteranceView Creation
|
||||
|
||||
-(NSMutableDictionary*)createAssistantUtteranceView:(NSString*)text speakableText:(NSString*)speakableText identifier:(NSString*)dialogIdentifier {
|
||||
-(NSMutableDictionary*)createAssistantUtteranceView:(NSString*)text speakableText:(NSString*)speakableText identifier:(NSString*)dialogIdentifier listenAfterSpeaking:(BOOL)listen {
|
||||
if (speakableText == nil) speakableText = text;
|
||||
NSMutableDictionary* props = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
text,@"text", speakableText,@"speakableText", dialogIdentifier,@"dialogIdentifier", nil];
|
||||
text,@"text", speakableText,@"speakableText", dialogIdentifier,@"dialogIdentifier", @(listen), @"listenAfterSpeaking", nil];
|
||||
return [self createObjectDictForGroup:@"com.apple.ace.assistant" class:@"AssistantUtteranceView" properties:props];
|
||||
}
|
||||
|
||||
-(NSMutableDictionary*)createAssistantUtteranceView:(NSString*)text speakableText:(NSString*)speakableText identifier:(NSString*)dialogIdentifier {
|
||||
return [self createAssistantUtteranceView:text speakableText:speakableText identifier:dialogIdentifier listenAfterSpeaking:NO];
|
||||
}
|
||||
|
||||
-(SOObject*)createAssistantUtteranceView:(NSString*)text {
|
||||
return [self createAssistantUtteranceView:text speakableText:text identifier:@"Misc#Ident"];
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
@protocol APSiriSession <NSObject>
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase;
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase listenAfterSpeaking:(BOOL)listen;
|
||||
- (void)sendAddViews:(NSArray*)views;
|
||||
- (void)sendAddViews:(NSArray*)views dialogPhase:(NSString*)dialogPhase scrollToTop:(BOOL)toTop temporary:(BOOL)temporary;
|
||||
-(NSMutableDictionary*)createSnippet:(NSString*)snippetClass properties:(NSDictionary*)props;
|
||||
@ -32,6 +33,7 @@
|
||||
+(id)sharedManager;
|
||||
- (void)reloadCustomRepliesPlugin:(NSDictionary*)replies;
|
||||
- (void)reloadActivatorListeners:(NSDictionary*)listeners;
|
||||
- (void)assistantWasDismissed;
|
||||
@end
|
||||
|
||||
@protocol APPluginManager <NSObject>
|
||||
@ -55,9 +57,13 @@
|
||||
@protocol APPluginCommand <NSObject>
|
||||
@optional
|
||||
-(BOOL)handleSpeech:(NSString*)text withTokens:(NSSet*)tokens withSession:(id<APSiriSession>)session;
|
||||
-(void)handleReply:(NSString*)text withTokens:(NSSet*)tokens withSession:(id<APSiriSession>)session;
|
||||
-(void)assistantWasDismissed;
|
||||
@end
|
||||
|
||||
@protocol APPlugin <NSObject>
|
||||
@required
|
||||
-(id)initWithPluginManager:(id<APPluginManager>)system;
|
||||
@optional
|
||||
- (void)assistantWasDismissed;
|
||||
@end
|
||||
|
Binary file not shown.
Binary file not shown.
@ -19,6 +19,8 @@
|
||||
dialogPhase: Possible values are Completion, Reflection, Summary, Error, Clarification, and Acknowledgement */
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase;
|
||||
|
||||
- (void)sendTextSnippet:(NSString*)text temporary:(BOOL)temporary scrollToTop:(BOOL)toTop dialogPhase:(NSString*)phase listenAfterSpeaking:(BOOL)shouldListen;
|
||||
|
||||
/* Create an editable dictionary representing a text snippet. In order to send this
|
||||
to the user you must add it to an NSArray and use sendAddviews: */
|
||||
-(NSMutableDictionary*)createTextSnippet:(NSString*)text;
|
||||
|
@ -1,8 +1,8 @@
|
||||
include theos/makefiles/common.mk
|
||||
|
||||
export ARCHS = armv7 arm64
|
||||
export TARGET = iphone:clang:latest:8.0
|
||||
export SDKVERSION=8.1
|
||||
export TARGET = iphone:clang:latest:8.4
|
||||
export SDKVERSION=8.4
|
||||
|
||||
BUNDLE_NAME = customreply
|
||||
customreply_BUNDLE_EXTENSION = assistantPlugin
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user