// // HDLSiriSceneListViewController.m // HdlSmartIoT // // Created by 陈嘉乐 on 2021/11/17. // #import "HDLSiriSceneListViewController.h" #import #import #import "HDLRunSceneIntent.h" //上方“设置Custom Intents”图中右边箭头指的“Class Name” #import "HDLSiriSceneListCell.h" #import "HDLSiriSceneModel.h" #import "HDLSceneSiri.h" #import "TopBarView.h" NSString * const HDLSiriSceneListCellIdentifier = @"HDLSiriSceneListCellIdentifier"; @interface HDLSiriSceneListViewController () /// TopBarView @property (nonatomic, strong) TopBarView *topBarView; @property (copy,nonatomic) NSArray *siriShortcutList; @end @implementation HDLSiriSceneListViewController - (instancetype)init { if (self = [super init]) { _tableViewStyle = UITableViewStylePlain; } return self; } - (void)viewDidLoad { [super viewDidLoad]; [self.navigationController setNavigationBarHidden:YES animated:YES]; self.view.backgroundColor = HEXCOLORA(0xF7F7FC,1.0); [self initView]; // Do any additional setup after loading the view. } /// initView - (void)initView{ //标题 if(self.titleName == nil || [self.titleName isEqual:@""]){ self.titleName = @"Siri快捷指令"; } [self setTopBarViewWithTitle:self.titleName]; [self initTableView]; [self refreshSiri]; } #pragma mark - TopBarView - (TopBarView *)topBarView{ if (!_topBarView) { _topBarView = [[TopBarView alloc] initWithFrame: CGRectMake(0, 0, APP_SCREEN_WIDTH, 40)]; [_topBarView.backButton addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside]; } return _topBarView; } //设置标题和返回按钮 - (void)setTopBarViewWithTitle:(NSString *)title{ [self.view addSubview:self.topBarView]; self.topBarView.backgroundColor = UIColor.whiteColor; self.topBarView.titleLabel.text = title; } //返回 - (void)goBack{ if ([self.navigationController.viewControllers indexOfObject:self] == 0) { [self dismissViewControllerAnimated:YES completion:nil]; } else { [self.navigationController popViewControllerAnimated:YES]; // [self.navigationController popToRootViewControllerAnimated:YES]; } } #pragma mark - UITableView - (UITableView *)tableView { if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, APP_SCREEN_WIDTH, 0) style:self.tableViewStyle]; // _tableView.backgroundColor = COLOR_MAIN_BACKGROUND; _tableView.backgroundColor = UIColor.clearColor; _tableView.showsVerticalScrollIndicator = NO; _tableView.showsHorizontalScrollIndicator = NO; _tableView.separatorStyle = NO; _tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); _tableView.dataSource = self; _tableView.delegate = self; } return _tableView; } - (void)initTableView{ self.tableView.frame = CGRectMake(0, APP_TOP_BAR_HEIGHT + 12, APP_SCREEN_WIDTH, APP_VISIBLE_HEIGHT - APP_TAB_BOTTOM_HEIGHT-12); // self.tableView.backgroundColor = HEXCOLORA(0xF7F7FC,1.0); [self.view addSubview:self.tableView]; // [self.tableView reloadData]; } #pragma mark - UITableViewDataSourceXW - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataSource.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { HDLSiriSceneListCell *cell = [tableView dequeueReusableCellWithIdentifier:HDLSiriSceneListCellIdentifier]; if (cell == nil) { cell = [[HDLSiriSceneListCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:HDLSiriSceneListCellIdentifier]; } HDLSiriSceneModel *model = self.dataSource[indexPath.row]; if(model){ if (@available(iOS 12.0, *)) { HDLRunSceneIntent *intent = [self getSceneIntent: model.userSceneId]; [cell initModel:model intent:intent]; } } return cell; } #pragma mark - UITableViewDelegate - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 72; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (@available(iOS 12.0, *)) { HDLSiriSceneModel *model = self.dataSource[indexPath.row]; if(model){ INVoiceShortcut *voiceShortcut = [self getSceneINVoiceShortcut:model.userSceneId]; [self addOrEditVoiceShortcut:voiceShortcut model:model]; } } } /// 添加或者编辑快捷指令 /// @param voiceShortcut 快捷指令 /// @param model 场景 -(void)addOrEditVoiceShortcut:(INVoiceShortcut *)voiceShortcut model:(HDLSiriSceneModel*)model API_AVAILABLE(ios(12.0)){ if(voiceShortcut==nil){ //1.如果不存在则添加 INUIAddVoiceShortcutViewController *vc = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:[self getINShortcut:model]]; vc.delegate = self; if(@available(iOS 13.0, *)) { vc.modalPresentationStyle = UIModalPresentationOverFullScreen; } [self presentViewController:vc animated:YES completion:nil]; }else{ //2.存在则编辑 INUIEditVoiceShortcutViewController* vc = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcut]; vc.delegate = self; if(@available(iOS 13.0, *)) { vc.modalPresentationStyle = UIModalPresentationOverFullScreen; } [self presentViewController:vc animated:YES completion:nil]; } } - (INShortcut *) getINShortcut:(HDLSiriSceneModel*)model API_AVAILABLE(ios(12.0)){ NSString *title = model.name; HDLRunSceneIntent *intent = [[HDLRunSceneIntent alloc] init]; intent.sceneId = model.userSceneId; intent.suggestedInvocationPhrase = title; //在Siri语音设置时显示的建议设置唤起文字 intent.sceneName = title; INShortcut *shortCut = [[INShortcut alloc] initWithIntent:intent]; return shortCut; } /// 根据场景ID或者之前配置过低快捷指令 /// @param sceneId 场景ID - (HDLRunSceneIntent*)getSceneIntent:(NSString *)sceneId API_AVAILABLE(ios(12.0)){ HDLRunSceneIntent *intentFind = nil; for (INVoiceShortcut *voiceShortcut in self.siriShortcutList) { HDLRunSceneIntent *intent = (HDLRunSceneIntent *)voiceShortcut.shortcut.intent; if(intent){ if([intent.sceneId isEqualToString:sceneId]){ intentFind = intent; break; } } } return intentFind; } /// 根据场景ID或者之前配置过低快捷指令 /// @param sceneId 场景ID - (INVoiceShortcut*)getSceneINVoiceShortcut:(NSString *)sceneId API_AVAILABLE(ios(12.0)){ INVoiceShortcut *voiceShortcutFind = nil; for (INVoiceShortcut *voiceShortcut in self.siriShortcutList) { HDLRunSceneIntent *intent = (HDLRunSceneIntent *)voiceShortcut.shortcut.intent; if(intent){ if([intent.sceneId isEqualToString:sceneId]){ voiceShortcutFind = voiceShortcut; break; } } } return voiceShortcutFind; } #pragma mark - refreshSiri - (BOOL)checkCurrentClass:(INVoiceShortcut*)voiceShortcut API_AVAILABLE(ios(12.0)){ return [voiceShortcut.shortcut.intent isKindOfClass:[HDLRunSceneIntent class]]; } /// refreshSiri - (void)refreshSiri { if (@available(iOS 12.0, *)) { NSMutableArray *temp = [NSMutableArray array]; [[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray * _Nullable voiceShortcuts, NSError * _Nullable error) { //该方法不是在主线程运行的,所以如果ok了需要回到主线程来 dispatch_async(dispatch_get_main_queue(), ^{ for (INVoiceShortcut *voiceShortcut in voiceShortcuts) { if ([self checkCurrentClass:voiceShortcut]) { [temp addObject:voiceShortcut]; } } self.siriShortcutList = [NSArray arrayWithArray:temp]; [self.tableView reloadData]; }); }]; } [self.tableView reloadData]; } #pragma mark - INUIAddVoiceShortcutButtonDelegate - (void)presentAddVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)addVoiceShortcutViewController forAddVoiceShortcutButton:(INUIAddVoiceShortcutButton *)addVoiceShortcutButton API_AVAILABLE(ios(12.0)){ addVoiceShortcutViewController.delegate = self; if(@available(iOS 13.0, *)) { addVoiceShortcutViewController.modalPresentationStyle = UIModalPresentationOverFullScreen; } [self presentViewController:addVoiceShortcutViewController animated:YES completion:nil]; } - (void)presentEditVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)editVoiceShortcutViewController forAddVoiceShortcutButton:(INUIAddVoiceShortcutButton *)addVoiceShortcutButton API_AVAILABLE(ios(12.0)){ editVoiceShortcutViewController.delegate = self; if(@available(iOS 13.0, *)) { editVoiceShortcutViewController.modalPresentationStyle = UIModalPresentationOverFullScreen; } [self presentViewController:editVoiceShortcutViewController animated:YES completion:nil]; } #pragma mark - INUIAddVoiceShortcutViewControllerDelegate - (void)addVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)controller didFinishWithVoiceShortcut:(INVoiceShortcut *)voiceShortcut error:(NSError *)error API_AVAILABLE(ios(12.0)){ [self refreshSiri]; [controller dismissViewControllerAnimated:YES completion:nil]; } - (void)addVoiceShortcutViewControllerDidCancel:(INUIAddVoiceShortcutViewController *)controller API_AVAILABLE(ios(12.0)){ [self refreshSiri]; [controller dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - INUIEditVoiceShortcutViewControllerDelegate - (void)editVoiceShortcutViewControllerDidCancel:(INUIEditVoiceShortcutViewController *)controller API_AVAILABLE(ios(12.0)){ [self refreshSiri]; [controller dismissViewControllerAnimated:YES completion:nil]; } - (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didUpdateVoiceShortcut:(INVoiceShortcut *)voiceShortcut error:(NSError *)error API_AVAILABLE(ios(12.0)){ [self refreshSiri]; [controller dismissViewControllerAnimated:YES completion:nil]; } - (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didDeleteVoiceShortcutWithIdentifier:(NSUUID *)deletedVoiceShortcutIdentifier API_AVAILABLE(ios(12.0)){ [self refreshSiri]; [controller dismissViewControllerAnimated:YES completion:nil]; } @end