Xamarin.iOS'ta Siri Kısayolları

iOS 10'da Apple SiriKit'i tanıtarak Siri ile etkileşim kuran mesajlaşma, VoIP araması, ödemeler, egzersizler, sürüş rezervasyonu ve fotoğraf arama uygulamaları oluşturmayı mümkün hale getirdi.

iOS 11'de SiriKit, daha fazla uygulama türü için destek ve kullanıcı arabirimi özelleştirmesi için daha fazla esneklik kazandı.

iOS 12, Siri Kısayolları'nı ekleyerek tüm uygulama türlerinin işlevlerini Siri'ye sunmalarına olanak sağlar. Siri, belirli uygulama tabanlı görevlerin kullanıcıyla en ilgili olduğu zamanları öğrenir ve kısayollar aracılığıyla olası eylemler önermek için bu bilgiyi kullanır. Bir kısayola dokunulduğunda veya bir sesli komutla çağrılırsa bir uygulama açılır veya arka plan görevi çalıştırılır.

Birçok durumda söz konusu uygulamayı açmadan kullanıcının ortak bir görevi gerçekleştirme becerisini hızlandırmak için kısayollar kullanılmalıdır.

Örnek uygulama: Soup Chef

Siri Kısayollarını daha iyi anlamak için Soup Chef örnek uygulamasına göz atın. Soup Chef, kullanıcıların hayali bir çorba restoranından sipariş vermelerini, sipariş geçmişlerini görüntülemelerini ve Siri ile etkileşim kurarak çorba sipariş ederken kullanılacak ifadeleri tanımlamalarını sağlar.

İpucu

Bir iOS 12 simülatöründe veya cihazında Soup Chef'i test etmeden önce, kısayollarda hata ayıklama yaparken yararlı olan aşağıdaki iki ayarı etkinleştirin:

  • Ayarlar uygulamasında Geliştirici > Görüntüleme Son Kısayolları'nı etkinleştirin.
  • Ayarlar uygulamasında, Kilit Ekranında Geliştirici > Ekran Bağışları'nı etkinleştirin.

Bu hata ayıklama ayarları, iOS kilit ekranında ve arama ekranında yakın zamanda oluşturulan (tahmin edilen) kısayolları bulmayı kolaylaştırır.

Örnek uygulamayı kullanmak için:

  • Soup Chef örnek uygulamasını bir iOS 12 simülatörüne veya cihazına yükleyin ve çalıştırın.
  • + Yeni bir sipariş oluşturmak için sağ üst köşedeki düğmeye tıklayın.
  • Bir çorba türü seçin, miktar ve seçenekleri belirtin ve Sipariş Ver'e dokunun.
  • Sipariş Geçmişi ekranında, ayrıntılarını görüntülemek için yeni oluşturulan siparişe dokunun.
  • Sipariş ayrıntıları ekranının en altında Siri'ye Ekle'ye dokunun.
  • Siparişle ilişkilendirmek için bir ses tümceciği kaydedin ve Bitti'ye dokunun.
  • Soup Chef'i simge durumuna küçültün, Siri'yi çağırın ve kaydettiğiniz sesli ifadeyi kullanarak siparişi yeniden yerleştirin.
  • Siri siparişi tamamladıktan sonra Soup Chef'i yeniden açın ve yeni siparişin Sipariş Geçmişi ekranında listelendiğine dikkat edin.

Örnek uygulama aşağıdakilerin nasıl yapılacağını gösterir:

Info.plist ve Entitlements.plist

Soup Chef kodunu daha derinlemesine incelemeden önce Info.plist ve Entitlements.plist dosyalarına göz atın.

Info.plist

SoupChef projesindeki Info.plist dosyası Paket Tanımlayıcısı'nı olarak com.xamarin.SoupCheftanımlar. Bu paket tanımlayıcısı, bu belgenin ilerleyen bölümlerinde ele alınan Intents and Intents kullanıcı arabirimi uzantılarının paket tanımlayıcıları için ön ek olarak kullanılacaktır.

Info.plist dosyası da aşağıdaki girdiyi içerir:

<key>NSUserActivityTypes</key>
<array>
    <string>OrderSoupIntent</string>
    <string>com.xamarin.SoupChef.viewMenu</string>
</array>

Bu NSUserActivityTypes anahtar/değer çifti, Soup Chef'in bir OrderSoupIntentöğesinin nasıl işleneceğini bildiğini ve NSUserActivity "com.xamarin.SoupChef.viewMenu" değerine sahip ActivityType olduğunu gösterir.

Uzantılarından farklı olarak uygulamanın kendisine geçirilen etkinlikler ve özel amaçlar (yöntemi tarafından ContinueUserActivity aUIApplicationDelegate) içinde AppDelegate işlenir.

Entitlements.plist

SoupChef projesindeki Entitlements.plist dosyası aşağıdaki girdileri içerir:

<key>com.apple.security.application-groups</key>
<array>
    <string>group.com.xamarin.SoupChef</string>
</array>
<key>com.apple.developer.siri</key>
<true/>

Bu yapılandırma, uygulamanın "group.com.xamarin.SoupChef" uygulama grubunu kullandığını gösterir. SoupChefIntents uygulama uzantısı, iki projenin paylaşmasına izin veren aynı uygulama grubunu kullanırNSUserDefaults Veri.

Anahtar, com.apple.developer.siri uygulamanın Siri ile etkileşim kurduğunu gösterir.

Not

SoupChef projesinin derleme yapılandırması Özel Yetkilendirmeleri Entitlements.plist olarak ayarlar.

Bir uygulamayı açmak için NSUserActivity kısayolu kullanma

Belirli içerikleri görüntülemek üzere bir uygulamayı açan bir kısayol oluşturmak için, bir NSUserActivity oluşturun ve kısayolu açmak istediğiniz ekranın görünüm denetleyicisine ekleyin.

