
Salah satu fitur iOS 12 yang berguna (menurut saya) yang diperkenalkan di WWDC 2018 adalah Siri Shortcuts .
Pintasan ( pintasan ) - perintah cepat, cara singkat untuk melakukan tindakan apa pun yang melewati skrip standar.
Di aplikasi Anda, Anda dapat mengambil pintasan untuk beberapa tindakan. Mempelajari bagaimana dan kapan pengguna mengimplementasikannya, Siri memulai dengan cerdas, pada waktu dan tempat yang tepat, untuk menawarkan kepadanya pintasan ini dan, yang paling penting, pengguna dapat memanggil mereka dengan frasa yang akan dilampirkan padanya! Di bawah kucing lebih banyak.
Bagaimana cara kerjanya
Kami menggunakan aplikasi yang, dengan tindakan tertentu, membuat dan mengirimkan pintasan ke sistem.
Anda dapat melihat pintasan ini di Pengaturan → Siri dan Cari .

Tangkapan layar di atas menunjukkan tiga pintasan terakhir yang ditangkap sistem dari berbagai aplikasi. Jika kita mengklik tombol “Lebih banyak jalan pintas”, kita akan melihat semua jalan pintas yang dikirimkan ke sistem oleh setiap aplikasi.
Dengan pengaturan tertentu dalam kode pembuatan pintasan, Siri akan menawarkan pintasan ini kepada pengguna di layar yang terkunci, di pusat notifikasi dan pencarian, dengan fokus pada seberapa sering kita menggunakan tindakan ini, pada jam berapa, pada hari apa dalam seminggu, dan di mana faktor-faktor lainnya.
Sebagai contoh, jika pada Jumat malam Anda biasanya mencari ATM, kemudian setelah dilatih, Siri akan menawarkan Anda jalan pintas dengan tindakan ini pada Jumat malam.

Kita dapat menambahkan perintah suara ke setiap pintasan jika kita mengeklik ikon " + ".
Kami mengucapkan perintah suara, tekan "Selesai", dan sekarang kita dapat melakukan tindakan di belakang pintasan menggunakan suara melalui Siri. Ternyata pengguna akan dapat melakukan fungsionalitas aplikasi Anda melalui Siri tanpa membuka aplikasi itu sendiri. Pintasan dengan frasa tersebut disimpan dalam "Pintasan saya".
Membuat Pintasan
Untuk pengembangan, kita akan memerlukan Xcode 10 dan iOS 12. Pada saat penulisan, keduanya berada pada tahap Beta .
Pintasan dapat dibuat baik melalui NSUserActivity
atau melalui Intent
.
Kasus pertama:
Pengguna mengklik pintasan, yang melewati perintah dengan parameter ( NSUserActivity
) ke aplikasi kami, dan memutuskan bagaimana perintah ini harus diproses (buka jendela kurs USD saat ini, atau jendela pesanan pizza favorit kami). Ini adalah jalan pintas Spotlight tua yang baik yang kita semua tahu, tetapi ditawarkan dengan cerdas oleh Siri.
Kasus kedua:
Pintasan yang dibuat melalui Intent
lebih menarik - pintasan memungkinkan Anda untuk menjalankan perintah langsung di antarmuka Siri tanpa meluncurkan aplikasi Anda. Sebelumnya, perangkat Intent
sangat sulit untuk Apple: mentransfer uang, mengirim pesan, dan lainnya . Sekarang, kami para pengembang memiliki kesempatan untuk membuat Intent
kami!
Terlepas dari bagaimana cara pintas dibuat, ia melewati 3 tahap siklus hidup:
- Pengumuman ( Tentukan )
- Pengiriman ke sistem ( Sumbang )
- Diproses dengan aplikasi ( Menangani )

