å æ¥ã®WWDC18ã§çºè¡¨ããããiOS 12ã®æ°æ©è½ "Siri Shortcuts"ããããããæé ã声ã§å¼ã³åºãããã¨ããã®ã¯ãã¡ããå¬ãããã¨ã§ããããããããã
ãããã¯ã¹ã¯ãªã¼ã³ããå¼ã³åºããã
ã¨ããã¨ããã«ããã©ãããã©ã¼ã ã®å¶ç´ã®ä¸ã§åæ¨é¸æãããããªããã¡ã¢ããªéçºè ã¨ãã¦ã¯å§åçé åãæããããå¾ã¾ããã

ãä½ãã©ãã¾ã§ã§ããã®ããã©ãå®è£ ããã®ãããæ´ãã¹ããã¾ãã¯ãã®æå°å®è£ ã確èªãã¦ã¿ã¾ããã
ã¡ãªã¿ã«åèè³æã¯WWDC 2018ã®ã»ãã·ã§ã³çªå·211ãIntroduction to Siri Shortcutsãã¨ãµã³ãã«ã³ã¼ããSoupChefãã§ãã1
å®è£ æ¹æ³ã¯2éã
Siri Shortcutsã®å®è£ æ¹æ³ã¨ãã¦ã¯ã以ä¸ã®2種é¡ãããã¾ãã
- NSUserActivityãå©ç¨ããæ¹æ³
- Intentsãå©ç¨ããæ¹æ³
æ¬è¨äºã§ã¯ãã¿ã¤ãã«éããNSUserActivityãç¨ããSiri Shortcutsã®æå°å®è£
ã ããç´¹ä»ãã¾ãã
Appleã®ãµã³ãã«ãSoupChefãã¯ä¸¡æ¹ã®å®è£ ãå ¥ã£ã¦ãããããã¯ããã§ãããããã®ã§ãããåãã¦æã人ã«ã¯ã©ã®ã³ã¼ããã©ã£ã¡ç¨ãªã®ãããã¨ãã°Intentsã使ããªãå ´åã¯ã©ããçããã®ãã¨ãã£ããã¨ããããã¥ããã¨æãã®ã§ããã®ããããæ¬è¨äºã§ç´è§£ããã°ã¨ã
3ã¹ããã
NSUserActivityãç¨ããSiri Shortcutsã®å®è£
ã¯ã次ã®3ã¤ã®æé ã§è¡ãã¾ãã
- ã·ã§ã¼ãã«ãããå®ç¾©ãã
- ã·ã§ã¼ãã«ãããæä¾ããï¼donateï¼ 2
- ã·ã§ã¼ãã«ããããã³ãã«ãã
ãã¢ããªã®ç»é¢Bãéããã¨ããã·ã§ã¼ãã«ãããSiri Shortcutsãå®ç¾ãã¦ã¿ã¾ãã
1. ã·ã§ã¼ãã«ãããå®ç¾©ãã
Info.plistã«æ¬¡ã®ããã«NSUserActivityTypesãå®ç¾©ãã¾ãã
<key>NSUserActivityTypes</key> <array> <string>com.myapp.name.my-activity-type</string> </array>
2. ã·ã§ã¼ãã«ãããæä¾ãã
Intentsãã¤ã³ãã¼ããã¦ã
import Intents
次ã®ããã«NSUserActivityãç¨æãã¾ãã
extension NSUserActivity { public static let myActivityType = "com.myapp.name.my-activity-type" public static var myActivity: NSUserActivity { let userActivity = NSUserActivity(activityType: myActivityType) userActivity.isEligibleForSearch = true userActivity.isEligibleForPrediction = true userActivity.title = "My First Activity" userActivity.suggestedInvocationPhrase = "Let's do it" return userActivity } }
ä¸è¦è¤éã«è¦ãã¾ãããSiri Shortcutsã«é¢ä¿ãããã¤ã³ãã¨ãã¦ã¯ã
isEligibleForPredictionããããã£ã«trueãã»ããããsuggestedInvocationPhraseããããã£ãã»ãããã- ããã«ã»ãããããã¬ã¼ãºãã·ã§ã¼ãã«ããã®é³å£°ã³ãã³ããã¦ã¼ã¶ã¼ã«é²é³ãã¦ãããç»é¢ã§ãµã¸ã§ã¹ãããã
ãããããã§ãã
Appleã®ãµã³ãã«ã«ã¯ã次ã®ããã«CSSearchableItemAttributeSetã使ãã¦contentAttributeSetã«ã»ããããå®è£
ãå
¥ã£ã¦ãã¾ããã
// çç¥å¯ let attributes = CSSearchableItemAttributeSet(itemContentType: "hoge") attributes.thumbnailData = UIImage(named: "filename")!.pngData() attributes.keywords = ["foo", "bar"] attributes.displayName = "My First Activity" attributes.contentDescription = "Subtitle" userActivity.contentAttributeSet = attributes
ç§ã試ããã¨ããã§ã¯Siri Shortcutsãè¡ãã ãã§ããã°çç¥å¯è½ã§ãã3ãæ¤ç´¢çªï¼Spotlightï¼ããã®ããã¹ãã«ããæ¤ç´¢ã«ã対å¿ããããå ´åã«å¿ è¦ãªã®ã§ã¯ãªãã§ããããã
使ããNSUserActivityãªãã¸ã§ã¯ãããã·ã§ã¼ãã«ãããæä¾ããUIViewControlllerã®userActivityããããã£ï¼æ£ç¢ºã«ã¯UIResponderã®ããããã£ï¼ã«ã»ãããã¾ãã
userActivity = NSUserActivity.myActivity
ããã§ãAppleã®ãµã³ãã«ã§ã¯æ¬¡ã®ããã«updateUserActivityState(_)ããªã¼ãã¼ã©ã¤ããã¦NSUserActivityã®addUserInfoEntries(from:)ã¡ã½ããã§userInfoã®ãã¼ã¿ãä¾çµ¦ããå®è£
ãå
¥ã£ã¦ãã¾ããããããããªãã¦ãåä½ãã¾ããã
// çç¥å¯ override func updateUserActivityState(_ activity: NSUserActivity) { let userInfo: [String: Any] = [NSUserActivity.ActivityKeys.menuItems: menuItems.map { $0.itemNameKey }, NSUserActivity.ActivityKeys.segueId: "Soup Menu"] activity.addUserInfoEntries(from: userInfo) }
ã·ã§ã¼ãã«ããã§ã¢ããªãèµ·åããéã«ãã¢ããªã®ç¶æ
ã復å
ããããã«å¿
è¦ãªãã¼ã¿ï¼userInfoï¼ãããå ´åã«å®è£
ãã¹ããã®ã¨æããã¾ãã
ãªããããã«åºã¦ããNSUserActivityãCSSearchableItemAttributeSetãåè¦ã®æ¹ã¯ããiOS 9 ã®æ°æ©è½ã®ãµã³ãã«ã³ã¼ãéãã®ãSearch APIsããµã³ãã«ãå®è¡ãã¦ã¿ã¤ã¤ã³ã¼ããèªãã§ã¿ãã¨é常ã«ããããããã§ããNSUserActivity ã使ããã®ã¨ãCore Spotlight ã使ããã®ã®2種é¡ãå®è£
ãã¦ãããã³ã¼ããã·ã³ãã«ãªã®ã§ã©ã®ããããã£ãä½ã«å¯¾å¿ãã¦ãã®ããããããããã§ãã
3. ã·ã§ã¼ãã«ããããã³ãã«ãã
ã·ã§ã¼ãã«ãããå¼ã³åºããã¦ã¢ããªãèµ·åããéãUIApplicationDelegateã®application(_:continue:restorationHandler:)ãå¼ã³åºãããã®ã§ãããã§æ¸¡ããã¦ããã¢ã¯ãã£ããã£ï¼NSUserActivityï¼ããã³ãã«ãã¾ãã
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if userActivity.activityType == NSUserActivity.myActivityType { // Restore state for userActivity and userInfo guard let window = window, let rootViewController = window.rootViewController as? UINavigationController, let vc = rootViewController.viewControllers.first as? ViewController else { os_log("Failed to access ViewController.") return false } vc.performSegue(withIdentifier: "B", sender: nil) return true } return false }
ããã§ã¯activityTypeã§ã©ã®ã¢ã¯ãã£ããã£ããå¤å®ãããã¨ã¯æç´ã«performSegueã§ç»é¢Bã«é·ç§»ããã¦ããã ãã§ãã
宿åã®æå
NDAæéä¸ã®ãã宿åã®æåããã£ããã£ãã¦ã¢ãããããã¨ãã§ããªãã®ã§ããã
- è¨å®ããå½è©²Siri Shortcutãç»é²
- ããã¯ã¹ã¯ãªã¼ã³ããç»é²ãããã¬ã¼ãºã§å¼ã³åºã
ããã§ã¢ããªãèµ·åããç»é¢Bã¾ã§èªåçã«é·ç§»ãã¾ããã
ã¢ããªã¯ããã¯ã°ã©ã¦ã³ãã§çãã¦ããå¿ è¦ãããã®ãï¼
æ°ã«ãªã£ãã®ããUIViewControllerã®userActivityããããã£ã«å½è©²NSUserActivityãªãã¸ã§ã¯ããã»ããããç¹ã§ããããã£ã¦ãã®View Controllerãã·ã§ã¼ãã«ããã®donatorã§ãããã¢ããªãçãã¦ãªãã¨å¼ã³åºããªãã®ãï¼ã¨ã
ã¨ããããã§ã¢ããªãkillãã¦ãNSUserActivityãã¼ã¹ã®Siri Shortcutã¯åä½ããã試ãã¦ã¿ã¾ããã
çµæ â åä½ãã¾ããã
è¯ãã£ãã§ãã
次å
- Intentsãç¨ããå ´åã®æå°å®è£
- 両è ãã©ã使ãåããã
- Siri Shortcutsã§å¼ã³åºããªãæ©è½ã¯ãã¨ãã°ã©ããªãã®ãããï¼
ã¨ãã£ããããã«ã¤ãã¦æ¸ãã¾ããï¼æ¸ããããããªã¨æã£ã¦ãã¾ãï¼
-
æ¬è¨äºã¯NDAã«é æ ®ããXcode 10ãiOS 12ã®ã¹ã¯ã·ã§ã¯ä½¿ãããå ¬éæ å ±ã®ã¿ã§æ§æãã¦ãã¾ãã↩
-
ãæ©è½ãæä¾ãããã¨ãããã¨ãiOSã§è¡¨ç¾ããå ´åã«ã¯ãã"provide"ã¨ããåè©ã使ããããã¨ãå¤ãæ°ããã¾ããããã§Appleãããã¦ãå¯ä»ããããå¯è´ãããã¨ãã£ãæå³ã®"donate"ãå©ç¨ãã¦ããã®ã¯ã©ãããæ°æã¡ãããã£ã¦ããã®ã§ãããï¼↩
-
ãã®ã¸ãããã£ãã·ã¥ãæ®ããããªæåããããå使¤è¨¼çµæã«100%確信ãããã¾ããã↩