NSUserActivity ayarlama

Menü ekranında bir SoupMenuViewControllerNSUserActivity oluşturur ve bunu görünüm denetleyicisinin UserActivity özelliğine atar:

public override void ViewDidLoad()
{
    base.ViewDidLoad();
    UserActivity = NSUserActivityHelper.ViewMenuActivity;
}

Özelliğin UserActivityayarlanması etkinliği Siri'ye bağışlar . Siri bu bağıştan, bu etkinliğin kullanıcı için ne zaman ve nerede ilgili olduğu hakkında bilgi edinecek ve gelecekte daha iyi önermeyi öğrenecektir.

NSUserActivityHelper, SoupKit sınıf kitaplığındaki SoupChef çözümüne dahil edilen bir yardımcı program sınıfıdır. Bir oluşturur NSUserActivity ve Siri ve arama ile ilgili çeşitli özellikleri ayarlar:

public static string ViewMenuActivityType = "com.xamarin.SoupChef.viewMenu";

public static NSUserActivity ViewMenuActivity {
    get
    {
        var userActivity = new NSUserActivity(ViewMenuActivityType)
        {
            Title = NSBundleHelper.SoupKitBundle.GetLocalizedString("ORDER_LUNCH_TITLE", "View menu activity title"),
            EligibleForSearch = true,
            EligibleForPrediction = true
        };

        var attributes = new CSSearchableItemAttributeSet(NSUserActivityHelper.SearchableItemContentType)
        {
            ThumbnailData = UIImage.FromBundle("tomato").AsPNG(),
            Keywords = ViewMenuSearchableKeywords,
            DisplayName = NSBundleHelper.SoupKitBundle.GetLocalizedString("ORDER_LUNCH_TITLE", "View menu activity title"),
            ContentDescription = NSBundleHelper.SoupKitBundle.GetLocalizedString("VIEW_MENU_CONTENT_DESCRIPTION", "View menu content description")
        };
        userActivity.ContentAttributeSet = attributes;

        var phrase = NSBundleHelper.SoupKitBundle.GetLocalizedString("ORDER_LUNCH_SUGGESTED_PHRASE", "Voice shortcut suggested phrase");
        userActivity.SuggestedInvocationPhrase = phrase;
        return userActivity;
    }
}

Özellikle aşağıdaki özelliklere dikkat edin:

  • ayarı EligibleForPredictiontrue Siri'nin bu etkinliği tahmin edip kısayol olarak ortaya çıkarabileceğini gösterir.
  • DiziContentAttributeSet, iOS arama sonuçlarına eklemek için kullanılan bir NSUserActivity standarttırCSSearchableItemAttributeSet.
  • SuggestedInvocationPhrase , Siri'nin kısayola bir tümcecik atarken kullanıcıya olası bir seçenek olarak önereceği bir ifadedir.

NSUserActivity kısayolunu işleme

Bir kullanıcı tarafından çağrılan bir NSUserActivity kısayolu işlemek için iOS uygulamasının sınıfın AppDelegate yöntemini geçersiz kılması ContinueUserActivity ve geçirilen NSUserActivity nesnenin ActivityType alanına göre yanıt vermesi gerekir:

public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
    // ...
    else if (userActivity.ActivityType == NSUserActivityHelper.ViewMenuActivityType)
    {
        HandleUserActivity();
        return true;
    }
    // ...
}

Bu yöntem, menü ekranının segue'sini bulan ve çağıran öğesini çağırır HandleUserActivity:

void HandleUserActivity()
{
    var rootViewController = Window?.RootViewController as UINavigationController;
    var orderHistoryViewController = rootViewController?.ViewControllers?.FirstOrDefault() as OrderHistoryTableViewController;
    if (orderHistoryViewController is null)
    {
        Console.WriteLine("Failed to access OrderHistoryTableViewController.");
        return;
    }
    var segue = OrderHistoryTableViewController.SegueIdentifiers.SoupMenu;
    orderHistoryViewController.PerformSegue(segue, null);
}

NSUserActivity'e tümcecik atama

öğesine tümcecik atamak için NSUserActivityiOS Ayarlar uygulamasını açın ve Siri & Kısayollarımda Ara'yı > seçin. Ardından kısayolu (bu örnekte "Sipariş Öğle Yemeği") seçin ve bir tümcecik kaydedin.

Siri'yi çağırmak ve bu tümceciği kullanmak, Menü ekranında Soup Chef'i açar.

Görevi gerçekleştirmek için özel amaç kısayolu kullanma

Özel amaç tanımlama

Kullanıcının uygulamanızla ilgili belirli bir görevi hızla tamamlayabilmesini sağlayan bir kısayol sağlamak için özel bir amaç oluşturun. Özel amaç, kullanıcının tamamlamak isteyebileceği bir görevi, bu görevle ilgili parametreleri ve görevin yürütülmesinden kaynaklanan olası yanıtları temsil eder. Özel amacın nasıl tanımlandığına bağlı olarak, bu amacı çağırmak uygulamanızı açabilir veya bir arka plan görevi çalıştırabilir.

Özel amaçlar oluşturmak için Xcode 10 kullanın. SoupChef deposunda, özel amaç bir Objective-C proje olan OrderSoupIntentCodeGen içinde tanımlanır. OrderSoup amacını görüntülemek için bu projeyi açın ve Proje Gezgini'ndeIntents.intentdefinition dosyasını seçin.