Penelitian saya menunjukkan bahwa satu aplikasi dapat mengirimkan tidak lebih dari 20 pintasan ke sistem.
Selanjutnya kita akan mempertimbangkan bagaimana memberi aplikasi kita kemampuan untuk membuat cara pintas dan bagaimana cara bekerja dengan mereka di dalamnya.
Membuat Pintasan Melalui NSUserActivity
Mari kita menganalisis yang pertama, jenis cara pintas sederhana yang terbuka melalui NSUserActivity
.
Misalnya, dalam aplikasi bank seluler, kami memiliki layar pencarian ATM dan saya sering mencarinya. Untuk sampai ke layar dengan kartu ATM, saya harus meluncurkan aplikasi, buka tab "Lainnya" di tab, pilih bagian "Info" dan klik tombol "ATM" di sana.
Jika kita membuat pintasan yang langsung mengarah ke layar ini, pengguna akan dapat masuk ke dalamnya dengan satu sentuhan ketika Siri menawarkannya kepadanya, misalnya, pada layar yang terkunci.
Nyatakan pintasan
Langkah pertama adalah mendeklarasikan tipe seperti NSUserActivity
kami (kami dapat mengatakan bahwa ini adalah pengenalnya) di info.playlist :
<key>NSUserActivityTypes</key> <array> <string>ru.tinkoff.demo.show-cashMachine</string> </array>
Diumumkan
Kirimkan pintasan ke sistem (Sumbang)
Setelah deklarasi, kita dapat membuat NSUserActivity
dalam kode aplikasi kita dengan tipe yang kita atur di info.playlist :
let activity = NSUserActivity(activityType: "ru.tinkoff.demo.show-cashMachine")
Agar aktivitas masuk ke daftar pintasan sistem, itu harus diatur ke title
, dan setel properti isEligibleForSearch
menjadi true
. Properti lain tidak diperlukan untuk menambahkan pintasan, tetapi keberadaannya membuat pintasan lebih mudah dibaca dan ramah pengguna.
Api! NSUserActivity
adalah, untuk mengirimkannya ke sistem, ia masih harus mengambil langkah terakhir.
ViewConroller
memiliki properti userActivity
, yang kami perlukan untuk menetapkan activity
dibuat di atas:
self.userActivity = activity
Segera setelah baris ini dieksekusi, jalan pintas akan dibuat dari aktivitas ini. Ini akan dikirimkan ke sistem dan ditampilkan dalam pengaturan Siri ( Pengaturan → Siri dan Pencarian ). Kemudian Siri akan dapat menawarkannya kepada pengguna, dan pengguna akan dapat menetapkan perintah suaranya.
Catatan : Dokumentasi Apple mengatakan bahwa alih-alih menugaskan aktivitas ke pengontrol tampilan, itu sudah cukup untuk memanggil metode becomeCurrent()
pada becomeCurrent()
. Namun, tindakan ini tidak mengirimkan aktivitas ke sistem saya dan jalan pintas tidak muncul dalam daftar
Selanjutnya, panggil metode becomeCurrent()
pada objek aktivitas pengguna untuk menandainya sebagai arus, yang menyumbangkan aktivitas ke Siri. Atau, Anda dapat melampirkan objek ke objek UIViewController atau UIResponder, yang juga menandai aktivitas sebagai arus.
Untuk memeriksa apakah semuanya berfungsi, buka Pengaturan> Siri dan cari - pintasan berdasarkan aktivitas kami harus ada dalam daftar.
Memproses Pintasan berdasarkan Aplikasi (Pegangan)
Ketika pengguna menavigasi pintasan dari pusat notifikasi atau mengaktifkannya dengan suara, aplikasi akan dimulai, dan kita harus memproses pintasan ini.
activity
dilemparkan kepada kami di AppDelegate
'metode:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if userActivity.activityType == "ru.tinkoff.demo.show-cashMachine" {
Total
NSUserActivity
NSUserActivity dibuat sebagai berikut:
- Nyatakan tipe (pengidentifikasi)
NSUserActivity
di NSUserActivity
. - Kami membuat
NSUserActivity
dalam kode dan kami mengonfigurasi viewController'
.
Membuat perintah suara dari suatu aplikasi
Jadi, jika pengguna membuka Pengaturan> Siri dan mencari , ia akan melihat daftar pintasannya, yang dibuat oleh berbagai aplikasi, termasuk aplikasi kami. Dengan mengklik " + ", pengguna dapat membuat perintah suara apa saja dan mengaitkannya dengan pintasan yang dipilih. Namun, setiap kali memasuki pengaturan tidak nyaman bagi pengguna, banyak yang bahkan tidak menyadari tentang kemungkinan ini.
Sangat keren bahwa Anda dapat melampirkan perintah suara ke tindakan tertentu langsung di dalam aplikasi.
Misalkan seorang pengguna melakukan beberapa tindakan, itu dikirim ke sistem, ia ingin menyimpannya. Kita dapat menambahkan tombol " tambahkan tindakan ke Siri " (Anda dapat memberi nama dan menggambar tombol sesuka Anda) pada layar aplikasi kami, maka pengguna, dengan mengkliknya, akan dapat mengaitkan tindakan ini dengan perintah suara dari dalam aplikasi tanpa masuk ke pengaturan.
Dengan mengklik tombol, Anda harus membuka layar untuk menambahkan perintah suara ke cara pintas di Siri INUIAddVoiceShortcutViewController
, atau layar untuk mengedit perintah suara INUIEditVoiceShortcutViewController
, jika sudah dibuat. Tindakan yang tidak bereaksi action
tombol tersebut akan kira-kira sebagai berikut:
@IBAction func addToSiriAction() { // 1. , INVoiceShortcutCenter.shared.getAllVoiceShortcuts { (shortcuts, error) in guard error == nil, let shortcuts = shortcuts else { // TODO: Handle error return } // 2. , let donatedShortcut: INVoiceShortcut? = shortcuts.first(where: { (shorcut) -> Bool in return shorcut.__shortcut.userActivity?.activityType == "com.ba" }) if let shortcut = donatedShortcut { // 3. - . // let editVoiceShortcutViewController = INUIEditVoiceShortcutViewController(voiceShortcut: shortcut) editVoiceShortcutViewController.delegate = self self.present(editVoiceShortcutViewController, animated: true, completion: nil) } else { // 4. let shortcut = INShortcut(userActivity: self.userActivity!) let addVoiceShortcutViewController = INUIAddVoiceShortcutViewController(shortcut: shortcut) addVoiceShortcutViewController.delegate = self } } }
Jadi, layar untuk menambahkan dan mengedit perintah suara untuk cara pintas Siri terlihat:

Kita juga harus menerapkan metode delegasi dari viewControllers ini, di mana mereka perlu menyembunyikan dismiss(animated: true, completion: nil)
dan, jika perlu, perbarui layar saat ini. Misalnya, jika sebelumnya ada tombol “tambahkan perintah suara” di layar, maka setelah menambahkan perintah suara, tombol ini akan hilang atau berubah menjadi “edit perintah suara”.
Pintasan Intent
Sejauh ini, kami hanya berbicara tentang cara pintas yang membuka aplikasi dan meneruskan data NSUserActivity
ke NSUserActivity
.
Tetapi kembali ke pintasan yang dibuat melalui Intent
, yang memungkinkan Anda melakukan beberapa tindakan tanpa membuka aplikasi. Di sini kesenangan dimulai.
Bayangkan seorang pengguna memesan pizza favoritnya. Dia akan memesannya berkali-kali kapan pun dia mau, dan dia bahkan menambahkan perintah suara ke pintasan pizza ini - dan ini menyederhanakan hidupnya. Tetapi kita dapat melakukan lebih banyak untuknya - kita dapat memastikan bahwa dengan memberikan perintah suara Siri, sistem tidak membuangnya ke dalam aplikasi, tetapi menampilkan informasi pesanan dan memesan pizza segera di antarmuka Siri! Ini hanya terjadi ketika pengguna tidak perlu membuka aplikasi itu sendiri untuk melakukan beberapa tindakan.
Pertama, buka pengaturan proyek, pilih target utama, tab Capabilities
dan aktifkan akses ke Siri.
Aplikasi kita dapat berinteraksi dengan Siri, tetapi ini tidak terjadi pada kode utama aplikasi, tetapi dalam target-ekstensi yang terpisah Intents Extensions
Untuk memulai, target ini harus dibuat: File → Baru → Target , pilih Intents Extensions . Xcode akan menawarkan untuk membuat ekstensi target lain untuk jendela yang menampilkan tindakan Anda di Siri, jika ada kebutuhan untuk ini, maka kami setuju.

Nyatakan pintasan
Inovasi utama SiriKit di iOS 12 adalah kemampuan untuk membuat Inetnts
Anda, bagi yang sebelumnya.

Untuk melakukan ini, buat file baru: File → Baru → File , pilih SiriKit Intent Definition File dari bagian Resource .

Akibatnya, sebuah file dengan ekstensi .intentdefinition muncul , di mana Anda dapat membuat Intents
Anda sendiri. Kami membuka file, dan di mana tertulis " No Intents " di bagian bawah ada ikon " + " - klik di atasnya. " Niat Baru ". Niat akan muncul dalam daftar yang dapat Anda tambahkan parameter. Dalam hal pemesanan pizza, Anda dapat menambahkan jumlah pizza dan jenis pizza yang dipesan sebagai parameter. Untuk kuantitas kami memilih tipe Integer
, dan untuk tipe pizza kami memilih tipe Custom
, yang dalam kode akan diwakili oleh kelas INObject
.
Sekarang beberapa garis frustrasi:
Pengguna tidak akan dapat mengirimkan parameter yang berbeda ke perintah suara yang disimpan sama. Sayang!

Apa parameter untuk:
Misalkan Anda membuat entitas "Tampilkan nilai %currency
", di mana currency
adalah parameter entitas. Ini tidak berarti bahwa pengguna dapat mengatakan frasa “Tampilkan nilai tukar dolar”, “Tampilkan nilai tukar Bitcoin”, dll. Di luar kotak, ini tidak akan berfungsi seperti itu. Tetapi ini berarti bahwa jika pengguna melihat nilai tukar dolar, pintasan "Tampilkan kurs USD" telah dibuat, maka ketika ia melihat pada nilai tukar Bitcoin, pintasan "Tampilkan kurs BTC" telah dibuat, dll. Dengan kata lain, dia mungkin memiliki beberapa shorkata yang didasarkan pada tujuan yang sama, tetapi dengan parameter yang berbeda. Setiap pintasan, pengguna akan dapat meminta perintah suaranya.
Nah, dengan membuat maksud dalam file .intentdefinition , Xcode akan secara otomatis menghasilkan kelas untuk maksud itu (catatan: itu tidak akan muncul dalam file proyek, tetapi akan tersedia untuk digunakan). File yang dibuat secara otomatis ini hanya akan berada di target yang memiliki file .intentdefinition .
Setelah membuat maksud dalam file .intentdefinition , kita dapat membuat niat kita dalam kode.
let intent = OrderPizzaIntent()
Kirimkan pintasan ke sistem (Sumbang)
Agar entitas ini dimasukkan dalam daftar cara pintas, Anda harus menyematkannya. Untuk melakukan ini, objek INInteraction
dibuat dengan instance niat Anda, dan metode .donate dipanggil pada .donate
ini
let intent = OrderPizzaIntentf() // ... let interaction = INInteraction(intent: intent, response: nil) interaction.donate { (error) in // ... / }
Setelah menjalankan kode ini, pintasan berbasis maksud akan dikirimkan ke sistem dan ditampilkan dalam Pengaturan Siri.
Kami memproses aplikasi pintasan (Menangani)
Langkah selanjutnya adalah memproses maksud ketika pengguna mengkliknya di sirjest Siri atau menyebutnya dengan perintah suara.
Kami telah membuat ekstensi target untuk Siri dan memiliki kelas IntentHandler yang telah dibuat sebelumnya, yang memiliki satu metode tunggal - `` handle (untuk maksud) ``
class IntentHandler: INExtension { override func handler(for intent: INIntent) -> Any { guard intent is OrderPizzaIntent else { fatalError("Unhandled intent type: \(intent)") } return OrderPizzaIntentHandler() } }
Catatan: Jika kompiler tidak melihat kelas maksud Anda, maka Anda belum menambahkan file ekstensi target .intentdefinition untuk Siri.
Dalam metode ini, kami menentukan jenis niat masuk dan untuk setiap jenis kami membuat objek penangan yang akan memproses niat ini. Buat penangan untuk OrderPizzaIntent
kami, dan terapkan protokol OrderPizzaIntentHandling
di dalamnya, yang sudah dihasilkan secara otomatis setelah membuat Intent di .intentdefinition Anda .
Protokol berisi dua metode confirm
dan handle
. Pertama, confirm
disebut di mana semua data diperiksa dan ketersediaan tindakan diperiksa. Kemudian handle
akan bekerja dalam aksi singkat yang akan dilakukan.
public class OrderPizzaIntentHandler: NSObject, OrderPizzaIntentHandling { public func confirm(intent: OrderPizzaIntent, completion: @escaping (OrderPizzaIntentResponse) -> Void) {
Kedua metode ini pasti harus memanggil completion
dengan respons OrderPizzaIntentResponse
(ini juga dibuat secara otomatis), jika tidak, Siri hanya akan menunggu lama dan kemudian memberikan kesalahan.
Jawaban lebih rinci dari Siri
Ada seperangkat kode respons standar yang dibuat secara otomatis - enum OrderPizzaIntentResponseCode
, tetapi mungkin tidak cukup untuk antarmuka yang ramah. Misalnya, pada tahap confirm
, beberapa kesalahan dapat terjadi - pizza telah habis, pizzeria tidak berfungsi saat ini, dll. dan pengguna harus belajar tentang fakta-fakta ini, alih-alih pesan standar "Kesalahan Aplikasi". Ingat kami membuat Intent
di file .intentdefinition ? Bersamaan dengan maksud itu sendiri, Response
di mana Anda dapat menambahkan opsi Anda sendiri untuk kesalahan dan jawaban yang berhasil, dan mengonfigurasinya dengan parameter:

Sekarang kami dapat memberi tahu pengguna lebih banyak kesalahan dan jawaban informatif:
public func confirm(intent: OrderPizzaIntent, completion: @escaping (OrderPizzaIntentResponse) -> Void) { guard let pizzaKindId = intent.kind?.identifier else { // - completion(OrderPizzaIntentResponse(code: .failure, userActivity: nil)) return } if pizzeriaManager.isPizzeriaClosed == true { /// - completion(OrderPizzaIntentResponse(code: .failurePizzeriaClosed, userActivity: nil)) return } else if pizzeriaManager.menu.isPizzaUnavailable(identifier: pizzaKindId) { /// - completion(OrderPizzaIntentResponse(code: .failurePizzaUnavailable(kind: intent.kind), userActivity: nil)) return } // - completion(OrderPizzaIntentResponse(code: .ready, userActivity: nil)) }
Intent
rendering
Jika kami membuat ekstensi target UI Intent Extension , maka kami dapat menggambar tampilan khusus di Siri untuk maksud yang kami butuhkan. Kami memiliki MainInterface.storyboard
dan IntentViewController
di mana kami dapat membuat sketsa desain mereka. Pengontrol tampilan ini mengimplementasikan protokol INUIHostedViewControlling dan tampilan configureView
dalam metode configureView
// Prepare your view controller for the interaction to handle. func configureView(for parameters: Set<INParameter>, of interaction: INInteraction, interactiveBehavior: INUIInteractiveBehavior, context: INUIHostedViewContext, completion: @escaping (Bool, Set<INParameter>, CGSize) -> Void) { // Do configuration here, including preparing views and calculating a desired size for presentation. completion(true, parameters, self.desiredSize) } var desiredSize: CGSize { return self.extensionContext!.hostedViewMaximumAllowedSize }
Agar metode ini dipanggil, Anda perlu menambahkan nama maksud kami ke array NSExtension
-> NSExtensionAttributes
-> IntentsSupported
, yang merujuk pada ekstensi target Intents UI
<key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>IntentsSupported</key> <array> <string>OrderPizzaIntent</string> </array> </dict>
Bergantung pada desain tampilan Anda di Siri dan interaction.intent
yang masuk ke metode, Anda bisa menggambar tampilan ini seperti yang Anda inginkan. Di bawah ini adalah tangkapan layar tentang bagaimana maksud kami di Siri, dalam pencarian, dan pada layar yang terkunci.

Perlu dipertimbangkan bahwa pengguna tidak akan dapat berinteraksi dengan tombol, pengguliran dan kontrol lain pada tampilan Anda, karena metode ini disebut dengan parameter interactiveBehavior = .none
, ini tentu saja memberlakukan sejumlah batasan.
Total
Pintasan berbasis Intent
dapat di-render di antarmuka siri atau di pusat notifikasi dan melakukan tindakan tanpa membuka aplikasi. Untuk membuatnya, Anda perlu:
- Aktifkan Kemampuan untuk Menggunakan Siri
- Buat Intents Extensions dan Intents Extensions UI
- Buat File Definisi Intensi SiriKit
- Kami membuat
Intent
kami di file ini dan menetapkan parameter untuknya. - Buat
IntentHandler
tempat kami menerapkan metode confirm
dan hanlde
Rekomendasi
Kode generik dalam target ekstensi Siri dan aplikasi utama
Jika Anda memiliki kode yang digunakan di target untuk Siri dan di target proyek utama - ada 2 cara untuk mengatasi masalah ini:
- Sorot kelas umum menambahkannya ke kedua target. ( Lihat → Utilites → Tampilkan Inspektur File , di bagian Keanggotaan Target tambahkan tanda centang ke target yang membutuhkan akses ke file yang dipilih)
- Buat satu atau beberapa kerangka kerja target dan ambil kode umum di sana.
Metode yang terakhir lebih disukai, karena Anda kemudian dapat menggunakan kerangka kerja ini di ekstensi dan proyek lain. Perlu juga dicatat bahwa untuk kerangka kerja ini disarankan untuk menetapkan bendera Allow app extension API only
, kemudian, ketika mengembangkan kerangka kerja, kompiler akan bersumpah jika Anda mencoba menggunakan API yang ilegal dalam mengembangkan ekstensi (misalnya, UIApplication
).
Sumber daya bersama dapat digeledah antara target melalui Grup Aplikasi
Debugging
Menguji pintasan akan membantu untuk membantu:
- Pengaturan telepon Pengaturan → Pengembang : Menampilkan Pintasan Terbaru dan Menampilkan Sumbangan pada sakelar Layar Kunci :

- Untuk menguji Intens, Anda dapat segera meluncurkan ekstensi target dengan menentukan dalam Xcode frase yang dibuka dengan Siri. Untuk melakukan ini, pilih skema untuk ekstensi target Siri

Klik pada target ini, klik Edit Skema ...

Di bidang Siri Intent Query , masukkan frasa yang Siri akan memulai, seolah-olah Anda sudah mengatakannya.
Total
Saya mengusulkan untuk berhenti dan merangkum apa yang kami lakukan:
- Pintasan dapat dibuat melalui
NSUserActivity
, atau melalui INIntent
- Pintasan perlu dinyatakan (dinyatakan), dilaporkan ke sistem (donasi), dan diproses (ditangani).
- Anda dapat menambahkan tombol " Tambahkan ke Siri " ke aplikasi, dengan mengklik di mana pengguna dapat menambahkan frasa untuk tindakan dan selanjutnya menyebutnya dengan suaranya.
- Anda dapat membuat
Intents
Anda sendiri di samping built-in. - Melalui
Intents
berbasis Intents Intents
Anda dapat membuat tindakan yang akan dilakukan melalui antarmuka Siri (baik pada layar yang terkunci atau dalam pencarian) tanpa perlu membuka aplikasi itu sendiri.
Dalam dokumentasi Apple ada tautan ke proyek Demo , yang berguna untuk mengunduh dan memfokuskannya selama pengembangan.
Saya ingin menekankan bahwa pada saat penulisan artikel ini adalah API pada tahap beta
. Dan saya sering mengalami masalah dan bug. Selama bekerja, saya secara berkala menemukan hal-hal berikut:
- , Intent Siri, .
- Siri .
- Siri.
Referensi
- WWDC 2018, session 211: Introduction to Siri Shortcuts
- WWDC 2018, session 214: Building for Voice with Siri Shortcuts
- Apple Developer: SiriKit
- Apple Developer: INUIHostedViewControlling
- Demo Soup Chef Apple