あなたがレストラン予約アプリケーション、またはユーザーのために予約を入れるアプリケーション(フライト、列車、チケット)を開発している場合、予約の詳細についてSiriに通知することができます。
この記事では、予約アプリのデモを作成します。ユーザーが予約を行うと、アプリが予約情報をSiriに送信し、Siriは予約情報をカレンダーに追加するようユーザーに促します。予約が閲覧されると、アプリが予約時間を更新します。システムカレンダーアプリが予約情報の更新について、ユーザーに通知するのが確認できます。
利点
Siriに通知することで、ユーザーはイベントをカレンダーに追加するための通知を即座に受け取ります。
イベント会場の詳細情報もSiriによって自動的に入力されます。
また、Siriは予約前に関連情報をユーザーの画面に表示します。
もう一つのメリットは、(予約IDに基づいて)特定の予約イベントに関する最新情報がアプリ上で更新されると、Siriがイベントの詳細を自動的に更新することです。アプリ上で既存の予約に変更があると、システムカレンダーアプリに通知バッジが表示されます。
import intents
Github: https://github.com/mszmagic/SiriReservationSample
ステップ 1. 期間を定める
まず、予約が続行する期間を定める関数を書きます。実演アプリケーションでは、レストランの予約を2時間に設定しました。
private func getReservationPromoteDateRange(_ item: Reservation) -> INDateComponentsRange {
let calendar = Calendar.autoupdatingCurrent
// 予約時間の2時間後まで、予約の詳細を閲覧するようユーザーに宣伝しましょう
let promoteDate_end = calendar.date(byAdding: .hour, value: 2, to: item.bookedTime) ?? item.bookedTime
let promoteDate_end_components = calendar.dateComponents(in: TimeZone.autoupdatingCurrent, from: promoteDate_end)
let promoteDate_start = item.bookedTime
let promoteDate_start_components = calendar.dateComponents(in: TimeZone.autoupdatingCurrent, from: promoteDate_start)
//
return .init(start: promoteDate_start_components, end: promoteDate_end_components)
}
ステップ 2. 予約名を定める
予約項目に対して固有の識別名を作成する必要があります。
let reservation_item = INSpeakableString(vocabularyIdentifier: item.reservationID, spokenPhrase: "\(item.restaurantName)の予約", pronunciationHint: nil)
ステップ 3. 予約を見る時に実行するアクションを定める
それから、ユーザーが予約を見たい時に実行するアクションを定めます。URLを提供することもできます。これらの情報は、ユーザーが特定の予約項目を見たい時に、どのようなアクションを実行するかをSiriが認識するために使用されます:
private func getViewReservationDetailsAction(_ item: Reservation) -> INReservationAction {
let viewDetailsAction = NSUserActivity(activityType: "com.example.SiriReservationSample.viewReservationDetails")
let reservationDateStr = DateFormatter.localizedString(from: item.bookedTime, dateStyle: .short, timeStyle: .short)
viewDetailsAction.title = "\(item.restaurantName)における\(reservationDateStr)での予約状況の詳細を表示します"
viewDetailsAction.userInfo = ["reservationID" : item.reservationID]
viewDetailsAction.requiredUserInfoKeys = ["reservationID"]
viewDetailsAction.webpageURL = generateReservationURL(item)
return .init(type: .checkIn,
validDuration: getReservationPromoteDateRange(item),
userActivity: viewDetailsAction)
}
ステップ4. 予約オブジェクトを決めてください
let reservation = INRestaurantReservation(itemReference: reservation_item,
reservationNumber: item.reservationID,
bookingTime: item.bookedTime,
reservationStatus: item.reservation_status,
reservationHolderName: item.personName,
actions: reservation_actions,
url: generateReservationURL(item),
reservationDuration: getReservationPromoteDateRange(item),
partySize: item.reservation_partySize,
restaurantLocation: item.restruantLocation)
| Variable name | Explanation |
|---|---|
| itemReference | 参照IDオブジェクト reservation_item
|
| reservationNumber | 予約ID |
| bookingTime | ユーザーがこの予約を入れる時間 |
| reservationStatus | 予約状況 |
| reservationHolderName | この予約を行なった人物の名前 |
| actions | この例における関数 getViewReservationDetailsAction() のアウトプット |
| url | ユーザーが予約詳細へアクセスするためのURLアドレス(ウェブページ) |
| reservationDuration | 予約の開始と終了を定めてください。getReservationPromoteDateRange() 機能の出力 |
| partySize | この予約の対象人数 |
| restaurantLocation | レストランの所在地 CLPlacemark
|
ステップ5.予約についてシステムに入力してください。
ここで、予約についてシステムに入力する必要があります。
let intent = INGetReservationDetailsIntent(reservationContainerReference: reservation_item, reservationItemReferences: nil)
let response = INGetReservationDetailsIntentResponse(code: .success, userActivity: nil)
response.reservations = [reservation]
let interaction = INInteraction(intent: intent, response: response)
interaction.donate(completion: completionHandler)
これで、カレンダーのイベントに追加するためのSiriのメッセージがユーザーに表示されます。
関数を呼び出すタイミング
ユーザーが予約を閲覧するたびに(情報が変更されていなくても)上記の関数を呼び出す必要があります。予約の詳細が変更された場合は、Siriがカレンダーアプリを通じてユーザーに通知します。
なお、1つの予約に対してご自分の予約IDが同じであることを確認することが重要です。
ステップ6. NSUserActivityTypes
プロジェクトの設定から Info タブに移動し、サポートされているアクティビティタイプの情報を追加します。上のコードでは、アクティビティタイプとして com.example.SiriReservationSample.viewReservationDetails を使用しています。
ステップ 7. Siriでのアプリケーションの起動を処理
ユーザーが予約の閲覧を希望する場合、Siriでアプリケーションを起動する事ができます。
SceneDelegate.swift ファイル内に次の関数を追加してください:
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if userActivity.activityType == "INGetReservationDetailsIntent" {
//
}
}
こちらが予約IDをフェッチする方法です:
if let userActivity = notificationObject.object as? NSUserActivity,
let intentObject = userActivity.interaction?.intent as? INGetReservationDetailsIntent,
let reservationName = intentObject.reservationItemReferences?.first,
let reservationID = reservationName.vocabularyIdentifier {
DispatchQueue.main.async {
self.viewingReservationID = .init(reservationID: reservationID)
}
}
userInfo プロパティの利用を試みましたが、そこには、予約IDは含まれていないようです。つきましては、代わりに上記のコードを使って予約IDを取得してください
以前のコードの設定:
let reservation_item = INSpeakableString(vocabularyIdentifier: item.reservationID, spokenPhrase: "\(item.restaurantName)の予約", pronunciationHint: nil)
従って、変数 vocabularyIdentifier にアクセスすると、item.reservationID が得られます。