Aşağıdaki özelliklere dikkat edin:

  • Amacın Bir Sipariş Kategorisivardır. Özel amaçlar için kullanılabilecek önceden tanımlanmış çeşitli kategoriler vardır; özel amacınızın etkinleştireceği görevle en yakın eşleşeni seçin. Bu çözüm bir çorba sipariş uygulaması olduğundan, OrderSoupIntent Order kullanır.
  • Onay onay kutusu Siri'nin görevi yürütmeden önce onay isteyip istememesi gerektiğini gösterir. Soup Chef'te Çorba Sipariş Et amacı için, kullanıcı satın alma işlemi gerçekleştirdiğinden bu seçenek etkinleştirilir.
  • .intentdefinition dosyasının Parameters bölümü, bir kısayolla ilgili parametreleri tanımlar. Çorba siparişi vermek için Çorba Şefinin çorbanın türünü, miktarını ve ilişkili seçenekleri bilmesi gerekir. Her parametrenin bir türü vardır; önceden tanımlanmış bir türle temsil edilemeyen parametre Özel olarak ayarlanır.
  • Kısayol Türleri arabirimi, Siri'nin kısayolunuzu önerirken kullanabileceği çeşitli parametre bileşimlerini açıklar. İlişkili Başlık ve Alt Başlık bölümleri, Siri'nin kullanıcıya önerilen bir kısayol sunarken kullanacağı iletileri tanımlamanızı sağlar.
  • Daha fazla kullanıcı etkileşimi için uygulamayı açmadan yürütülebilecek kısayollar için Arka Plan Yürütmeyi Destekler onay kutusu seçilmelidir.

Özel amaç yanıtları tanımlama

OrderSoup amacının altında iç içe yerleştirilmiş Yanıt öğesi, bir çorba siparişinden kaynaklanan olası yanıtları temsil eder.

OrderSoup amacının yanıt tanımında aşağıdaki özelliklere dikkat edin:

  • Yanıt özellikleri, kullanıcıya geri ileti iletilebilen iletiyi özelleştirmek için kullanılabilir. OrderSoup amacı yanıtı çorba ve waitTime özelliklerine sahiptir.
  • Yanıt Şablonları, bir amacın görevi tamamlandıktan sonra durumu belirtmek için kullanılabilecek çeşitli başarı ve başarısızlık iletilerini belirtir.
  • Başarılı olduğunu belirten yanıtlar için Başarı onay kutusu seçilmelidir.
  • OrderSoupIntent başarı yanıtı, çorba siparişinin ne zaman hazır olacağını açıklayan kolay ve kullanışlı bir ileti sağlamak için çorba ve waitTime özelliklerini kullanır.

Özel amaç için kod oluşturma

Bu özel amaç tanımını içeren Xcode projesinin oluşturulması, Xcode'un özel amaç ve yanıtları ile program aracılığıyla etkileşim kurmak için kullanılabilecek kod oluşturmasına neden olur.

Bu oluşturulan kodu görüntülemek için:

  • AppDelegate.m dosyasını açın.
  • Özel amacın üst bilgi dosyasına içeri aktarma ekleyin: #import "OrderSoupIntent.h"
  • sınıfındaki herhangi bir yöntemde öğesine OrderSoupIntentbir başvuru ekleyin.
  • Sağ tıklayın OrderSoupIntent ve Tanıma Atla'yı seçin.
  • Yeni açılan OrderSoupIntent.h dosyasına sağ tıklayın ve Bulucuda Göster'i seçin.
  • Bu eylem, oluşturulan kodu içeren bir .h ve .m dosyası içeren bir Bulucu penceresi açar.

Bu oluşturulan kod şunları içerir:

  • OrderSoupIntent – Özel amacı temsil eden bir sınıf.
  • OrderSoupIntentHandling – Amacın yürütülmesi gerektiğini onaylamak için kullanılacak yöntemleri ve onu gerçekten yürüten yöntemi tanımlayan bir protokol.
  • OrderSoupIntentResponseCode – Çeşitli yanıt durumlarını tanımlayan bir sabit listesi.
  • OrderSoupIntentResponse – bir amacın yürütülmesine verilen yanıtı temsil eden bir sınıf.

Özel amada bağlama oluşturma

Xcode tarafından oluşturulan kodu bir Xamarin.iOS uygulamasında kullanmak için bunun için bir C# bağlaması oluşturun.

Statik kitaplık ve C# bağlama tanımları oluşturma

SoupChef deposunda OrderSoupIntentStaticLib klasörüne göz atın ve OrderSoupIntentStaticLib.xcodeproj Xcode projesini açın.

Bu Cocoa Touch Statik Kitaplığı projesi, Xcode tarafından oluşturulan OrderSoupIntent.h ve OrderSoupIntent.m dosyalarını içerir.

Statik kitaplık projesi derleme ayarlarını yapılandırma

Xcode Proje Gezgini'nde en üst düzey projeyi (OrderSoupIntentStaticLib) seçin ve Derleme Aşamaları > Derleme Kaynakları'na gidin. OrderSoupIntent.m 'nin (OrderSoupIntent.h'i içeri aktaran) burada listelendiğine dikkat edin. İkiliYi Kitaplıklarla Bağla bölümünde Intents.framework ve Foundation.framework'ün dahil olduğuna dikkat edin. Bu ayarlar gerçekleştiğinde, çerçeve doğru şekilde derlenir.

Statik kitaplığı oluşturma ve C# bağlamaları tanımları oluşturma

