Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
iOS 13におけるSiri Shortcuts 最小実装+α
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Maika Yamada
September 21, 2020
2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
iOS 13におけるSiri Shortcuts 最小実装+α
Maika Yamada
September 21, 2020
More Decks by Maika Yamada
See All by Maika Yamada
対話を頑張らなくても作れるSiri Shortcuts向けIntents App Extension
myamada04
0
770
知っておきたかったUIGestureRecognizerとUITouchの違い
myamada04
1
1.2k
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Optimising Largest Contentful Paint
csswizardry
37
4k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
290
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
23k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.4k
Tell your own story through comics
letsgokoyo
1
1.1k
Un-Boring Meetings
codingconduct
0
480
Chasing Engaging Ingredients in Design
codingconduct
0
380
Transcript
J04%$+BQBOEBZ ໌ຑҥՖ !N@ZBNBEB J04ʹ͓͚Δ4JSJ4IPSUDVUT ࠷খ࣮ Ћ
ࣗݾհ w ໌ຑҥՖ w 5XJUUFS!N@ZBNBEB w 4UVEZQMVT *OD w ʙ
w ࣄ৬ˠ4*FSˠݱࡏ w J04&OHJOFFS
4JSJ4IPSUDVUTػೳΛϦϦʔε ͋ͳͨͷؤுΓΛݟ͑ΔԽ͢ΔษڧهΞϓϦ 4UVEZQMVT
ରԠͨ͠ը໘ w Ϣʔβʔͷ23ίʔυը໘ w ॻ੶ͷόʔίʔυಡΈऔΓΧϝ ϥը໘ ͦΕͧΕɺ"QQMF͕4JSJ4IPSUDVUT ͷ࣮ΛקΊΔΞϓϦΛར༻͢Δ ্ͰԿճ܁Γฦ͠ߦΘΕΔૢ࡞ ʹ֘͢Δͱஅ࣮ͯ͠
4JSJ4IPSUDVUTར༻ঢ়گ ˞݄ʙ݄࣌ w γϣʔτΧοτܦ༝ͰΞϓϦΛ։͍ͨ w ճɿ w ਓɿ
w "EEUP4JSJϘλϯ͔ΒΞϓϦΛ։͘γϣʔτΧοτΛొͨ͠ w ճɿ w ਓɿ
ΞδΣϯμ w 4JSJ4IPSUDVUT࠷খ࣮ w 4QPUMJHIUͷl4JSJ͔ΒͷఏҊzʹγϣʔτΧοτΛࡌͤΔ w "EEUP4JSJϘλϯΛஔ͢Δ w ࣮ͯ͠Έͨ͏͑Ͱͷࢲతߟ w
"EEUP4JSJϘλϯΛஔ͢ΔͱΑ͍ը໘ɺஔ͠ͳ͍΄͏͕Α͍ը໘ w ఏҊϑϨʔζͷબͼ͔ͨ
ΞδΣϯμ w 4JSJ4IPSUDVUT࠷খ࣮ w 4QPUMJHIUͷl4JSJ͔ΒͷఏҊzʹγϣʔτΧοτΛࡌͤΔ w "EEUP4JSJϘλϯΛஔ͢Δ w ࣮ͯ͠Έͨ͏͑Ͱͷࢲతߟ w
"EEUP4JSJϘλϯΛஔ͢ΔͱΑ͍ը໘ɺஔ͠ͳ͍΄͏͕Α͍ը໘ w ఏҊϑϨʔζͷબͼ͔ͨ
࠷খ࣮ͱ 4JSJ4IPSUDVUTࣗମʹ࣮ํ๏͕େ͖͘௨Γ͋Δ w *OUFOUT*OUFOUT6*Λ༻͍Δ w ΞϓϦʹͯ܁Γฦ͠ߦ͏ಈ࡞Λ༷ʑͳΛड͚औΓͭͭ࠶ݱՄೳ w /46TFS"DUJWJUZΛ༻͍Δ w ಛఆͷը໘Λ։͍ͨঢ়ଶͷΞϓϦΛىಈ͢ΔͳͲɺ୯७ͳಈ࡞Λ࠶ݱՄೳ
࠷খ࣮ͱ 4JSJ4IPSUDVUTࣗମʹ࣮ํ๏͕େ͖͘௨Γ͋Δ w *OUFOUT*OUFOUT6*Λ༻͍Δ w ΞϓϦʹͯ܁Γฦ͠ߦ͏ಈ࡞Λ༷ʑͳΛड͚औΓͭͭ࠶ݱՄೳ w /46TFS"DUJWJUZΛ༻͍Δ w ಛఆͷը໘Λ։͍ͨঢ়ଶͷΞϓϦΛىಈ͢ΔͳͲɺ୯७ͳಈ࡞Λ࠶ݱՄೳ
࣮ *OGPQMJTUʹΞΫγϣϯͷ*%Λఆٛ <plist version="1.0"> <dict> <!-- தུ --> <key>NSUserActivityTypes</key> <array>
<string>$(BUNDLE_ID).materialBarcodeRead</string> <string>$(BUNDLE_ID).viewQRCode</string> </array> </dict> </plist>
࣮ ֘ͷΞΫγϣϯΛߦ͏/46TFS"DUJWJUZΦϒδΣΫτΛੜ ˞ҎԼόʔίʔυಡΈऔΓΧϝϥը໘༻ͷΦϒδΣΫτੜॲཧ import Intents struct MaterialBarcodeReadAction { static var
actionName: String { return "\(bundleId).materialBarcodeRead" } static var userActivity: NSUserActivity { let userActivity = NSUserActivity(activityType: actionName) userActivity.persistentIdentifier = actionName userActivity.title = "ڭࡐͷόʔίʔυΛಡΈऔΔ" return userActivity } }
࣮ ֘ͷΞΫγϣϯͰ։͘6*7JFX$POUSPMMFSΦϒδΣΫτΛઃఆ final class MaterialBarcodeReaderViewController: UIViewController { override func viewDidLoad()
{ super.viewDidLoad() let activity = MaterialBarcodeReadAction.userActivity userActivity = activity } }
࣮ "QQ%FMFHBUFʹϋϯυϧ࣌ͷॲཧΛ࣮ func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler:
@escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { switch userActivity.activityType { case MaterialBarcodeReadAction.actionName: // όʔίʔυಡΈऔΓΧϝϥը໘දࣔ return true case ViewQRCodeAction.actionName: // QRίʔυը໘දࣔ return true default: return false } }
࠷খ࣮·Ͱࡁ·ͤΔͱʜ ˠlγϣʔτΧοτzΞϓϦʹͯར༻ՄೳͳΞΫγϣϯͱͯ͠બࢶ͕දࣔ͞ΕΔ ˞4JSJ4IPSUDVUT࣮ͨ͠ޙͷରը໘ΛճҎ্։͍͍ͯΔඞཁ͋Γ
γϣʔτΧοτͷొํ๏ J04࣌
None
γϣʔτΧοτΪϟϥϦʔ͔ΒొՄೳ
ΞδΣϯμ w 4JSJ4IPSUDVUT࠷খ࣮ w 4QPUMJHIUͷl4JSJ͔ΒͷఏҊzʹγϣʔτΧοτΛࡌͤΔ w "EEUP4JSJϘλϯΛஔ͢Δ w ࣮ͯ͠Έͨ͏͑Ͱͷࢲతߟ w
"EEUP4JSJϘλϯΛஔ͢ΔͱΑ͍ը໘ɺஔ͠ͳ͍΄͏͕Α͍ը໘ w ఏҊϑϨʔζͷબͼ͔ͨ
࣮ /46TFS"DUJWJUZΦϒδΣΫτʹͯఏҊʹࡌͤΔΛઃఆ #if canImport(CoreSpotlight) import CoreSpotlight import MobileCoreServices #endif /*
লུ */ static var userActivity: NSUserActivity { let userActivity = NSUserActivity(activityType: actionName) userActivity.persistentIdentifier = actionName userActivity.title = "ڭࡐͷόʔίʔυΛಡΈऔΔ" userActivity.isEligibleForPrediction = true #if canImport(CoreSpotlight) let attributes = CSSearchableItemAttributeSet(itemContentType: kUTTypeContent as String) attributes.title = "ڭࡐͷόʔίʔυΛಡΈऔΔ" attributes.contentDescription = "ొ͍ͨ͠ڭࡐͷόʔίʔυΛಡΈऔΕ·͢" userActivity.contentAttributeSet = attributes #endif return userActivity }
#if canImport(CoreSpotlight) import CoreSpotlight import MobileCoreServices #endif /* লུ */
static var userActivity: NSUserActivity { let userActivity = NSUserActivity(activityType: actionName) userActivity.persistentIdentifier = actionName userActivity.title = "ڭࡐͷόʔίʔυΛಡΈऔΔ" userActivity.isEligibleForPrediction = true #if canImport(CoreSpotlight) let attributes = CSSearchableItemAttributeSet(itemContentType: kUTTypeContent as String) attributes.title = "ڭࡐͷόʔίʔυΛಡΈऔΔ" attributes.contentDescription = "ొ͍ͨ͠ڭࡐͷόʔίʔυΛಡΈऔΕ·͢" userActivity.contentAttributeSet = attributes #endif return userActivity } ࣮ /46TFS"DUJWJUZΦϒδΣΫτʹͯఏҊʹࡌͤΔΛઃఆ *NQPSUΛՃ 4QPUMJHIUͰ4JSJ͔ΒͷఏҊͱͯ͠දࣔΛ༗ޮʹ͠ɺ දࣔ͢ΔΛઃఆ
࣮ ֘7JFX$POUSPMMFSΛ։͍ͨࡍʹ௨͢Δ final class MaterialBarcodeReaderViewController: UIViewController { override func viewDidLoad()
{ super.viewDidLoad() let activity = MaterialBarcodeReadAction.userActivity userActivity = activity activity.becomeCurrent() } }
࣮ ֘7JFX$POUSPMMFSΛ։͍ͨࡍʹ௨͢Δ final class MaterialBarcodeReaderViewController: UIViewController { override func viewDidLoad()
{ super.viewDidLoad() let activity = MaterialBarcodeReadAction.userActivity userActivity = activity activity.becomeCurrent() } } ࣮ࡁΈͷ/46TFS"DUJWJUJZΦϒδΣΫτͰ࠶ݱͰ͖Δ ૢ࡞Λͨ͜͠ͱΛ௨
௨ͷ࣮·Ͱࡁ·ͤΔͱʜ ˠ֘ͷը໘ΛΑ͘͏߹ɺ ɹl4JSJ͔ΒͷఏҊzʹදࣔ͞ΕΔ ˞બ͢Δͱɺը໘ʹભҠ͢Δ͕γϣʔτΧοτ ͷՃෆՄ ˞σόοάʹɺͷઃఆσϕϩού %JTQMBZ3FDFOU4IPSUDVUTΛ0/
ΞδΣϯμ w 4JSJ4IPSUDVUT࠷খ࣮ w 4QPUMJHIUͷl4JSJ͔ΒͷఏҊzʹγϣʔτΧοτΛࡌͤΔ w "EEUP4JSJϘλϯΛஔ͢Δ w ࣮ͯ͠Έͨ͏͑Ͱͷࢲతߟ w
"EEUP4JSJϘλϯΛஔ͢ΔͱΑ͍ը໘ɺஔ͠ͳ͍΄͏͕Α͍ը໘ w ఏҊϑϨʔζͷબͼ͔ͨ
࣮ ϘλϯΛஔ͢Δ final class MaterialBarcodeReaderViewController: UIViewController { override func viewDidLoad()
{ super.viewDidLoad() let activity = MaterialBarcodeReadAction.userActivity userActivity = activity activity.becomeCurrent() let addToSiriButton = INUIAddVoiceShortcutButton(style: .automaticOutline) addToSiriButton.shortcut = INShortcut(userActivity: activity) addToSiriButton.delegate = self view.addSubview(addToSiriButton) } }
࣮ ϘλϯΛஔ͢Δ final class MaterialBarcodeReaderViewController: UIViewController { override func viewDidLoad()
{ super.viewDidLoad() let activity = MaterialBarcodeReadAction.userActivity userActivity = activity activity.becomeCurrent() let addToSiriButton = INUIAddVoiceShortcutButton(style: .automaticOutline) addToSiriButton.shortcut = INShortcut(userActivity: activity) addToSiriButton.delegate = self view.addSubview(addToSiriButton) } } "EEUP4JSJϘλϯͷΦϒδΣΫτΛੜ γϣʔτΧοτͱͯ͠ొ͢Δૢ࡞ "EEUP4JSJϘλϯΛԡԼͨ͠ࡍʹ ͜Ε͔Βදࣔ͢Δը໘ΦϒδΣΫτΛड͚औΔͨΊઃఆ
࣮ ϘλϯΛԡԼޙͷॲཧΛ࣮ extension MaterialBarcodeReaderViewController: INUIAddVoiceShortcutButtonDelegate { func present(_ addVoiceShortcutViewController: INUIAddVoiceShortcutViewController,
for addVoiceShortcutButton: INUIAddVoiceShortcutButton) { addVoiceShortcutViewController.delegate = self present(addVoiceShortcutViewController, animated: true, completion: nil) } func present(_ editVoiceShortcutViewController: INUIEditVoiceShortcutViewController, for addVoiceShortcutButton: INUIAddVoiceShortcutButton) { editVoiceShortcutViewController.delegate = self present(editVoiceShortcutViewController, animated: true, completion: nil) } }
None
࣮ 4JSJ4IPSUDVUTͷՃɾฤूྃ࣌ͷॲཧΛ࣮ Ճ extension MaterialBarcodeReaderViewController: INUIAddVoiceShortcutViewControllerDelegate { func addVoiceShortcutViewController( _
controller: INUIAddVoiceShortcutViewController, didFinishWith voiceShortcut: INVoiceShortcut?, error: Error?) { controller.dismiss(animated: true, completion: nil) } func addVoiceShortcutViewControllerDidCancel( _ controller: INUIAddVoiceShortcutViewController) { controller.dismiss(animated: true, completion: nil) } }
࣮ 4JSJ4IPSUDVUTͷՃɾฤूྃ࣌ͷॲཧΛ࣮ ฤू extension MaterialBarcodeReaderViewController: INUIEditVoiceShortcutViewControllerDelegate { func editVoiceShortcutViewController( _
controller: INUIEditVoiceShortcutViewController, didUpdate voiceShortcut: INVoiceShortcut?, error: Error?) { controller.dismiss(animated: true, completion: nil) } func editVoiceShortcutViewController( _ controller: INUIEditVoiceShortcutViewController, didDeleteVoiceShortcutWithIdentifier deletedVoiceShortcutIdentifier: UUID) { controller.dismiss(animated: true, completion: nil) } func editVoiceShortcutViewControllerDidCancel(_ controller: INUIEditVoiceShortcutViewController) { controller.dismiss(animated: true, completion: nil) } }
"EEUP4JSJϘλϯ͕͋Δͱʜ ˠࣗͷΞϓϦ͔Β4JSJγϣʔτΧοτΛՃ͢Δಋઢ͕Ͱ͖Δ ˠ࣮ࡍʹͦͷը໘ΛΑ͘ར༻͢ΔϢʔβʔ͕ݟ͚ͭ͘͢ͳΔ
ΞδΣϯμ w 4JSJ4IPSUDVUT࠷খ࣮ w 4QPUMJHIUͷl4JSJ͔ΒͷఏҊzʹγϣʔτΧοτΛࡌͤΔ w "EEUP4JSJϘλϯΛஔ͢Δ w ࣮ͯ͠Έͨ͏͑Ͱͷࢲతߟ w
"EEUP4JSJϘλϯΛஔ͢ΔͱΑ͍ը໘ɺஔ͠ͳ͍΄͏͕Α͍ը໘ w ఏҊϑϨʔζͷબͼ͔ͨ
"EEUP4JSJϘλϯΛ ஔ͢ΔͱΑ͍ը໘ w ஔ͢Δ͜ͱͰຊདྷͷׂΛશ͏͢Δͷʹࢧো͕ग़ͳ͍ w ͱͱ༨ന͕ेʹ͋ΓɺӬଓతʹදࣔ͠ଓ͚ͯͳ͍ w Ϋογϣϯϖʔδͱͯ͠ผը໘ΛڬΉܗͰදࣔͯࠩ͠͠ࢧ͑ͳ͍ ஔ͠ͳ͍΄͏͕Α͍ը໘ w
ஔ͢ΔͱຊདྷͷׂΛશ͏͢ΔͨΊͷྖҬ͕ڱ͘ͳΔը໘ w ༷ʑͳใΛݟΔͨΊͷը໘ͳͲ
ΞδΣϯμ w 4JSJ4IPSUDVUT࠷খ࣮ w 4QPUMJHIUͷl4JSJ͔ΒͷఏҊzʹγϣʔτΧοτΛࡌͤΔ w "EEUP4JSJϘλϯΛஔ͢Δ w ࣮ͯ͠Έͨ͏͑Ͱͷࢲతߟ w
"EEUP4JSJϘλϯΛஔ͢ΔͱΑ͍ը໘ɺஔ͠ͳ͍΄͏͕Α͍ը໘ w ఏҊϑϨʔζͷબͼ͔ͨ
ఏҊϑϨʔζͱ /46TFS"DUJWJUZͷTVHHFTUFE*OWPDBUJPO1ISBTF import Intents struct MaterialBarcodeReadAction { static var actionName:
String { return "\(bundleId).materialBarcodeRead" } static var userActivity: NSUserActivity { let userActivity = NSUserActivity(activityType: actionName) userActivity.persistentIdentifier = actionName userActivity.title = “ڭࡐͷόʔίʔυΛಡΈऔΔ” userActivity.suggestedInvocationPhrase = "όʔίʔυΛಡΈऔΔ" return userActivity } }
ఏҊϑϨʔζ͕දࣔ͞ΕΔॴ w "EEUP4JSJϘλϯԡԼޙ w γϣʔτΧοτΪϟϥϦʔܦ༝ ͰͷγϣʔτΧοτొ ԻίϚϯυཝͷσϑΥϧτɻೖΕ ͓ͯ͘ͱϢʔβʔࣗͰʮԿͯݺͼ ͔͚Α͏ʁʯͱߟ͑ΔखؒΛল͍ͯొ Ͱ͖ͯศར
ఏҊϑϨʔζ͕දࣔ͞ΕΔॴ w "EEUP4JSJϘλϯԡԼޙ w γϣʔτΧοτΪϟϥϦʔܦ༝ ͰͷγϣʔτΧοτొ ԻίϚϯυཝͷσϑΥϧτɻೖΕ ͓ͯ͘ͱϢʔβʔࣗͰʮԿͯݺͼ ͔͚Α͏ʁʯͱߟ͑ΔखؒΛল͍ͯొ Ͱ͖ͯศར
ˠ4JSJ͕ฉ͖औΓͮΒ͍ݴ༿ɺϢʔβʔ͕͍ʹ͍͘ݴ༿ΛΛઃఆͯ͠͠·͏ͱɺΘΕͳ͘ͳΔ
ΑΓϢʔβʔ͕ར༻͍͢͠ ϑϨʔζΛબͿʹʁ
w ଞΞϓϦͷγϣʔτΧοτͱॏෳ͠ͳ͍ w ݕূ͢Δ w ݕূ͢Δڥ
ଞΞϓϦͷྨࣅγϣʔτΧοτͱॏෳͤ͞ͳ͍ w ಉ͡ʹڞଘ͍ͯ͠ΔՄೳੑ͕ߴ͍ΞϓϦͷγϣʔτΧοτΛ֬ೝ w ྨࣅͷγϣʔτΧοτ͕͋Δ߹ɺڞଘͯ͠ݺͼ͚Ͱ͖ΔΑ͏ΞϓϦ ໊ΛؚΊΔͷ͕Φεεϝ w ΞϓϦ໊༏ઌͯ͠ฉ͖औΓͯ͘͠ΕΔ༷ࢠ w ΞϓϦ໊ͰུশͳͲཁݕূ
ݕূ͢Δ w αϙʔτ͍ͯ͠Δ04όʔδϣϯͷ͏ͪɺҰ൪͍ϝδϟʔόʔδϣϯͷ Ͱ֬ೝ w 04όʔδϣϯ͕ਐΉຖʹฉ͖औΓੑೳ͕େ্͖͍ͯ͘͠Δ w αϙʔτ͍ͯ͠Δ04όʔδϣϯͷൣғͰۃྗεϖοΫͷ͍Ͱ֬ೝ w ϋʔυ໘Ͱฉ͖औΓੑೳ͕ҟͳΔ
ݕূ͢Δڥ w Ͱ͖Δ͚ͩϢʔβʔ͕࣮ࡍʹར༻͠͏Δڥʹ͍ۙঢ়ଶͰࢼ͢ w εϙʔπδϜͰར༻͢ΔΞϓϦͳΒ࣮ࡍʹ͍͖࣋ͬͯฉ͖औΓΛࢼ͢ͳͲ w صͷ্ʹฏஔ͖ͨ͠ঢ়ଶͰࢼ͢ w ֯ͷ໘ͷ߹͔Β͔ɺखͰ࣋ͭΑΓҙਤ͠ͳ͍ࡶԻ͕रΘ Ε͕ͪ
Α͍4JSJ4IPSUDVUTରԠΛ
ࢀߟ /46TFS"DUJWJUZUJUMF /46TFS"DUJWJUZDPOUFOU"UUSJCVUF4FUDPOUFOU%FTDSJQUJPO γϣʔτΧοτ 4JSJ͔ΒͷఏҊ 4JSJʹՃ /46TFS"DUJWJUZDPOUFOU"UUSJCVUF4FUUIVNCOBJM%BUB /46TFS"DUJWJUZTVHHFTUFE*OWPDBUJPO1ISBTF ᶃ ᶃ
ᶃ ᶃ ᶃ ᶄ ᶄ ᶄ ᶅ ᶅ ᶅ ᶅ ᶅ ᶆ ᶆ
ࢀߟ w "EEJOH6TFS*OUFSBDUJWJUZXJUI4JSJ4IPSUDVUTBOEUIF4IPSUDVUT"QQ w IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOTJSJLJU BEEJOH@VTFS@JOUFSBDUJWJUZ@XJUI@TJSJ@TIPSUDVUT@BOE@UIF@TIPSUDVUT@BQ Q w %FTJHOJOH(SFBU4IPSUDVUT w
IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED
ࢀߟ w 4PVQ$IFG αϯϓϧίʔυ w IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOTJSJLJU TPVQ@DIFG@BDDFMFSBUJOH@BQQ@JOUFSBDUJPOT@XJUI@TIPSUDVUT w 4JSJ4IPSUDVUT·ͱΊ
w IUUQTLVSPIBUFOBCMPHDPNFOUSZ w J1IPOFJ1BEͰγϣʔτΧοτ"QQΛ͏c"QQMF w IUUQTTVQQPSUBQQMFDPNKBKQ)5