Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Siri Shortcut的OTT應用

Avatar for Mars Mars
October 20, 2018

Siri Shortcut的OTT應用

摘要

* 介紹 SiriKit
* 介紹 Siri Shortcut
* 如何應用到 OTT app
* 開發經驗分享

細節

在 2018 的 WWDC 中,介紹了新的 SiriKit 應用 Shortcut,在這次的分享中,不但會簡單介紹 SiriKit & Siri Shortcut,並且會介紹實際應用在 OTT 的方式和與如何提升與使用者的互動。

設定的目標聽眾會是想了解最新的 Siri Shortcut 的功能以外,並且想提升活躍使用者數量的 app 開發者。

說明

* 今年最新的 WWDC 所介紹的功能
* 實際應用在有百萬等級以上使用者所使用的 OTT app
* SiriKit & Siri Shortcut 的官方文件較沒有統整性,並且多在歷年的 WWDC 才有詳細資訊,統整過後的資訊對於其他開發者有很大的助益

Avatar for Mars

Mars

October 20, 2018
Tweet

More Decks by Mars

Other Decks in Technology

Transcript

  1. – Apple Inc. “SiriKit enables your iOS apps and watchOS

    apps to work with Siri, so users can get things done using just their voice.”
  2. SiriKit • Introduced in 2016 • Use “intent” as user

    request • Group intents into “domains”
  3. –Apple Inc. “Siri can now intelligently pair users' daily routines

    with your apps to suggest convenient shortcuts right when they're needed”
  4. 2. Add NSUserActivityTypes • Use the reverse domain as naming

    • The name of the intent
 
 
 
 
 
 

  5. NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:@"com.chocolabs.dramacrazy-test.dramainfo"]; userActivity.title = [NSString stringWithFormat:@"播放

    %@", dramaObject.dramaName]; [userActivity addUserInfoEntriesFromDictionary:@{@"dramaID" : dramaObject.dramaID, @"dramaName" : dramaObject.dramaName, }]; userActivity.needsSave = YES; userActivity.eligibleForSearch = YES; userActivity.eligibleForPrediction = YES; userActivity.persistentIdentifier = @"com.chocolabs.dramacrazy.activity"; userActivity.suggestedInvocationPhrase = [NSString stringWithFormat:@"播放 %@", dramaObject.dramaName]; self.userActivity = userActivity;
  6. NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:@"com.chocolabs.dramacrazy-test.dramainfo"]; userActivity.title = [NSString stringWithFormat:@"播放

    %@", dramaObject.dramaName]; [userActivity addUserInfoEntriesFromDictionary:@{@"dramaID" : dramaObject.dramaID, @"dramaName" : dramaObject.dramaName, }]; userActivity.needsSave = YES; userActivity.eligibleForSearch = YES; userActivity.eligibleForPrediction = YES; userActivity.persistentIdentifier = @"com.chocolabs.dramacrazy.activity"; userActivity.suggestedInvocationPhrase = [NSString stringWithFormat:@"播放 %@", dramaObject.dramaName]; self.userActivity = userActivity;
  7. NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:@"com.chocolabs.dramacrazy-test.dramainfo"]; userActivity.title = [NSString stringWithFormat:@"播放

    %@", dramaObject.dramaName]; [userActivity addUserInfoEntriesFromDictionary:@{@"dramaID" : dramaObject.dramaID, @"dramaName" : dramaObject.dramaName, }]; userActivity.needsSave = YES; userActivity.eligibleForSearch = YES; userActivity.eligibleForPrediction = YES; userActivity.persistentIdentifier = @"com.chocolabs.dramacrazy.activity"; userActivity.suggestedInvocationPhrase = [NSString stringWithFormat:@"播放 %@", dramaObject.dramaName]; self.userActivity = userActivity;
  8. INImage *artwork = [INImage imageWithURL:[NSURL URLWithString:dramaObject.posterUrlVertical]]; INMediaItem *item = [[INMediaItem

    alloc] initWithIdentifier:dramaObject.dramaID title:dramaObject.dramaName type:INMediaItemTypeTVShow artwork:artwork]; INPlayMediaIntent *intent = [[INPlayMediaIntent alloc] initWithMediaItems:nil mediaContainer:item playShuffled:@(0) playbackRepeatMode:INPlaybackRepeatModeNone resumePlayback:@(0)]; intent.suggestedInvocationPhrase = [NSString stringWithFormat:@"播放 %@", dramaObject.dramaName];
  9. INImage *artwork = [INImage imageWithURL:[NSURL URLWithString:dramaObject.posterUrlVertical]]; INMediaItem *item = [[INMediaItem

    alloc] initWithIdentifier:dramaObject.dramaID title:dramaObject.dramaName type:INMediaItemTypeTVShow artwork:artwork]; INPlayMediaIntent *intent = [[INPlayMediaIntent alloc] initWithMediaItems:nil mediaContainer:item playShuffled:@(0) playbackRepeatMode:INPlaybackRepeatModeNone resumePlayback:@(0)]; intent.suggestedInvocationPhrase = [NSString stringWithFormat:@"播放 %@", dramaObject.dramaName];
  10. Import Intent Header #import <Intents/Intents.h> NS_ASSUME_NONNULL_BEGIN API_AVAILABLE(ios(12.0), watchos(5.0)) @interface CTPlayDramaIntent

    : INIntent @property (readwrite, copy, nullable, nonatomic) NSString *startTime; @property (readwrite, copy, nullable, nonatomic) NSString *episode; @property (readwrite, copy, nullable, nonatomic) NSString *dramaName; @property (readwrite, copy, nullable, nonatomic) NSString *dramaID; @end @class CTPlayDramaIntentResponse;
  11. Donate It if (@available(iOS 12.0, *)) { CTPlayDramaIntent *intent =

    [[CTPlayDramaIntent alloc] init]; intent.dramaID = dramaObject.dramaID; intent.dramaName = dramaObject.dramaName; if (saveHistory) { intent.episode = saveHistory.epsTitle; intent.startTime = saveHistory.offsetTimeString; } intent.suggestedInvocationPhrase = [NSString stringWithFormat:@"播放 %@", dramaObject.dramaName]; INInteraction *interaction = [[INInteraction alloc] initWithIntent:intent response:nil]; [interaction donateInteractionWithCompletion:^(NSError * _Nullable error) { if (error) { NSLog(@"donate error: %@", error); } }]; }
  12. // CTDropHistoryIntentHandler.m - (void)confirmDropHistory:(CTDropHistoryIntent *)intent completion:(void (^)(CTDropHistoryIntentResponse *_Nonnull))completion API_AVAILABLE(ios(12.0)) {

    CTDropHistoryIntentResponse *intentResponse = [[CTDropHistoryIntentResponse alloc] initWithCode:CTDropHistoryIntentResponseCodeReady userActivity:nil]; completion(intentResponse); }
  13. // CTDropHistoryIntentHandler.m - (void)handleDropHistory:(CTDropHistoryIntent *)intent completion:(void (^) (CTDropHistoryIntentResponse *_Nonnull))completion API_AVAILABLE(ios(12.0))

    { [self dropHistoryWithSuccess:^{ CTDropHistoryIntentResponse *intentResponse = [[CTDropHistoryIntentResponse alloc] initWithCode:CTDropHistoryIntentResponseCodeSuccess userActivity:nil]; completion(intentResponse); } failure:^(NSError *error) { CTDropHistoryIntentResponse *intentResponse = [[CTDropHistoryIntentResponse alloc] initWithCode:CTDropHistoryIntentResponseCodeFailure userActivity:nil]; completion(intentResponse); }]; }
  14. // IntentHandler.m @implementation IntentHandler - (id)handlerForIntent:(INIntent *)intent { if ([intent

    isKindOfClass:[CTDropHistoryIntent class]]) { return [CTDropHistoryIntentHandler new]; } return self; } @end
  15. Suggest Siri Suggestion #import "Intents/INShortcut.h" #import “Intents/INVoiceShortcutCenter.h" INShortcut *activityShortcut =

    [[INShortcut alloc] initWithUserActivity:userActivity]; INShortcut *intentShortcut = [[INShortcut alloc] initWithIntent:intent]; [[INVoiceShortcutCenter sharedCenter] setShortcutSuggestions:@[activityShortcut, intentShortcut]];
  16. Q&A