Statik kitaplığı oluşturmak ve bunun için C# bağlamaları tanımları oluşturmak için şu adımları izleyin:

  • Xcode tarafından oluşturulan .h ve .m dosyalarından bağlama tanımları oluşturmak için kullanılan araç olan Objective Sharpie'yi yükleyin.

  • Sisteminizi Xcode 10 Komut Satırı Araçları'nı kullanacak şekilde yapılandırın:

    Uyarı

    Seçili Komut Satırı Araçları'nın güncelleştirilmesi, sisteminizde yüklü tüm Xcode sürümlerini etkiler. Soup Chef örnek uygulamasını kullanmayı bitirdiğinizde bu ayarı özgün yapılandırmasına döndürdiğinizden emin olun.

    • Xcode'da Xcode > Tercih Konumları'nı> seçin ve Komut Satırı Araçları'nı sisteminizde kullanılabilen en güncel Xcode 10 yüklemesine ayarlayın.
  • Terminalde OrderSoupIntentStaticLib cd dizinine gidin.

  • Şunu derleyen yazın make:

    • LibOrderSoupIntentStaticLib.a statik kitaplığı
    • Bo output dizininde C# tanımlarını bağlar:
      • ApiDefinitions.cs
      • StructsAndEnums.cs

Bu statik kitaplığı ve ilişkili bağlama tanımlarını destekleyen OrderSoupIntentBindings projesi bu öğeleri otomatik olarak oluşturur. Ancak, yukarıdaki işlemi el ile çalıştırmak beklendiği gibi oluşturulmasını sağlar.

Statik kitaplık oluşturma ve Objective Sharpie kullanarak C# bağlama tanımları oluşturma hakkında daha fazla bilgi için iOS Objective-C kitaplığı bağlama kılavuzuna göz atın.

Bağlama kitaplığı oluşturma

Statik kitaplık ve C# bağlama tanımları oluşturulduğunda, Xamarin.iOS projesinde Xcode tarafından oluşturulan amaçla ilgili kodu kullanmak için gereken kalan parça bir bağlama kitaplığıdır.

Soup Chef deposunda SoupChef.sln dosyasını açın. Bu çözüm, daha önce oluşturulan statik kitaplık için bir bağlama kitaplığı olan OrderSoupIntentBinding'i içerir.

Özellikle bu projenin şunları içerdiğine dikkat edin:

  • ApiDefinitions.cs: Objective Sharpie tarafından daha önce oluşturulan ve bu projeye eklenen bir dosya. Bu dosyanın Derleme Eylemi ObjcBindingApiDefinition olarak ayarlanmıştır.

  • StructsAndEnums.cs : Objective Sharpie tarafından daha önce oluşturulan ve bu projeye eklenen başka bir dosya. Bu dosyanın Derleme Eylemi ObjcBindingCoreSource olarak ayarlanmıştır.

  • Daha önce oluşturulan statik kitaplık olan libOrderSoupIntentStaticLib.a için Yerel Başvuru. Yerel başvuru özelliklerini güncelleştirin ve aşağıdaki değerleri belirtin:

    1. Çerçeveler = Foundation Intents
    2. Akıllı Bağlantı = On
    3. Yüklemeye Zorla = On
    4. Tür = Static

Not

hem ApiDefinitions.cs hem de StructsAndEnums.cs gibi [Watch (5,0), iOS (12,0)]öznitelikler içerir. Objective Sharpie tarafından oluşturulan bu öznitelikler, bu proje için gerekli olmadığından açıklama satırı yapılmıştır.

C# bağlamaları kitaplığı oluşturma hakkında daha fazla bilgi için iOS Objective-C Kitaplığı bağlama kılavuzuna göz atın.

SoupChef projesinin OrderSoupIntentBinding'e bir başvuru içerdiğine dikkat edin; bu da artık C# dilinde içerdiği sınıflara, arabirimlere ve numaralandırmalara erişebileceği anlamına gelir:

  • OrderSoupIntent
  • OrderSoupIntentHandling
  • OrderSoupIntentResponse
  • OrderSoupIntenseResponseCode

Swift çerçevesi oluşturma

Amaç tanımı yerel kodu, yerel projenizin dili kullanılarak varsayılan olarak Xcode tarafından oluşturulur. Intents.intentdefinition dosyasını bir Swift projesinde tanımlarsanız, Xcode size gerekli tüm sınıfları içeren tek bir Swift dosyası oluşturur ve bu dosyayı swift çerçevesi oluşturmak için kullanabilirsiniz.

İpucu

Xcode derleme ayarlarında oluşturulan amaç kodu için istediğiniz dili seçebilirsiniz. Amaç hedefi Derleme Ayarlar > Amaç Tanımı Derleyicisi - Kod Oluşturma'ya gidin ve Swift veya Objective-Cöğesini > seçin. Hedef dilinizle eşleşecek şekilde otomatik olarak da tutabilirsiniz.

Swift çerçevesi oluşturma işlemi, daha önce açıklanana benzer:

  1. Yeni bir Swift çerçeve projesi oluşturun.
  2. Amaç koduyla otomatik olarak oluşturulan Swift dosyasını bu projeye kopyalayın, bu dosyayı burada açıklandığı gibi bulabilirsiniz.
  3. Objective-C Köprü oluşturma üst bilgisini etkinleştirin; böylece çerçeve, keskin üst bilgi dosyasının gerektirdiği Objective-C şekilde otomatik olarak oluşturulur.

Çerçeve oluşturulduktan sonra, Xamarin bağlaması oluşturmak için daha önce açıklanan adımları izleyin. Swift çerçevesi için bağlama oluşturma hakkında daha fazla bilgiyi burada bulabilirsiniz.

Amaç tanım dosyasını çözümünüze ekleme

C# SoupChef çözümünde , SoupKit projesi uygulama ve uzantıları arasında paylaşılan kodu içerir. Intents.intentdefinition dosyası, SoupKit'in Base.lproj dizinine yerleştirilmiştir ve bir İçerik Derleme Eylemine sahiptir. Derleme işlemi bu dosyayı Soup Chef uygulama paketine kopyalar ve burada uygulamanın düzgün çalışması gerekir.

Amaç bağışı yapma

Siri'nin kısayol önermesi için önce kısayolu ne zaman uygun olduğunu anlaması gerekir.

