Xamarin.iOS'ta teslim
Bu makale, kullanıcının diğer cihazlarında çalışan uygulamalar arasında kullanıcı etkinliklerini aktarmak için Xamarin.iOS uygulamasında Handoff ile çalışmayı kapsar.
Apple, iOS 8 ve OS X Yosemite'da (10.10) kullanıcının cihazlarından birinde başlatılan etkinlikleri aynı uygulamayı veya aynı etkinliği destekleyen başka bir uygulamayı çalıştıran başka bir cihaza aktarmasına yönelik ortak bir mekanizma sağlamak için Handoff'u kullanıma sunmuştur.
Bu makale, Xamarin.iOS uygulamasında etkinlik paylaşımını etkinleştirmeye hızlı bir bakış sağlayacak ve Handoff çerçevesini ayrıntılı olarak ele alacaktır:
İletim Hakkında
İletim (Süreklilik olarak da bilinir), Apple tarafından iOS 8 ve OS X Yosemite'da (10.10) kullanıcının cihazlarından birinde (iOS veya Mac) bir etkinlik başlatmasının ve aynı etkinliği başka bir cihazda (kullanıcının iCloud Hesabı tarafından tanımlandığı şekilde) sürdürmesinin bir yolu olarak tanıtıldı.
İletim, iOS 9'da yeni, gelişmiş Arama özelliklerini de destekleyecek şekilde genişletildi. Daha fazla bilgi için lütfen Arama Geliştirmeleri belgelerimize bakın.
Örneğin, kullanıcı i Telefon üzerinde bir e-posta başlatabilir ve mac'lerinde e-postaya sorunsuz bir şekilde devam edebilir; tüm ileti bilgileri doldurulmuş ve imleç iOS'ta bıraktığı konumdadır.
Aynı Ekip Kimliğini paylaşan tüm uygulamalarınız, bu uygulamalar iTunes App Store üzerinden teslim edildikçe veya kayıtlı bir geliştirici (Mac, Enterprise veya Geçici uygulamalar için) tarafından imzalandıysa uygulamalar genelinde kullanıcı etkinliklerine devam etmek için Handoff kullanabilir.
Tüm NSDocument
veya UIDocument
tabanlı uygulamalar otomatik olarak Yerleşik İletim desteğine sahiptir ve İletim desteği için çok az değişiklik gerektirir.
Devam Eden Kullanıcı Etkinlikleri
NSUserActivity
sınıfı (ve AppKit
üzerinde yapılan bazı küçük değişikliklerle UIKit
birlikte), kullanıcının başka bir cihazında devam edilebilecek bir kullanıcının etkinliğini tanımlama desteği sağlar.
Bir etkinliğin kullanıcının başka bir cihazına geçirilmesi için, geçerli etkinlik olarak işaretlenmiş bir örnekte NSUserActivity
kapsüllenmesi, yükün ayarlanmış olması (devamı gerçekleştirmek için kullanılan veriler) ve etkinliğin bu cihaza iletilmesi gerekir.
İletim, iCloud aracılığıyla daha büyük veri paketlerinin eşitlenmesiyle devam edilecek etkinliği tanımlamak için en düşük bilgileri geçirir.
Alıcı cihazda, kullanıcı bir etkinliğin devamı için kullanılabilir olduğuna dair bir bildirim alır. Kullanıcı yeni cihazda etkinliğe devam etmeyi seçerse, belirtilen uygulama başlatılır (zaten çalışmıyorsa) ve etkinliği yeniden başlatmak için üzerindeki NSUserActivity
yük kullanılır.
Yalnızca aynı geliştirici Ekip Kimliğini paylaşan ve belirli bir Etkinlik Türüne yanıt veren uygulamalar devam etmeye uygundur. Bir uygulama, Info.plist dosyasının NSUserActivityTypes
anahtarı altında desteklediği Etkinlik Türlerini tanımlar. Bunu göz önünde bulundurarak, devam eden bir cihaz Ekip Kimliği, Etkinlik Türü ve isteğe bağlı olarak Etkinlik Başlığı temelinde devamlılığı gerçekleştirmek için uygulamayı seçer.
Alıcı uygulama, kullanıcı arabirimini yapılandırmak ve geçişin NSUserActivity
son kullanıcıya sorunsuz görünmesi için verilen etkinliğin durumunu geri yüklemek için 'nin UserInfo
sözlüğündeki bilgileri kullanır.
Devam, aracılığıyla verimli bir NSUserActivity
şekilde gönderilebilenden daha fazla bilgi gerektiriyorsa, devam eden uygulama kaynak uygulamaya bir çağrı gönderebilir ve gerekli verileri iletmek için bir veya daha fazla akış oluşturabilir. Örneğin, etkinlik birden çok görüntü içeren büyük bir metin belgesini düzenliyorsa, alıcı cihazda etkinliğe devam etmek için gereken bilgileri aktarmak için akış gerekir. Daha fazla bilgi için aşağıdaki Destekleyici Devamlılık Akışlar bölümüne bakın.
Yukarıda NSDocument
belirtildiği gibi veya UIDocument
tabanlı uygulamalar otomatik olarak Yerleşik İletim desteğine sahiptir. Daha fazla bilgi için aşağıdaki Belge Tabanlı Uygulamalarda Destek İletimi bölümüne bakın.
NSUserActivity Sınıfı
NSUserActivity
sınıfı, Bir İletim değişimindeki birincil nesnedir ve devamlılık için kullanılabilen bir Kullanıcı Etkinliğinin durumunu kapsüllemek için kullanılır. Bir uygulama, desteklediği tüm etkinlikler için bir kopyasını NSUserActivity
oluşturur ve başka bir cihazda devam etmek ister. Örneğin, belge düzenleyicisi şu anda açık olan her belge için bir etkinlik oluşturur. Ancak, yalnızca en öndeki belge (en öndeki Pencere veya Sekmede görüntülenir) Geçerli Etkinliktir ve devam için kullanılabilir.
örneği NSUserActivity
hem hem ActivityType
Title
de özellikleriyle tanımlanır. UserInfo
Sözlük özelliği, etkinliğin durumu hakkında bilgi taşımak için kullanılır. NeedsSave
'nin temsilcisi aracılığıyla NSUserActivity
durum bilgilerini gecikmeli yüklemek istiyorsanız özelliğini true
olarak ayarlayın. Etkinliğin AddUserInfoEntries
durumunu korumak için diğer istemcilerden gelen yeni verileri sözlükle UserInfo
birleştirmek için yöntemini kullanın.
NSUserActivityDelegate Sınıfı
NSUserActivityDelegate
, 'NSUserActivity
nin UserInfo
sözlüğündeki bilgileri güncel ve etkinliğin geçerli durumuyla eşitlenmiş durumda tutmak için kullanılır. Sistemin etkinlikteki bilgilerin güncelleştirilmesi gerektiğinde (örneğin, başka bir cihazda devam etmeden önce), temsilcinin yöntemini çağırır UserActivityWillSave
.
Yöntemini uygulamanız ve geçerli etkinliğin UserActivityWillSave
NSUserActivity
durumunu yansıtmaya devam etmesini sağlamak için yönteminde (, Title
UserInfo
vb.) herhangi bir değişiklik yapmanız gerekir. Sistem yöntemini çağırdığında UserActivityWillSave
, NeedsSave
bayrağı temizlenir. Etkinliğin veri özelliklerinden herhangi birini değiştirirseniz yeniden olarak ayarlamanız NeedsSave
true
gerekir.
Yukarıda sunulan yöntemi kullanmak UserActivityWillSave
yerine, isteğe bağlı olarak kullanıcı etkinliğini otomatik olarak UIKit
alabilir veya AppKit
yönetebilirsiniz. Bunu yapmak için yanıtlayıcı nesnesinin UserActivity
özelliğini ayarlayın ve yöntemini uygulayın UpdateUserActivityState
. Daha fazla bilgi için aşağıdaki Yanıtlayıcılarda Destek İletimi bölümüne bakın.
App Framework Desteği
Hem (iOS) hem AppKit
de UIKit
(OS X), , Yanıtlayıcı (/UIResponder
NSResponder
) ve AppDelegate
sınıflarında NSDocument
İletim için yerleşik destek sağlar. Her işletim sistemi Handoff'u biraz farklı uygulasa da temel mekanizma ve API'ler aynıdır.
Belge Tabanlı Uygulamalarda Kullanıcı Etkinlikleri
Belge tabanlı iOS ve OS X uygulamaları otomatik olarak Yerleşik İletim desteğine sahiptir. Bu desteği etkinleştirmek için, uygulamanın Info.plist dosyasındaki her CFBundleDocumentTypes
giriş için bir NSUbiquitousDocumentUserActivityType
anahtar ve değer eklemeniz gerekir.
Bu anahtar varsa, belirtilen türde iCloud tabanlı belgeler için hem hem de NSDocument
UIDocument
otomatik olarak örnekler oluşturun NSUserActivity
. Uygulamanın desteklediği her belge türü için bir etkinlik türü sağlamanız gerekir ve birden çok belge türü aynı etkinlik türünü kullanabilir. UIDocument
hem hem de NSDocument
özelliğini kendi özelliğinin NSUserActivity
değeriyle FileURL
otomatik olarak doldururUserInfo
.
OS X'te, NSUserActivity
tarafından yönetilen AppKit
ve yanıtlayanlarla ilişkilendirilmiş olan, belgenin penceresi ana pencere olduğunda otomatik olarak Geçerli Etkinlik olur. iOS'ta, tarafından UIKit
yönetilen nesneler için NSUserActivity
yöntemini açıkça çağırmanız BecomeCurrent
veya uygulama ön plana geldiğinde belgenin UserActivity
özelliğinin ayarlanmış UIViewController
olması gerekir.
AppKit
, OS X'te bu şekilde oluşturulan tüm UserActivity
özellikleri otomatik olarak geri yükler. Bu durum, yöntemin döndürmesi ContinueUserActivity
false
veya engellenmemesi durumunda oluşur. Bu durumda, belge yöntemiyle OpenDocument
NSDocumentController
açılır ve ardından bir RestoreUserActivityState
yöntem çağrısı alır.
Daha fazla bilgi için aşağıdaki Belge Tabanlı Uygulamalarda Destekleyici İletim bölümüne bakın.
Kullanıcı Etkinlikleri ve Yanıtlayıcılar
Hem hem AppKit
de UIKit
yanıtlayıcı nesnesinin UserActivity
özelliği olarak ayarlarsanız kullanıcı etkinliğini otomatik olarak yönetebilir. Durum değiştirildiyse, yanıtlayanın NeedsSave
UserActivity
özelliğini olarak true
ayarlamanız gerekir. Sistem, yanıtlayana UserActivity
yöntemini çağırarak UpdateUserActivityState
durumu güncelleştirmesi için zaman verdikten sonra gerekli olduğunda otomatik olarak kaydeder.
Birden çok yanıtlayan tek NSUserActivity
bir örneği paylaşıyorsa, sistem kullanıcı etkinliği nesnesini güncelleştirdiğinde bir UpdateUserActivityState
geri çağırma alır. Yanıtlayıcının AddUserInfoEntries
bu noktada geçerli etkinlik durumunu yansıtacak şekilde 's UserInfo
sözlüğü güncelleştirmek NSUserActivity
için yöntemini çağırması gerekir. UserInfo
Sözlük her UpdateUserActivityState
çağrıdan önce temizlenir.
Bir etkinlikle ilişkilendirmesini kaldırmak için, yanıtlayıcı özelliğini olarak null
ayarlayabilirUserActivity
. Uygulama çerçevesi yönetilen NSUserActivity
örneğinde artık ilişkili yanıtlayıcı veya belge kalmadığında, otomatik olarak geçersiz kılınmış olur.
Daha fazla bilgi için aşağıdaki Yanıtlayıcılarda Destek İletimi bölümüne bakın.
Kullanıcı Etkinlikleri ve AppDelegate
Bir İletim AppDelegate
devamı işlenirken uygulamanızın birincil giriş noktasıdır. Kullanıcı bir İletim bildirimine yanıt verdiği zaman, uygun uygulama başlatılır (zaten çalışmıyorsa) ve WillContinueUserActivityWithType
yöntemi AppDelegate
çağrılır. Bu noktada uygulama, kullanıcıya devamlılık işleminin başlatıldığını bildirmelidir.
'NSUserActivity
s ContinueUserActivity
yöntemi çağrıldığında AppDelegate
örnek teslim edilir. Bu noktada, uygulamanın kullanıcı arabirimini yapılandırmalı ve verilen etkinliğe devam etmelisiniz.
Daha fazla bilgi için aşağıdaki İletim Uygulama bölümüne bakın.
Xamarin Uygulamasında İletimi Etkinleştirme
Handoff tarafından uygulanan güvenlik gereksinimleri nedeniyle, Handoff çerçevesini kullanan bir Xamarin.iOS uygulamasının hem Apple Geliştirici Portalı'nda hem de Xamarin.iOS proje dosyasında düzgün yapılandırılması gerekir.
Aşağıdakileri yapın:
Apple Geliştirici Portalı'na giriş yapın.
Sertifikalar, Tanımlayıcılar ve Profiller'e tıklayın.
Henüz yapmadıysanız, Tanımlayıcılar'a tıklayın ve uygulamanız için bir kimlik oluşturun (örneğin),
com.company.appname
yoksa mevcut kimliğinizi düzenleyin.iCloud hizmetinin verilen kimlik için denetlendiğinden emin olun:
Değişikliklerinizi kaydedin.
Sağlama Profilleri>Geliştirme'ye tıklayın ve uygulamanız için yeni bir geliştirme sağlama profili oluşturun:
Yeni sağlama profilini indirip yükleyin veya Xcode kullanarak profili indirip yükleyin.
Xamarin.iOS proje seçeneklerinizi düzenleyin ve az önce oluşturduğunuz sağlama profilini kullandığınızdan emin olun:
Ardından Info.plist dosyanızı düzenleyin ve sağlama profilini oluşturmak için kullanılan Uygulama Kimliğini kullandığınızdan emin olun:
Arka Plan Modları bölümüne gidin ve aşağıdaki öğeleri denetleyin:
Değişiklikleri tüm dosyalara kaydedin.
Bu ayarlar uygulanarak uygulama artık Handoff Framework API'lerine erişmeye hazırdır. Sağlama hakkında ayrıntılı bilgi için lütfen Cihaz Sağlama ve Uygulamanızı Sağlama kılavuzlarımıza bakın.
İletimi Uygulama
Kullanıcı etkinlikleri, aynı geliştirici Ekip Kimliği ile imzalanan ve aynı Etkinlik Türünü destekleyen uygulamalar arasında devam edebilir. Xamarin.iOS uygulamasında Handoff'u uygulamak için bir Kullanıcı Etkinliği Nesnesi (veya AppKit
içindeUIKit
) oluşturmanız, etkinliği izlemek için nesnenin durumunu güncelleştirmeniz ve alıcı cihazda etkinliği sürdürmeniz gerekir.
Kullanıcı Etkinliklerini Tanımlama
İletim'i uygulamanın ilk adımı, uygulamanızın desteklediği kullanıcı etkinliklerinin türlerini belirlemek ve bu etkinliklerden hangilerinin başka bir cihazda devam etmek için iyi adaylar olduğunu görmektir. Örneğin: ToDo uygulaması, öğeleri bir Kullanıcı Etkinlik Türü olarak düzenlemeyi ve kullanılabilir öğeler listesine başka bir kullanıcı olarak göz atmayı destekleyebileceğinden.
Bir uygulama, uygulamanın sağladığı herhangi bir işlev için gereken sayıda Kullanıcı Etkinlik Türü oluşturabilir. Her Kullanıcı Etkinlik Türü için, uygulamanın türdeki bir etkinliğin ne zaman başlayıp bittiğini izlemesi ve bu göreve başka bir cihazda devam etmek için güncel durum bilgilerini koruması gerekir.
Kullanıcı Etkinlikleri, gönderen ve alan uygulamalar arasında bire bir eşleme yapılmadan aynı Ekip Kimliği ile imzalanan herhangi bir uygulamada devam edebilir. Örneğin, belirli bir uygulama başka bir cihazdaki farklı ve tek tek uygulamalar tarafından kullanılan dört farklı etkinlik türü oluşturabilir. Bu, uygulamanın Mac sürümü (birçok özellik ve işleve sahip olabilir) ile her uygulamanın daha küçük olduğu ve belirli bir göreve odaklandığı iOS uygulamaları arasında sık karşılaşılan bir durumdur.
Etkinlik Türü Tanımlayıcıları Oluşturma
Etkinlik Türü Tanımlayıcısı, belirli bir Kullanıcı Etkinlik Türünü benzersiz olarak tanımlamak için NSUserActivityTypes
kullanılan uygulamanın Info.plist dosyasının dizisine eklenen kısa bir dizedir. Uygulamanın desteklediği her etkinlik için dizide bir giriş olacaktır. Apple, çakışmaları önlemek için Etkinlik Türü Tanımlayıcısı için ters DNS stilinde bir gösterimin kullanılmasını önerir. Örneğin: com.company-name.appname.activity
belirli uygulama tabanlı etkinlikler veya com.company-name.activity
birden çok uygulamada çalıştırabilen etkinlikler için.
Etkinlik Türü Tanımlayıcısı, etkinlik türünü tanımlamak için bir NSUserActivity
örnek oluşturulurken kullanılır. Bir etkinlik başka bir cihazda devam ettiğinde Etkinlik Türü (uygulamanın Ekip Kimliği ile birlikte), etkinliğe devam etmek için hangi uygulamanın başlatıldığını belirler.
Örnek olarak MonkeyBrowser adlı bir örnek uygulama oluşturacağız. Bu uygulama, her birinin web tarayıcısı görünümünde farklı bir URL'si açık olan dört sekme sunacaktır. Kullanıcı, uygulamayı çalıştıran farklı bir iOS cihazında herhangi bir sekmeye devam edebilecektir.
Bu davranışı desteklemek için gerekli Etkinlik Türü Tanımlayıcılarını oluşturmak için Info.plist dosyasını düzenleyin ve Kaynak görünümüne geçin. Bir NSUserActivityTypes
anahtar ekleyin ve aşağıdaki tanımlayıcıları oluşturun:
Örnek MonkeyBrowser uygulamasındaki sekmelerin her biri için birer tane olan dört yeni Etkinlik Türü Tanımlayıcısı oluşturduk . Kendi uygulamalarınızı oluştururken, dizinin içeriğini uygulamanızın NSUserActivityTypes
desteklediği etkinliklere özgü Etkinlik Türü Tanımlayıcıları ile değiştirin.
Kullanıcı Etkinliği Değişikliklerini İzleme
Sınıfın yeni bir örneğini oluşturduğumuz zaman, etkinliğin NSUserActivity
durumundaki değişiklikleri izlemek için bir NSUserActivityDelegate
örnek belirteceğiz. Örneğin, durum değişikliklerini izlemek için aşağıdaki kod kullanılabilir:
using System;
using CoreGraphics;
using Foundation;
using UIKit;
namespace MonkeyBrowse
{
public class UserActivityDelegate : NSUserActivityDelegate
{
#region Constructors
public UserActivityDelegate ()
{
}
#endregion
#region Override Methods
public override void UserActivityReceivedData (NSUserActivity userActivity, NSInputStream inputStream, NSOutputStream outputStream)
{
// Log
Console.WriteLine ("User Activity Received Data: {0}", userActivity.Title);
}
public override void UserActivityWasContinued (NSUserActivity userActivity)
{
Console.WriteLine ("User Activity Was Continued: {0}", userActivity.Title);
}
public override void UserActivityWillSave (NSUserActivity userActivity)
{
Console.WriteLine ("User Activity will be Saved: {0}", userActivity.Title);
}
#endregion
}
}
Bir UserActivityReceivedData
Devamlılık Akışı gönderen bir cihazdan veri aldığında yöntemi çağrılır. Daha fazla bilgi için aşağıdaki Destekleyici Devamlılık Akışlar bölümüne bakın.
Yöntemi UserActivityWasContinued
, başka bir cihaz geçerli cihazdan bir etkinliği devraldığında çağrılır. ToDo listesine yeni öğe ekleme gibi etkinlik türüne bağlı olarak, uygulamanın gönderen cihazdaki etkinliği durdurması gerekebilir.
Yöntem UserActivityWillSave
, etkinlikte yapılan değişiklikler yerel olarak kullanılabilir cihazlar arasında kaydedilmeden ve eşitlenmeden önce çağrılır. Gönderilmeden önce örneğin özelliğinde UserInfo
NSUserActivity
son dakika değişiklikleri yapmak için bu yöntemi kullanabilirsiniz.
NSUserActivity Örneği Oluşturma
Uygulamanızın başka bir cihazda devam etme olasılığını sağlamak istediği her etkinlik bir NSUserActivity
örnekte kapsüllenmelidir. Uygulama gerektiği kadar etkinlik oluşturabilir ve bu etkinliklerin doğası söz konusu uygulamanın işlevselliğine ve özelliklerine bağlıdır. Örneğin, bir e-posta uygulaması yeni ileti oluşturmak için bir etkinlik ve ileti okumak için başka bir etkinlik oluşturabilir.
Örnek uygulamamız için, kullanıcı sekmeli web tarayıcısı görünümünden birine her yeni URL girdiğinde yeni bir NSUserActivity
url oluşturulur. Aşağıdaki kod, belirli bir sekmenin durumunu depolar:
public NSString UserActivityTab1 = new NSString ("com.xamarin.monkeybrowser.tab1");
public NSUserActivity UserActivity { get; set; }
...
UserActivity = new NSUserActivity (UserActivityTab1);
UserActivity.Title = "Weather Tab";
UserActivity.Delegate = new UserActivityDelegate ();
// Update the activity when the tab's URL changes
var userInfo = new NSMutableDictionary ();
userInfo.Add (new NSString ("Url"), new NSString (url));
UserActivity.AddUserInfoEntries (userInfo);
// Inform Activity that it has been updated
UserActivity.BecomeCurrent ();
Yukarıda oluşturulan Kullanıcı Etkinlik Türünden birini kullanarak yeni NSUserActivity
bir oluşturur ve Etkinlik için okunabilir bir başlık sağlar. Durum değişikliklerini izlemek için yukarıda oluşturulan örneğine NSUserActivityDelegate
ekler ve iOS'a bu Kullanıcı Etkinliğinin Geçerli Etkinlik olduğunu bildirir.
UserInfo Sözlüğü Doldurma
Yukarıda gördüğümüz gibi, sınıfın UserInfo
NSUserActivity
özelliği, belirli bir NSDictionary
etkinliğin durumunu tanımlamak için kullanılan anahtar-değer çiftlerinin bir özelliğidir. içinde UserInfo
depolanan değerler şu türlerden biri olmalıdır: NSArray
, NSData
, NSDate
, , NSDictionary
, NSNull
, , NSNumber
, NSSet
NSString
, veya NSURL
. NSURL
iCloud belgelerine işaret eden veri değerleri, alıcı cihazda aynı belgelere işaret edecek şekilde otomatik olarak ayarlanır.
Yukarıdaki örnekte bir NSMutableDictionary
nesne oluşturduk ve kullanıcının verilen sekmede görüntülemekte olduğu URL'yi sağlayan tek bir anahtarla doldurduk. AddUserInfoEntries
Kullanıcı Etkinliği yöntemi, etkinliği alan cihazdaki etkinliği geri yüklemek için kullanılacak verilerle güncelleştirmek için kullanılmıştır:
// Update the activity when the tab's URL changes
var userInfo = new NSMutableDictionary ();
userInfo.Add (new NSString ("Url"), new NSString (url));
UserActivity.AddUserInfoEntries (userInfo);
Apple, etkinliğin alıcı cihaza zamanında gönderilmesini sağlamak için gönderilen bilgilerin en düşük düzeyde tutulmasını önerir. Belgenin düzenlenmesi gereken bir görüntü gibi daha büyük bilgiler gerekiyorsa, Devamlılık Akışlar kullanmanız gerekir. Daha fazla ayrıntı için aşağıdaki Destekleyici Devamlılık Akışlar bölümüne bakın.
Etkinliğe Devam Etme
İletim, kaynak cihaza fiziksel olarak yakın olan ve aynı iCloud hesabında oturum açan yerel iOS ve OS X cihazlarını, devam eden Kullanıcı Etkinliklerinin kullanılabilirliği konusunda otomatik olarak bilgilendirir. Kullanıcı yeni bir cihazda bir etkinliğe devam etmeyi seçerse sistem uygun uygulamayı başlatır (Ekip Kimliği ve Etkinlik Türüne göre) ve devam etmesi gereken bilgileri AppDelegate
verir.
İlk olarak, WillContinueUserActivityWithType
uygulamanın kullanıcıya devamın başlamak üzere olduğunu bildirebilmesi için yöntemi çağrılır. Devamı başlatmak için örnek uygulamamızın AppDelegate.cs dosyasında aşağıdaki kodu kullanırız:
public NSString UserActivityTab1 = new NSString ("com.xamarin.monkeybrowser.tab1");
public NSString UserActivityTab2 = new NSString ("com.xamarin.monkeybrowser.tab2");
public NSString UserActivityTab3 = new NSString ("com.xamarin.monkeybrowser.tab3");
public NSString UserActivityTab4 = new NSString ("com.xamarin.monkeybrowser.tab4");
...
public FirstViewController Tab1 { get; set; }
public SecondViewController Tab2 { get; set;}
public ThirdViewController Tab3 { get; set; }
public FourthViewController Tab4 { get; set; }
...
public override bool WillContinueUserActivity (UIApplication application, string userActivityType)
{
// Report Activity
Console.WriteLine ("Will Continue Activity: {0}", userActivityType);
// Take action based on the user activity type
switch (userActivityType) {
case "com.xamarin.monkeybrowser.tab1":
// Inform view that it's going to be modified
Tab1.PreparingToHandoff ();
break;
case "com.xamarin.monkeybrowser.tab2":
// Inform view that it's going to be modified
Tab2.PreparingToHandoff ();
break;
case "com.xamarin.monkeybrowser.tab3":
// Inform view that it's going to be modified
Tab3.PreparingToHandoff ();
break;
case "com.xamarin.monkeybrowser.tab4":
// Inform view that it's going to be modified
Tab4.PreparingToHandoff ();
break;
}
// Inform system we handled this
return true;
}
Yukarıdaki örnekte, her Görünüm Denetleyicisi ile AppDelegate
kaydolup bir Etkinlik Göstergesi ve kullanıcıya etkinliğin geçerli cihaza devredilmek üzere olduğunu bildiren bir ileti görüntüleyen bir genel PreparingToHandoff
yönteme sahiptir. Örnek:
private void ShowBusy(string reason) {
// Display reason
BusyText.Text = reason;
//Define Animation
UIView.BeginAnimations("Show");
UIView.SetAnimationDuration(1.0f);
Handoff.Alpha = 0.5f;
//Execute Animation
UIView.CommitAnimations();
}
...
public void PreparingToHandoff() {
// Inform caller
ShowBusy ("Continuing Activity...");
}
öğesinin ContinueUserActivity
AppDelegate
adı, verilen etkinliğe gerçekten devam etmek için çağrılır. Örnek uygulamamızdan tekrar:
public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
// Report Activity
Console.WriteLine ("Continuing User Activity: {0}", userActivity.ToString());
// Get input and output streams from the Activity
userActivity.GetContinuationStreams ((NSInputStream arg1, NSOutputStream arg2, NSError arg3) => {
// Send required data via the streams
// ...
});
// Take action based on the Activity type
switch (userActivity.ActivityType) {
case "com.xamarin.monkeybrowser.tab1":
// Preform handoff
Tab1.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab1});
break;
case "com.xamarin.monkeybrowser.tab2":
// Preform handoff
Tab2.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab2});
break;
case "com.xamarin.monkeybrowser.tab3":
// Preform handoff
Tab3.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab3});
break;
case "com.xamarin.monkeybrowser.tab4":
// Preform handoff
Tab4.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab4});
break;
}
// Inform system we handled this
return true;
}
Her View Controller'ın genel PerformHandoff
yöntemi aslında iletimi önceden oluşturur ve geçerli cihazdaki etkinliği geri yükler. Örnek söz konusu olduğunda, kullanıcının farklı bir cihazda göz attığını belirtilen bir sekmede aynı URL'yi görüntüler. Örnek:
private void HideBusy() {
//Define Animation
UIView.BeginAnimations("Hide");
UIView.SetAnimationDuration(1.0f);
Handoff.Alpha = 0f;
//Execute Animation
UIView.CommitAnimations();
}
...
public void PerformHandoff(NSUserActivity activity) {
// Hide busy indicator
HideBusy ();
// Extract URL from dictionary
var url = activity.UserInfo ["Url"].ToString ();
// Display value
URL.Text = url;
// Display the give webpage
WebView.LoadRequest(new NSUrlRequest(NSUrl.FromString(url)));
// Save activity
UserActivity = activity;
UserActivity.BecomeCurrent ();
}
yöntemi, ContinueUserActivity
belge veya yanıtlayıcı tabanlı etkinlik devam ettirilmesi için çağırabileceğiniz bir UIApplicationRestorationHandler
içerir. Çağrıldığında Geri Yükleme İşleyicisi'ne bir NSArray
veya geri yüklenebilen nesneler geçirmeniz gerekir. Örneğin:
completionHandler (new NSObject[]{Tab4});
Geçirilen her nesne için RestoreUserActivityState
yöntemi çağrılır. Daha sonra her nesne kendi durumunu geri yüklemek için sözlükteki UserInfo
verileri kullanabilir. Örneğin:
public override void RestoreUserActivityState (NSUserActivity activity)
{
base.RestoreUserActivityState (activity);
// Log activity
Console.WriteLine ("Restoring Activity {0}", activity.Title);
}
Belge tabanlı uygulamalar için yöntemini uygulamazsanız ContinueUserActivity
veya döndürürse false
UIKit
veya AppKit
etkinliği otomatik olarak sürdürebilir. Daha fazla bilgi için aşağıdaki Belge Tabanlı Uygulamalarda Destekleyici İletim bölümüne bakın.
İletimi Düzgün Bir Şekilde Başarısız Oluyor
İletim, gevşek bağlı bir koleksiyon iOS ve OS X cihazları arasında bilgi aktarımına bağlı olduğundan, aktarım işlemi bazen başarısız olabilir. Uygulamanızı bu hataları düzgün bir şekilde işleyecek ve ortaya çıkan her durumda kullanıcıyı bilgilendirecek şekilde tasarlamanız gerekir.
Bir hata durumunda yöntemi DidFailToContinueUserActivitiy
AppDelegate
çağrılır. Örneğin:
public override void DidFailToContinueUserActivitiy (UIApplication application, string userActivityType, NSError error)
{
// Log information about the failure
Console.WriteLine ("User Activity {0} failed to continue. Error: {1}", userActivityType, error.LocalizedDescription);
}
Kullanıcıya hata hakkında bilgi sağlamak için sağlanan NSError
öğesini kullanmanız gerekir.
Yerel Uygulamadan Web Tarayıcısına İletimi
Kullanıcı, istenen cihazda uygun bir yerel uygulama yüklü olmadan bir etkinliğe devam etmek isteyebilir. Bazı durumlarda, web tabanlı bir arabirim gerekli işlevselliği sağlayabilir ve etkinlik devam edebilir. Örneğin, kullanıcının e-posta hesabı iletileri oluşturmak ve okumak için web tabanlı bir kullanıcı arabirimi sağlayabilir.
Kaynak, yerel uygulama web arabiriminin URL'sini (ve devam edilen öğeyi tanımlamak için gerekli söz dizimini) biliyorsa, bu bilgileri örneğin özelliğinde WebpageURL
NSUserActivity
kodlayabilir. Alıcı cihazda devamı işlemek için uygun bir yerel uygulama yüklü değilse, sağlanan web arabirimi çağrılabilir.
Web Tarayıcıdan Yerel Uygulamaya İletim
Kullanıcı kaynak cihazda web tabanlı bir arabirim kullanıyorsa ve alıcı cihazdaki yerel bir uygulama özelliğin WebpageURL
etki alanı bölümünü talep ederse, sistem bu uygulamayı devamlılığı işleyen uygulamayı kullanır. Yeni cihaz Etkinlik Türü'nü olarak işaretleyen bir NSUserActivity
örnek alır ve WebpageURL
kullanıcının ziyaret edeceği URL'yi içerir, UserInfo
sözlük boş olur.BrowsingWeb
Bir uygulamanın bu tür bir İletim'e katılması için, etki alanını biçiminde <service>:<fully qualified domain name>
bir com.apple.developer.associated-domains
yetkilendirmede talep etmesi gerekir (örneğin: activity continuation:company.com
).
Belirtilen etki alanı bir WebpageURL
özelliğin değeriyle eşleşiyorsa, Handoff bu etki alanındaki web sitesinden onaylı uygulama kimliklerinin listesini indirir. Web sitesi, apple-app-site-association adlı imzalı bir JSON dosyasında onaylı kimliklerin listesini sağlamalıdır (örneğin, https://company.com/apple-app-site-association
).
Bu JSON dosyası, biçimindeki <team identifier>.<bundle identifier>
uygulama kimliklerinin listesini belirten bir sözlük içerir. Örneğin:
{
"activitycontinuation": {
"apps": [ "YWBN8XTPBJ.com.company.FirstApp",
"YWBN8XTPBJ.com.company.SecondApp" ]
}
}
JSON dosyasını imzalamak için (değerinin doğru Content-Type
application/pkcs7-mime
olması için), Terminal uygulamasını ve iOS tarafından güvenilen bir sertifika yetkilisi tarafından verilen sertifika ve anahtara sahip bir openssl
komutu kullanın (liste için bkzhttps://support.apple.com/kb/ht5012. ). Örneğin:
echo '{"activitycontinuation":{"apps":["YWBN8XTPBJ.com.company.FirstApp",
"YWBN8XTPBJ.com.company.SecondApp"]}}' > json.txt
cat json.txt | openssl smime -sign -inkey company.com.key
-signer company.com.pem
-certfile intermediate.pem
-noattr -nodetach
-outform DER > apple-app-site-association
Komut, openssl
web sitenize apple-app-site-association URL'sinde yerleştirdiğiniz imzalı bir JSON dosyasının çıkışını oluşturur. Örneğin:
https://example.com/apple-app-site-association.
Uygulama, etki alanı yetkilendirmesinde com.apple.developer.associated-domains
olan WebpageURL
tüm etkinlikleri alır. http
Yalnızca ve https
protokolleri desteklenir, diğer protokoller özel durum oluşturur.
Belge Tabanlı Uygulamalarda İletimi Destekleme
Yukarıda belirtildiği gibi, iOS ve OS X'te, uygulamanın Info.plist dosyasında CFBundleDocumentTypes
anahtarı NSUbiquitousDocumentUserActivityType
varsa, belge tabanlı uygulamalar iCloud tabanlı belgelerin teslimini otomatik olarak destekler. Örneğin:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>NSRTFDPboardType</string>
. . .
<key>LSItemContentTypes</key>
<array>
<string>com.myCompany.rtfd</string>
</array>
. . .
<key>NSUbiquitousDocumentUserActivityType</key>
<string>com.myCompany.myEditor.editing</string>
</dict>
</array>
Bu örnekte dize, etkinliğin adı eklenmiş bir ters DNS uygulama belirleyicisidir. Bu şekilde girilirse, etkinlik türü girdilerinin Info.plist dosyasının dizisinde NSUserActivityTypes
yinelenmeleri gerekmez.
Otomatik olarak oluşturulan Kullanıcı Etkinliği nesnesine (belgenin UserActivity
özelliği aracılığıyla kullanılabilir) uygulamadaki diğer nesneler tarafından başvurulabilir ve devamlılık durumunu geri yüklemek için kullanılabilir. Örneğin, öğe seçimini ve belge konumunu izlemek için. Durum değiştiğinde ve yöntemindeki UpdateUserActivityState
sözlüğü güncelleştirdiğinizde UserInfo
bu etkinlikler NeedsSave
özelliğini true
olarak ayarlamanız gerekir.
UserActivity
özelliği herhangi bir iş parçacığından kullanılabilir ve anahtar-değer gözlemleme (KVO) protokolüne uygun olduğundan, iCloud'a girip çıktıktan sonra belgeyi eşitlenmiş durumda tutmak için kullanılabilir. UserActivity
Belge kapatıldığında özellik geçersiz kılınacak.
Daha fazla bilgi için lütfen Belge Tabanlı Uygulamalarda Apple'ın Kullanıcı Etkinliği Desteği belgelerine bakın.
Yanıtlayıcılarda İletimi Destekleme
Yanıtlayanları (iOS veya NSResponder
OS X'ten UIResponder
devralınan) özelliklerini ayarlayarak UserActivity
etkinliklerle ilişkilendirebilirsiniz. Sistem, yöntemini kullanarak kullanıcı etkinliği nesnesine UserActivity
geçerli verileri eklemek için yanıtlayanın UpdateUserActivityState
yöntemini çağırarak AddUserInfoEntriesFromDictionary
özelliği uygun zamanlarda otomatik olarak kaydeder.
Devamlılık Akışlar Destekleme
Bir etkinliğe devam etmek için gereken bilgi miktarının ilk İletim yükü tarafından verimli bir şekilde aktarılamadığı durumlar olabilir. Bu gibi durumlarda, alıcı uygulama verileri aktarmak için kendisiyle kaynak uygulama arasında bir veya daha fazla akış oluşturabilir.
Kaynak uygulama, örneğin özelliğini NSUserActivity
olarak true
ayarlarSupportsContinuationStreams
. Örneğin:
// Create a new user Activity to support this tab
UserActivity = new NSUserActivity (ThisApp.UserActivityTab1){
Title = "Weather Tab",
SupportsContinuationStreams = true
};
UserActivity.Delegate = new UserActivityDelegate ();
// Update the activity when the tab's URL changes
var userInfo = new NSMutableDictionary ();
userInfo.Add (new NSString ("Url"), new NSString (url));
UserActivity.AddUserInfoEntries (userInfo);
// Inform Activity that it has been updated
UserActivity.BecomeCurrent ();
Daha sonra alıcı uygulama, akışı oluşturmak için içindeki AppDelegate
yöntemini NSUserActivity
çağırabilirGetContinuationStreams
. Örneğin:
public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
// Report Activity
Console.WriteLine ("Continuing User Activity: {0}", userActivity.ToString());
// Get input and output streams from the Activity
userActivity.GetContinuationStreams ((NSInputStream arg1, NSOutputStream arg2, NSError arg3) => {
// Send required data via the streams
// ...
});
// Take action based on the Activity type
switch (userActivity.ActivityType) {
case "com.xamarin.monkeybrowser.tab1":
// Preform handoff
Tab1.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab1});
break;
case "com.xamarin.monkeybrowser.tab2":
// Preform handoff
Tab2.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab2});
break;
case "com.xamarin.monkeybrowser.tab3":
// Preform handoff
Tab3.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab3});
break;
case "com.xamarin.monkeybrowser.tab4":
// Preform handoff
Tab4.PerformHandoff (userActivity);
completionHandler (new NSObject[]{Tab4});
break;
}
// Inform system we handled this
return true;
}
Kaynak cihazda Kullanıcı Etkinliği Temsilcisi, devam eden cihazda kullanıcı etkinliğine devam etmek için istenen verileri sağlamak için yöntemini çağırarak DidReceiveInputStream
akışları alır.
Akış verilerine salt okunur erişim sağlamak ve NSOutputStream
yalnızca yazma erişimi sağlamak için kullanacaksınızNSInputStream
. Akışlar, alıcı uygulamanın daha fazla veri istediği ve kaynak uygulamanın bunu sağladığı istek ve yanıt biçiminde kullanılmalıdır. Böylece, kaynak cihazdaki çıkış akışına yazılan veriler devam eden cihazdaki giriş akışından okunur ve bunun tersi de geçerlidir.
Continuation Stream'in gerekli olduğu durumlarda bile, iki uygulama arasında en az sayıda ileri geri iletişim olmalıdır.
Daha fazla bilgi için Apple'ın Devamlılık kullanma Akışlar belgelerine bakın.
En İyi İletim Yöntemleri
Bir Kullanıcı Etkinliğinin Handoff aracılığıyla sorunsuz bir şekilde devam ettirilmesi, ilgili tüm bileşenler nedeniyle dikkatli bir tasarım gerektirir. Apple, Handoff özellikli uygulamalarınız için aşağıdaki en iyi yöntemleri benimsemeyi önerir:
- Kullanıcı Etkinliklerinizi, devam edilecek etkinliğin durumunu ilişkilendirmek için mümkün olan en küçük yükü gerektirecek şekilde tasarlar. Yük ne kadar büyük olursa, devamın başlaması o kadar uzun sürer.
- Başarılı bir devam için büyük miktarda veri aktarmanız gerekiyorsa yapılandırma ve ağ ek yüküne ilişkin maliyetleri dikkate alın.
- Büyük bir Mac uygulamasının iOS cihazlarında birkaç, daha küçük, göreve özgü uygulamalar tarafından işlenen Kullanıcı Etkinlikleri oluşturması yaygın bir durumdur. Farklı uygulama ve işletim sistemi sürümleri birlikte iyi çalışacak veya düzgün bir şekilde başarısız olacak şekilde tasarlanmalıdır.
- Etkinlik Türlerinizi belirtirken çakışmaları önlemek için ters DNS gösterimini kullanın. Bir etkinlik belirli bir uygulamaya özgüyse, adı tür tanımına (örneğin
com.myCompany.myEditor.editing
) eklenmelidir. Etkinlik birden çok uygulamada çalışabiliyorsa, tanımdan uygulama adını bırakın (örneğincom.myCompany.editing
). - Uygulamanızın kullanıcı etkinliğinin (
NSUserActivity
) durumunu güncelleştirmesi gerekiyorsa özelliğini olaraktrue
ayarlayınNeedsSave
. Uygun zamanlarda, Handoff temsilcininUserActivityWillSave
yöntemini çağırır, böylece sözlüğü gerektiği gibi güncelleştirebilirsinizUserInfo
. - İletim işlemi alıcı cihazda anında başlatılamadığından, '
WillContinueUserActivity
leriAppDelegate
uygulamalı ve kullanıcıya bir devamın başlamak üzere olduğunu bildirmelisiniz.
Örnek İletim Uygulaması
Xamarin.iOS uygulamasında Handoff'un kullanılmasına örnek olarak MonkeyBrowser örnek uygulaması verilmiştir. Uygulamada, kullanıcının web'e göz atmak için kullanabileceği dört sekme vardır ve her birinin belirli bir etkinlik türü vardır: Hava Durumu, Sık Kullanılan, Kahve Molası ve Çalışma.
Herhangi bir sekmede, kullanıcı yeni bir URL girip Git düğmesine dokunduğunda, o sekme için kullanıcının şu anda göz atmakta olduğu URL'yi içeren yeni NSUserActivity
bir sekme oluşturulur:
Kullanıcının başka bir cihazında MonkeyBrowser uygulaması yüklüyse, aynı kullanıcı hesabı kullanılarak iCloud'da oturum açıldıysa, aynı ağdaysa ve yukarıdaki cihaza yakınsa, Handoff Etkinliği giriş ekranında (sol alt köşede) görüntülenir:
Kullanıcı, İletim simgesine yukarı doğru sürüklenirse uygulama başlatılır ve içinde NSUserActivity
belirtilen Kullanıcı Etkinliği yeni cihazda devam eder:
Kullanıcı Etkinliği başarılı bir şekilde başka bir Apple cihazına gönderildiğinde, gönderen cihaz NSUserActivity
Kullanıcı Etkinliğinin başka bir cihaza başarıyla aktarıldığını bildirmek için yöntemine NSUserActivityDelegate
bir çağrı UserActivityWasContinued
alır.
Özet
Bu makalede, kullanıcının Apple cihazlarının birden çoğu arasında Kullanıcı Etkinliğine devam etmek için kullanılan İletim çerçevesine giriş bilgileri verilmiştir. Ardından, Xamarin.iOS uygulamasında Handoff'un nasıl etkinleştirileceği ve uygulandığı gösterildi. Son olarak, kullanılabilir farklı Türlerde İletim devamı ve En iyi İletim yöntemleri ele alınmıştı.