Siri'ye bu anlayışı kazandırmak için Soup Chef , kullanıcı her çorba siparişinde Siri'ye bir amaç verir . Bu bağışa dayanarak - bağışlandığı zaman, nerede bağışlandığı, içerdiği parametreler - Siri gelecekte kısayolu ne zaman önereceğinizi öğrenir.

SoupChef bağış yapmak için sınıfını kullanır SoupOrderDataManager . Bir kullanıcı için çorba siparişi vermek üzere çağrıldığında, PlaceOrder yöntem sırayla öğesini çağırır DonateInteraction:

void DonateInteraction(Order order)
{
    var interaction = new INInteraction(order.Intent, null);
    interaction.Identifier = order.Identifier.ToString();
    interaction.DonateInteraction((error) =>
    {
        // ...
    });
}

Bir amaç getirildikten sonra bir içine INInteractionsarmalanır. INInteraction verilen birIdentifier siparişin benzersiz kimliğiyle eşleşir (daha sonra artık geçerli olmayan amaç bağışlarını silerken yararlı olacaktır). Ardından etkileşim Siri'ye bağışlanır.

Alıcıya yapılan order.Intent çağrı, kullanıcı Siri'nin amaçla ilişkilendirmesi için bir tümcecik kaydettiğinde öneri olarak kullanılacak , Soup, Optionsve görüntüsünü ve bir çağırma tümceciği ayarlayarak Quantitysırayı temsil eden bir getirirOrderSoupIntent:

public OrderSoupIntent Intent
{
    get
    {
        var orderSoupIntent = new OrderSoupIntent();
        orderSoupIntent.Quantity = new NSNumber(Quantity);
        orderSoupIntent.Soup = new INObject(MenuItem.ItemNameKey, MenuItem.LocalizedString);

        var image = UIImage.FromBundle(MenuItem.IconImageName);
        if (!(image is null))
        {
            var data = image.AsPNG();
            orderSoupIntent.SetImage(INImage.FromData(data), "soup");
        }

        orderSoupIntent.Options = MenuItemOptions
            .ToArray<MenuItemOption>()
            .Select<MenuItemOption, INObject>(arg => new INObject(arg.Value, arg.LocalizedString))
            .ToArray<INObject>();

        var comment = "Suggested phrase for ordering a specific soup";
        var phrase = NSBundleHelper.SoupKitBundle.GetLocalizedString("ORDER_SOUP_SUGGESTED_PHRASE", comment);
        orderSoupIntent.SuggestedInvocationPhrase = String.Format(phrase, MenuItem.LocalizedString);

        return orderSoupIntent;
    }
}

Geçersiz bağışlar kaldırılıyor

Siri'nin yararlı olmayan veya kafa karıştırıcı kısayol önerilerinde bulunmaması için artık geçerli olmayan bağışları kaldırmak önemlidir.

Soup Chef'te Menüyü Yapılandır ekranı, menü öğesini kullanılamaz olarak işaretlemek için kullanılabilir. Siri artık kullanılamayan menü öğesini sıralamak için bir kısayol önermemelidir, bu nedenle RemoveDonation yöntemi SoupMenuManager artık kullanılamayan menü öğeleri için bağışları siler. Uygulama bu işlevi şu şekilde uygular:

  • Şu anda kullanılamayan menü öğesiyle ilişkili siparişleri bulma.
  • Tanımlayıcılarını tutuyorlar.
  • Aynı tanımlayıcılara sahip etkileşimleri silme.
void RemoveDonation(MenuItem menuItem)
{
    if (!menuItem.IsAvailable)
    {
        Order[] orderHistory = OrderManager?.OrderHistory.ToArray<Order>();
        if (orderHistory is null)
        {
            return;
        }

        string[] orderIdentifiersToRemove = orderHistory
            .Where<Order>((order) => order.MenuItem.ItemNameKey == menuItem.ItemNameKey)
            .Select<Order, string>((order) => order.Identifier.ToString())
            .ToArray<string>();

        INInteraction.DeleteInteractions(orderIdentifiersToRemove, (error) =>
        {
            if (!(error is null))
            {
                Console.WriteLine($"Failed to delete interactions with error {error.ToString()}");
            }
            else
            {
                Console.WriteLine("Successfully deleted interactions");
            }
        });
    }
}

Başarılı bağışları doğrulama

Çözüm birden çok proje ve belirli bir yapılandırma içerir. Bazı durumlarda, eksik yapılandırma nedeniyle uygulama kilitlenebilir, diğer durumlarda sessizce bir etkileşim bağışta bulunamaz. Başarılı bağışları doğrulamak önemlidir ve iOS Geliştirici ayarları buna yardımcı olur. Ayarlar > Geliştirici'ye gidin ve son bağışları ve kısayolları görmek için aşağıdaki geliştirici seçeneklerini etkinleştirin:

  • En Son Kısayolları Görüntüle
  • Bağışları Kilit Ekranında Görüntüle

Etkinleştirildikten sonra, her başarılı bağış kilit ekranında ve Siri önerileri seçeneklerinin altında görünür. Uygulamanızı çalıştırdıktan sonra bağışları orada görmüyorsanız aşağıdaki sorun giderme olaylarını gözden geçirin:

  1. Bir uygulama aşağıdaki hatayla oluşturamıyor OrderSoupIntent :

    'NativeLibrary.OrderSoupIntent' türünün yerel bir örneği oluşturulamadı: yerel sınıf yüklenmedi.

    Bu hata, Xamarin'in Xamarin bağlaması aracılığıyla yerel sınıfı yükleyemediği anlamına gelir. Bunu düzeltmek için yerel kitaplığın bağlama projesi tarafından başvuruda bulunan gerekli kodu içerdiğini ve burada açıklandığı gibi uygun bayrakların ayarlandığını doğrulayın. Bayrağı olarak OnayarlayınForce Load.

  2. Bir uygulama, amaç sınıfının yüklenen yerel örneğini şu hatayla başlatamıyor:

    'NativeLibrary.OrderSoupIntent' türünün bir örneği başlatılamadı: yerel 'init' yöntemi sıfır döndürdü.

    Sorun eksik amaç tanım dosyasıyla ilgilidir. Xamarin uygulaması, burada açıklandığı gibi türüne Content sahip özgün amaç tanım dosyasını içermelidir.

  3. Uygulama amacı oluşturur ve kilitlenme olmadan bağış yöntemini çağırır, ancak konsol çıkışı bilinmeyen amaç türü hakkında bir uyarı gösterir ve bağış yapılmaz:

    Geçerli kısayol türü olmayan OrderSoupIntent ile etkileşim bağışlanamaz

    Amacın plist'te düzgün bir şekilde tanımlanması gereken sorunu düzeltmek için Siri yetkilendirmesinin proje ayarları aracılığıyla geçerli derleme yapılandırması için etkinleştirilmesi ve seçilmesi gerekir.

    Uygulamanın info.plist dosyası:

    <key>NSUserActivityTypes</key>
    <array>
        <string>ScheduleMeetingIntent</string>
    </array>
    

    Siri özelliğine sahip uygulamanın Entitlements.plist'i:

    <key>com.apple.developer.siri</key>
    <true/>
    

    Hedeflenen derleme yapılandırması için özel yetkilendirmeler seçilmelidir. Proje ayarları Derleme iOS Paket İmzalama'ya gidin ve Özel Yetkilendirmeler'i gerekli yetkilendirmeleri içeren Entitlements.plist dosyasına ayarlayın.>>

Intents uzantısı oluşturma

Siri bir amacı çağırdığında çalıştırılan kod, Soup Chef gibi mevcut bir Xamarin.iOS uygulamasıyla aynı çözüme yeni bir proje olarak eklenebilecek bir Intents uzantısına yerleştirilir. SoupChef çözümünde uzantıya SoupChefIntents adı verilir.

SoupChefIntents – Info.plist ve Entitlements.plist

SoupChefIntents – Info.plist

SoupChefIntents projesindeki Info.plist, Paket Tanımlayıcısını olarak com.xamarin.SoupChef.SoupChefIntentstanımlar.

Info.plist dosyası da aşağıdaki girdiyi içerir:

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>IntentsRestrictedWhileLocked</key>
        <array/>
        <key>IntentsSupported</key>
        <array>
            <string>OrderSoupIntent</string>
        </array>
        <key>IntentsRestrictedWhileProtectedDataUnavailable</key>
        <array/>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.intents-service</string>
    <key>NSExtensionPrincipalClass</key>
    <string>IntentHandler</string>
</dict>

Yukarıdaki Info.plist dosyasında:

  • IntentsRestrictedWhileLocked cihazın kilidi açıldığında işlenecek amaçları listeler.
  • IntentsSupported bu uzantı tarafından işlenen amaçları listeler.
  • NSExtensionPointIdentifier uygulama uzantısının türünü belirtir. Daha fazla bilgi için Apple'ın belgelerine bakın.
  • NSExtensionPrincipalClass bu uzantı tarafından desteklenen amaçları işlemek için kullanılması gereken sınıfı belirtir.
SoupChefIntents – Entitlements.plist

SoupChefIntents projesindeki Entitlements.plist, Uygulama Grupları özelliğine sahiptir. Bu özellik, SoupChef projesiyle aynı uygulama grubunu kullanacak şekilde yapılandırılmıştır:

<key>com.apple.security.application-groups</key>
<array>
    <string>group.com.xamarin.SoupChef</string>
</array>

Soup Chef ile NSUserDefaultsverileri kalıcı hale alır. Uygulama ve uygulama uzantısı arasında veri paylaşmak için, Entitlements.plist dosyalarında aynı uygulama grubuna başvururlar.

Not

SoupChefIntents projesinin derleme yapılandırması, Özel Yetkilendirmeleri Entitlements.plist olarak ayarlar.

OrderSoupIntent arka plan görevini işleme

Intents uzantısı, özel bir amada göre bir kısayol için gerekli arka plan görevlerini yürütür.

Siri, öğesini işlemek OrderSoupIntentiçin kullanılabilen öğesini genişleten OrderSoupIntentHandlingbir sınıfın örneğini almak için sınıfının yöntemini IntentHandler (Info.plist içinde olarak NSExtensionPrincipalClasstanımlanır) çağırırGetHandler:

[Register("IntentHandler")]
public class IntentHandler : INExtension
{
    public override NSObject GetHandler(INIntent intent)
    {
        if (intent is OrderSoupIntent)
        {
            return new OrderSoupIntentHandler();
        }
        throw new Exception("Unhandled intent type: ${intent}");
    }

    protected IntentHandler(IntPtr handle) : base(handle) { }
}

OrderSoupIntentHandler, paylaşılan kodun SoupKit projesinde tanımlanan iki önemli yöntemi uygular:

  • ConfirmOrderSoup – Amaçla ilişkili görevin gerçekten yürütülmesi gerekip gerekmediğini onaylar
  • HandleOrderSoup – Çorba siparişini yerleştirir ve geçirilen tamamlama işleyicisini çağırarak kullanıcıya yanıt verir

Uygulamayı açan OrderSoupIntent'i işleme

Bir uygulamanın arka planda çalışmayan amaçları düzgün bir şekilde işlemesi gerekir. Bu amaçlar, ContinueUserActivity yönteminde AppDelegatekısayollarla aynı şekilde NSUserActivity işlenir:

public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
    var intent = userActivity.GetInteraction()?.Intent as OrderSoupIntent;
    if (!(intent is null))
    {
        HandleIntent(intent);
        return true;
    }
    // ...
}  

Özel amaç için kullanıcı arabirimi sağlama

Intents kullanıcı arabirimi uzantısı, Intents uzantısı için özel bir kullanıcı arabirimi sağlar. SoupChef çözümünde, SoupChefIntentsUI, SoupChefIntents için bir arabirim sağlayan bir Intents ui uzantısıdır.

SoupChefIntentsUI – Info.plist ve Entitlements.plist

SoupChefIntentsUI – Info.plist

SoupChefIntentsUI projesindeki Info.plist, Paket Tanımlayıcısını olarak com.xamarin.SoupChef.SoupChefIntentsuitanımlar.

Info.plist dosyası da aşağıdaki girdiyi içerir:

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>IntentsSupported</key>
        <array>
            <string>OrderSoupIntent</string>
        </array>
        <!-- ... -->
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.intents-ui-service</string>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
</dict>

Yukarıdaki Info.plist dosyasında:

  • IntentsSupported , öğesinin OrderSoupIntent bu Intents kullanıcı arabirimi uzantısı tarafından işlendiğini gösterir.
  • NSExtensionPointIdentifier uygulama uzantısının türünü belirtir. Daha fazla bilgi için Apple'ın belgelerine bakın.
  • NSExtensionMainStoryboard bu uzantının birincil arabirimini tanımlayan görsel taslak belirtir

SoupChefIntentsUI – Entitlements.plist

SoupChefIntentsUI projesinin bir Entitlements.plist dosyasına ihtiyacı yoktur.

Kullanıcı arabirimi oluşturma

SoupChefIntentsUI için Info.plist anahtarı olarak MainInterfaceayardığından NSExtensionMainStoryboard MainInterace.storyboard dosyası Intents UI uzantısı arabirimini tanımlar.

Bu görsel taslakta IntentViewController türünde tek bir görünüm denetleyicisi vardır. İki görünüme başvurur:

  • invoiceView, türü InvoiceView
  • confirmationView, türü ConfirmOrderView

Not

invoiceView ve confirmationView arabirimleri Main.storyboard'da ikincil görünümler olarak tanımlanır. Mac için Visual Studio ve Visual Studio 2017 ikincil görünümleri görüntüleme veya düzenleme desteği sağlamaz; bunu yapmak içinXcode'un Interface Builder'ında Main.storyboard.

IntentViewController uygulama IINUIHostedViewControlling arabirimi, Siri Amaçları ile çalışırken özel bir arabirim sağlamak için kullanılır. ConfigureViewyöntemi arabirimini özelleştirmek için çağrılır ve etkileşimin onaylanıp onaylanmadığına () veya başarıyla yürütülerek (INIntentHandlingStatus.ReadyINIntentHandlingStatus.Success):

[Export("configureViewForParameters:ofInteraction:interactiveBehavior:context:completion:")]
public void ConfigureView(
    NSSet<INParameter> parameters,
    INInteraction interaction,
    INUIInteractiveBehavior interactiveBehavior,
    INUIHostedViewContext context,
    INUIHostedViewControllingConfigureViewHandler completion)
{
    // ...
    if (interaction.IntentHandlingStatus == INIntentHandlingStatus.Ready)
    {
        desiredSize = DisplayInvoice(order, intent);
    }
    else if(interaction.IntentHandlingStatus == INIntentHandlingStatus.Success)
    {
        var response = interaction.IntentResponse as OrderSoupIntentResponse;
        if (!(response is null))
        {
            desiredSize = DisplayOrderConfirmation(order, intent, response);
        }
    }
    completion(true, parameters, desiredSize);
}

İpucu

Yöntem hakkında ConfigureView daha fazla bilgi için Apple'ın WWDC 2017 sunusu SiriKit'teki Yenilikler'i izleyin.

Ses kısayolu oluşturma

Soup Chef her sipariş için bir ses kısayolu atamak için bir arabirim sağlar ve Siri ile çorba sipariş etmek mümkün hale getirir. Aslında, ses kısayollarını kaydetmek ve atamak için kullanılan arabirim iOS tarafından sağlanır ve çok az özel kod gerektirir.

uygulamasındaOrderDetailViewController, bir kullanıcı tablonun Siri'ye Ekle satırına dokunduğundaRowSelected, yöntem bir ses kısayolu eklemek veya düzenlemek için bir ekran sunar:

public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
    // ...
    else if (TableConfiguration.Sections[indexPath.Section].Type == OrderDetailTableConfiguration.SectionType.VoiceShortcut)
    {
        INVoiceShortcut existingShortcut = VoiceShortcutDataManager?.VoiceShortcutForOrder(Order);
        if (!(existingShortcut is null))
        {
            var editVoiceShortcutViewController = new INUIEditVoiceShortcutViewController(existingShortcut);
            editVoiceShortcutViewController.Delegate = this;
            PresentViewController(editVoiceShortcutViewController, true, null);
        }
        else
        {
            // Since the app isn't yet managing a voice shortcut for
            // this order, present the add view controller
            INShortcut newShortcut = new INShortcut(Order.Intent);
            if (!(newShortcut is null))
            {
                var addVoiceShortcutVC = new INUIAddVoiceShortcutViewController(newShortcut);
                addVoiceShortcutVC.Delegate = this;
                PresentViewController(addVoiceShortcutVC, true, null);
            }
        }
    }
}

Şu anda görüntülenen sıra için mevcut bir ses kısayolunun mevcut olup olmadığına bağlı olarak, RowSelected veya INUIAddVoiceShortcutViewControllertüründe INUIEditVoiceShortcutViewController bir görünüm denetleyicisi sunar. Her durumda, OrderDetailViewController kendisini görünüm denetleyicisinin Delegateolarak ayarlar, bu nedenle de uygular IINUIAddVoiceShortcutViewControllerDelegate ve IINUIEditVoiceShortcutViewControllerDelegate.

Cihazda test etme

Soup Chef'i bir cihazda çalıştırmak için bu bölümdeki yönergeleri izleyin. Otomatik sağlama hakkındaki notu da okuyun.

Uygulama Grubu, Uygulama Kimlikleri, Sağlama Profilleri

Apple Geliştirici Portalı'nın Sertifikalar, Kimlikler ve Profiller bölümünde aşağıdaki adımları uygulayın:

  • Soup Chef uygulaması ve uzantıları arasında veri paylaşmak için bir uygulama grubu oluşturun. Örneğin: group.com.şirketinizinadı.SoupChef

  • Üç Uygulama Kimlikleri oluşturun: biri uygulamanın kendisi, biri Intents uzantısı ve diğeri intents ui uzantısı için. Örneğin:

    • Uygulama: com.yourcompanyname.SoupChef

      • Bu Uygulama Kimliği'ne SiriKit ve Uygulama Grupları özelliklerini atayın.
    • Intents extension: com.yourcompanyname.SoupChef.Intents

      • Bu Uygulama Kimliği'ne Uygulama Grupları özelliğini atayın.
    • Amaçlar kullanıcı arabirimi uzantısı: com.yourcompanyname.SoupChef.Intentsui

      • Bu Uygulama Kimliği için özel bir özellik gerekmez.
  • Yukarıdaki Uygulama Kimliklerini oluşturduktan sonra, uygulamaya atanan Uygulama Grupları özelliğini ve Intents uzantısını düzenleyerek daha önce oluşturulan belirli uygulama grubunu belirtin.

  • Yeni Uygulama kimliklerinin her biri için bir tane olacak şekilde üç yeni geliştirme sağlama profili oluşturun.

  • Bu sağlama profillerini indirin ve yüklemek için her birine çift tıklayın. Mac için Visual Studio veya Visual Studio 2017 zaten çalışıyorsa, yeni sağlama profillerini kaydettiğinizden emin olmak için yeniden başlatın.

Info.plist, Entitlements.plist ve kaynak kodunu düzenleme

Mac için Visual Studio veya Visual Studio 2017'de aşağıdaki adımları uygulayın:

  • Çözümdeki çeşitli Info.plist dosyalarını güncelleştirin. Uygulamayı, Intents uzantısını ve Intents UI uzantısı Paket Tanımlayıcısını daha önce tanımlanan Uygulama Kimlikleri olarak ayarlayın:

    • Uygulama: com.yourcompanyname.SoupChef
    • Amaç Uzantısı: com.yourcompanyname.SoupChef.Intents
    • Amaçlar Kullanıcı Arabirimi Uzantısı: com.yourcompanyname.SoupChef.Intentsui
  • SoupChef projesi için Entitlements.plist dosyasını güncelleştirin:

    • Uygulama Grupları özelliği için, grubu daha önce oluşturulan yeni uygulama grubuna ayarlayın (yukarıdaki örnekte, group.com.şirketinizinadı.SoupChef'tir).
    • SiriKit'in etkinleştirildiğinden emin olun.
  • SoupChefIntents projesi için Entitlements.plist dosyasını güncelleştirin:

    • Uygulama Grupları özelliği için, grubu daha önce oluşturulan yeni uygulama grubuna ayarlayın (yukarıdaki örnekte, group.com.şirketinizinadı.SoupChef'tir).
  • Son olarak NSUserDefaultsHelper.cs açın. Değişkenini AppGroup yeni uygulama grubunuzun değerine ayarlayın (örneğin, olarak ayarlayın group.com.yourcompanyname.SoupChef).

Derleme ayarlarını yapılandırma

Mac için Visual Studio veya Visual Studio 2017'de:

  • SoupChef projesinin seçeneklerini/özelliklerini açın. iOS Paket İmzalama sekmesinde İmzalama Kimliği'ni otomatik olarak, Sağlama Profili'ni ise daha önce oluşturduğunuz uygulamaya özgü yeni sağlama profili olarak ayarlayın.

  • SoupChefIntents projesinin seçeneklerini/özelliklerini açın. iOS Paket İmzalama sekmesinde İmzalama Kimliği'ni otomatik olarak, Sağlama Profili'ni ise daha önce oluşturduğunuz yeni Intents uzantısına özgü sağlama profiline ayarlayın.

  • SoupChefIntentsUI projesinin seçeneklerini/özelliklerini açın. iOS Paket İmzalama sekmesinde İmzalama Kimliği'ni otomatik olarak, Sağlama Profili'ni ise daha önce oluşturduğunuz yeni Intents kullanıcı arabirimi uzantısına özgü sağlama profiline ayarlayın.

Bu değişiklikler gerçekleştiğinde, uygulama bir iOS cihazında çalışır.

Otomatik sağlama

Bu sağlama görevlerinin çoğunu doğrudan IDE'de gerçekleştirmek için otomatik sağlamayı kullanabilirsiniz. Ancak, otomatik sağlama uygulama gruplarını ayarlamaz. Entitlements.plist dosyalarını kullanmak istediğiniz uygulama grubunun adıyla el ile yapılandırmanız, uygulama grubunu oluşturmak için Apple Geliştirici Portalı'nı ziyaret etmeniz, bu uygulama grubunu otomatik sağlama tarafından oluşturulan her Bir Uygulama Kimliğine atamanız, sağlama profillerini (uygulama, Amaçlar uzantısı, Amaçlar UI uzantısı) yeni oluşturulan uygulama grubunu içerecek şekilde yeniden oluşturmanız, ve bunları indirip yükleyin.