Birleşik API'ye Genel Bakış
Xamarin'in Birleşik API'si, Mac ile iOS arasında kod paylaşmayı ve aynı ikili dosyaya sahip 32 ve 64 bit uygulamaları desteklemeyi mümkün kılar. Birleşik API, yeni Xamarin.iOS ve Xamarin.Mac projelerinde varsayılan olarak kullanılır.
Önemli
Birleşik API'nin önündeki Xamarin Klasik API'si kullanım dışı bırakıldı.
- Klasik API'yi (monotouch.dll) destekleyen son Xamarin.iOS sürümü Xamarin.iOS 9.10 sürümüdür.
- Xamarin.Mac hala Klasik API'yi destekler, ancak artık güncelleştirilmez. Kullanım dışı bırakıldığından, geliştiricilerin uygulamalarını Birleştirilmiş API'ye taşıması gerekir.
Klasik API Tabanlı Uygulamaları Güncelleştirme
Platformunuz için ilgili yönergeleri izleyin:
- Mevcut Uygulamaları Güncelleştirme
- Mevcut iOS Uygulamalarını Güncelleştirme
- Mevcut Mac Uygulamalarını Güncelleştirme
- Mevcut Xamarin.Forms Uygulamalarını Güncelleştirme
- Bir Bağlamayı Unified API’ye Geçirme
Kodu Unified API’ye Güncelleştirmeye İlişkin İpuçları
Hangi uygulamaları geçirirseniz geçirin, Birleşik API'ye başarıyla güncelleştirmenize yardımcı olmak için bu ipuçlarına göz atın.
Kitaplık Bölme
Bu noktadan sonra API'lerimiz iki şekilde ortaya çıkarılacak:
- Klasik API: ve derlemelerinde
monotouch.dll
kullanıma sunulan 32 bit (yalnızca) ileXamMac.dll
sınırlıdır. - Birleşik API: ve
Xamarin.Mac.dll
derlemelerinde kullanılabilen tek bir API ile hem 32 hem de 64 bit geliştirmeyiXamarin.iOS.dll
destekler.
Bu, Kurumsal geliştiriciler için (App Store'un hedefine değil) mevcut Klasik API'leri kullanmaya devam edebilirsiniz. Bu api'lerin bakımını sonsuza kadar sürdüreceğiz veya yeni API'lere yükseltebilirsiniz.
Ad Alanı Değişiklikleri
Mac ve iOS ürünlerimiz arasındaki kodu paylaşma uyuşmalarını azaltmak için, ürünlerdeki API'lerin ad alanlarını değiştiriyoruz.
iOS ürünümüzden "MonoTouch" ön ekini ve Mac ürünümüzden "MonoMac" ön ekini veri türlerine bırakıyoruz.
Bu, koşullu derlemeye başvurmadan Mac ve iOS platformları arasında kod paylaşmayı kolaylaştırır ve kaynak kod dosyalarınızın üst kısmındaki gürültüyü azaltır.
- Klasik API: Ad alanları veya
MonoMac.
ön eki kullanırMonoTouch.
. - Birleştirilmiş API: Ad alanı ön eki yok
Çalışma Zamanı Varsayılanları
Birleştirilmiş API varsayılan olarak nesne sahipliğini izlemek için SGen çöp toplayıcısını ve Yeni Başvuru Sayma sistemini kullanır. Aynı özellik Xamarin.Mac'e de taşınabilir.
Bu, geliştiricilerin eski sistemle karşılaştığı bir dizi sorunu çözer ve bellek yönetimini kolaylaştırır.
Klasik API için bile Yeni Başvuru'yu etkinleştirmenin mümkün olduğunu, ancak varsayılan değerin muhafazakar olduğunu ve kullanıcıların herhangi bir değişiklik yapmasını gerektirmediğini unutmayın. Birleşik API ile varsayılanı değiştirme fırsatı bulduk ve geliştiricilere kodlarını yeniden düzenleyip yeniden test etmeleriyle aynı anda tüm iyileştirmeleri verdik.
API Değişiklikleri
Birleştirilmiş API, kullanım dışı bırakılan yöntemleri kaldırır ve Klasik API'lerdeki özgün MonoTouch ve MonoMac ad alanlarına bağlı olduklarında API adlarında yazım hataları olduğu birkaç örnek vardır. Bu örnekler yeni Birleşik API'lerde düzeltilmiştir ve bileşen, iOS ve Mac uygulamalarınızda güncelleştirilmiş olması gerekir. Karşılaşabileceğiniz en yaygın olanların listesi aşağıdadır:
Klasik API Yöntemi Adı | Birleşik API Yöntem Adı |
---|---|
UINavigationController.PushViewControllerAnimated() |
UINavigationController.PushViewController() |
UINavigationController.PopViewControllerAnimated() |
UINavigationController.PopViewController() |
CGContext.SetRGBFillColor() |
CGContext.SetFillColor() |
NetworkReachability.SetCallback() |
NetworkReachability.SetNotification() |
CGContext.SetShadowWithColor |
CGContext.SetShadow |
UIView.StringSize |
UIKit.UIStringDrawing.StringSize |
Klasik api'den Birleşik API'ye geçiş yaparken yapılan değişikliklerin tam listesi için lütfen Klasik (monotouch.dll) ile Birleşik (Xamarin.iOS.dll) API farklılıkları belgelerimize bakın.
Birleştirilmiş'e Güncelleştirme
Klasikte birkaç eski/bozuk/kullanım dışı API, Birleşik API'de kullanılamaz. Sizi doğru API'ye yönlendirecek öznitelik iletisi (uyarının CS0616
bir parçası) olacağından, (el ile veya otomatik) yükseltmenizi [Obsolete]
başlatmadan önce uyarıları düzeltmek daha kolay olabilir.
Proje güncelleştirmelerinizden önce veya sonra kullanılabilecek klasik ve birleşik API değişikliklerinin farkını yayımladığımıza dikkat edin. Klasik'te eski çağrıları düzeltmeye devam etmek genellikle zaman kazandıracaktır (daha az belge araması).
Mevcut iOS uygulamalarını veya Mac uygulamalarını Birleşik API'ye güncelleştirmek için bu yönergeleri izleyin. Bu sayfanın geri kalanını gözden geçirin ve kodunuzu geçirme hakkında ek bilgi için bu ipuçları .
NuGet
Daha önce Klasik API aracılığıyla Xamarin.iOS'yi destekleyen NuGet paketleri, monotouch10 platform adını kullanarak derlemelerini yayımladı.
Birleşik API, uyumlu paketler için yeni bir platform tanımlayıcısı sunar : Xamarin.iOS10. Mevcut NuGet paketlerinin, Birleştirilmiş API'ye göre oluşturularak bu platform için destek eklemek üzere güncelleştirilmiş olması gerekir.
Önemli
"Hata 3 Aynı Xamarin.iOS projesine hem 'monotouch.dll' hem de 'Xamarin.iOS.dll' eklenemiyor şeklinde bir hatanız varsa , 'Xamarin.iOS.dll' açıkça başvurulur, 'monotouch.dll', uygulamanızı Birleştirilmiş API'lere dönüştürdükten sonra 'xxx, Version=0.0.000, Culture=neutral, PublicKeyToken=null' tarafından başvurulsa da, bunun nedeni genellikle projede Birleştirilmiş API'ye güncelleştirilmemiş bir bileşenin veya NuGet Paketinin bulunmasıdır. Mevcut bileşeni/NuGet'i kaldırmanız, Birleşik API'leri destekleyen bir sürüme güncelleştirmeniz ve temiz bir derleme yapmanız gerekir.
64 Bit'e Giden Yol
32 ve 64 bit uygulamaları desteklemeye ilişkin arka plan bilgileri ve çerçeveler hakkında bilgi için bkz . 32 ve 64 bit Platform Konuları.
Yeni Veri Türleri
Farkın temelinde, hem Mac hem de iOS API'leri 32 bit platformlarda her zaman 32 bit ve 64 bit platformlarda 64 bit olan mimariye özgü veri türlerini kullanır.
Örneğin, Objective-C veri türünü int32_t
32 bit sistemlerde ve int64_t
64 bit sistemlerde ile eşlerNSInteger
.
Bu davranışı eşleştirmek için, Birleşik API'mizde önceki kullanımlarını int
(.NET'te her zaman olmak System.Int32
üzere tanımlanır) yeni bir veri türüyle değiştiriyoruz: System.nint
. "n" değerini "yerel" olarak düşünebilirsiniz, dolayısıyla platformun yerel tamsayı türü.
'yi nuint
kullanıma sunuyoruz nint
ve nfloat
gerektiğinde bunların üzerinde oluşturulan veri türlerini de sunuyoruz.
Bu veri türü değişiklikleri hakkında daha fazla bilgi edinmek için Yerel Türler belgesine bakın.
iOS uygulamalarının mimarisini algılama
Uygulamanızın 32 bit mi yoksa 64 bit iOS sisteminde mi çalıştığını bilmesi gereken durumlar olabilir. Mimariyi denetlemek için aşağıdaki kod kullanılabilir:
if (IntPtr.Size == 4) {
Console.WriteLine ("32-bit App");
} else if (IntPtr.Size == 8) {
Console.WriteLine ("64-bit App");
}
Diziler ve System.Collections.Generic
C# dizin oluşturucuları türü beklediğindenint
, bir koleksiyon veya dizideki öğelere erişmek için int
açıkça değerleri atamanız gerekirnint
. Örneğin:
public List<string> Names = new List<string>();
...
public string GetName(nint index) {
return Names[(int)index];
}
Bu beklenen bir davranıştır çünkü 64 bit'te 'den int
nint
ataması kayıplı olduğundan örtük dönüştürme yapılmaz.
DateTime'ı NSDate'a Dönüştürme
Birleşik API'leri kullanırken, değerlere NSDate
örtük dönüştürme DateTime
işlemi artık gerçekleştirilmemektedir. Bu değerlerin açıkça bir türden diğerine dönüştürülmesi gerekir. Bu işlemi otomatikleştirmek için aşağıdaki uzantı yöntemleri kullanılabilir:
public static DateTime NSDateToDateTime(this NSDate date)
{
// NSDate has a wider range than DateTime, so clip
// the converted date to DateTime.Min|MaxValue.
double secs = date.SecondsSinceReferenceDate;
if (secs < -63113904000)
return DateTime.MinValue;
if (secs > 252423993599)
return DateTime.MaxValue;
return (DateTime) date;
}
public static NSDate DateTimeToNSDate(this DateTime date)
{
if (date.Kind == DateTimeKind.Unspecified)
date = DateTime.SpecifyKind (date, /* DateTimeKind.Local or DateTimeKind.Utc, this depends on each app */)
return (NSDate) date;
}
Kullanım dışı API'ler ve Yazım Hataları
Xamarin.iOS klasik API'sinde [Obsolete]
(monotouch.dll) özniteliği iki farklı şekilde kullanıldı:
- Kullanım dışı bırakılan iOS API'si: Apple, yerine daha yeni bir API geçtiği için API'yi kullanmayı durdurmanızı önerdiği zamandır. Klasik API hala uygundur ve genellikle gereklidir (iOS'un eski sürümünü destekliyorsanız).
Bu API (ve
[Obsolete]
özniteliği) yeni Xamarin.iOS derlemelerine eklenir. - Yanlış API Bazı API'lerde adlarında yazım hataları vardı.
Özgün derlemeler (monotouch.dll ve XamMac.dll) için eski kodu uyumluluk için kullanılabilir durumda tuttuk ancak Birleşik API derlemelerinden (Xamarin.iOS.dll ve Xamarin.Mac) kaldırıldılar
NSObject alt sınıfları .ctor(IntPtr)
Her NSObject
alt sınıfın kabul eden bir IntPtr
oluşturucu vardır. Bu şekilde yerel bir ObjC tanıtıcısından yeni bir yönetilen örnek örneği oluşturabiliriz.
Klasikte bu bir public
oluşturucuydu. Ancak kullanıcı kodunda bu özelliği kötüye kullanmak kolaydı; örneğin, tek bir ObjC örneği için birkaç yönetilen örnek oluşturma veya beklenen yönetilen durumdan yoksun bir yönetilen örnek oluşturma (alt sınıflar için).
Bu tür sorunları IntPtr
önlemek için oluşturucular artık protected
birleşik API'dedir ve yalnızca alt sınıflama için kullanılır. Bu, tanıtıcılardan yönetilen örnek oluşturmak için doğru/güvenli API'nin kullanılmasını sağlar, örneğin.
var label = Runtime.GetNSObject<UILabel> (handle);
Bu API mevcut bir yönetilen örneği döndürür (zaten varsa) veya yeni bir örnek oluşturur (gerektiğinde). Hem klasik hem de birleşik API'de zaten kullanılabilir.
öğesinin de protected
artık olduğunu .ctor(NSObjectFlag)
ancak bunun alt sınıflama dışında nadiren kullanıldığını unutmayın.
NSAction Eylemiyle Değiştirildi
Birleşik API'ler ile, NSAction
standart .NET Action
yerine kaldırıldı. Bu büyük bir gelişmedir çünkü Action
yaygın bir .NET türüdür, ancak NSAction
Xamarin.iOS'a özgüdür. her ikisi de tam olarak aynı şeyi yapar, ancak farklı ve uyumsuz türlerdi ve aynı sonucu elde etmek için daha fazla kod yazılması gerekerek sonuçlandı.
Örneğin, mevcut Xamarin uygulamanız aşağıdaki kodu eklediyse:
UITapGestureRecognizer singleTap = new UITapGestureRecognizer (new NSAction (delegate() {
ShowDropDownAnimated (tblDataView);
}));
Artık basit bir lambda ile değiştirilebilir:
UITapGestureRecognizer singleTap = new UITapGestureRecognizer (() => ShowDropDownAnimated(tblDataView));
Önceden bu bir derleyici hatası olurdu çünkü Action
öğesine atanamaz NSAction
, ancak UITapGestureRecognizer
şimdi yerine bir Action
NSAction
aldığından, Birleşik API'lerde geçerlidir.
Özel temsilciler Eylem<T ile değiştirildi>
Birleşik bazı basit (örneğin, bir parametre) .net temsilcileri ile Action<T>
değiştirildi. Örneğin
public delegate void NSNotificationHandler (NSNotification notification);
artık olarak Action<NSNotification>
kullanılabilir. Bu, hem Xamarin.iOS hem de kendi uygulamalarınızda kodun yeniden kullanılmasını teşvik eder ve kod yinelemesini azaltır.
Görev<bool> değeri Görev<Boole değeri,NSError ile değiştirildi>>
Klasikte, döndüren Task<bool>
bazı zaman uyumsuz API'ler vardı. Ancak bazıları, imzanın bir NSError
parçası olduğunda kullanılacak yerler, yani bool
zaten true
olan ve almak NSError
için bir özel durum yakalamak zorunda kaldınız.
Bazı hatalar çok yaygın olduğundan ve dönüş değeri yararlı olmadığından, bu desen birleşik olarak değiştirilerek döndürüldüTask<Tuple<Boolean,NSError>>
. Bu, hem başarıyı hem de zaman uyumsuz çağrı sırasında olmuş olabilecek hataları denetlemenize olanak tanır.
NSString ile dize karşılaştırması
Birkaç durumda bazı sabitlerin olarak değiştirilmesi string
NSString
gerekiyordu, örneğin. UITableViewCell
Klasik
public virtual string ReuseIdentifier { get; }
Birleşik
public virtual NSString ReuseIdentifier { get; }
Genel olarak .NET System.String
türünü tercih ediyoruz. Ancak, Apple yönergelerine rağmen, bazı yerel API'ler sabit işaretçileri karşılaştırıyor (dizenin kendisini değil) ve bu yalnızca sabitleri olarak NSString
kullanıma sunduğumuzda çalışabilir.
Objective-C Protokol
Özgün MonoTouch, ObjC protokolleri için tam desteğe sahip değildi ve en yaygın senaryoyu desteklemek için bazı, en uygun olmayan API eklendi. Bu sınırlama artık mevcut değildir, ancak geriye dönük uyumluluk için ve XamMac.dll
içinde monotouch.dll
çeşitli API'ler tutulur.
Bu sınırlamalar Birleşik API'lerde kaldırıldı ve temizlendi. Değişikliklerin çoğu şöyle görünür:
Klasik
public virtual AVAssetResourceLoaderDelegate Delegate { get; }
Birleşik
public virtual IAVAssetResourceLoaderDelegate Delegate { get; }
Ön I
ek, ObjC protokolü için belirli bir tür yerine birleşik bir arabirimi kullanıma sunma anlamına gelir. Bu, Xamarin.iOS tarafından sağlanan belirli bir türü alt sınıfa almak istemediğiniz durumları kolaylaştırır.
Ayrıca bazı API'ler daha hassas ve kullanımı kolay hale getirilebilir; örneğin:
Klasik
public virtual void SelectionDidChange (NSObject uiTextInput);
Birleşik
public virtual void SelectionDidChange (IUITextInput uiTextInput);
Bu tür API'ler artık belgelere başvurmadan bizim için daha kolay ve IDE kod tamamlama işleminiz protokole/arabirime dayalı olarak size daha kullanışlı öneriler sağlayacaktır.
NSCoding Protokolü
Özgün bağlamamız, protokolü desteklemese NSCoding
bile her tür için bir .ctor(NSCoder) içeriyor. nesnesini kodlamak için içinde NSObject
tek Encode(NSCoder)
bir yöntem mevcuttu.
Ancak bu yöntem yalnızca örnek NSCoding protokolüne uygunsa çalışır.
Birleştirilmiş API'de bunu düzeltmiş olduk. Yeni derlemelerde yalnızca .ctor(NSCoder)
türü ile uyumluysa NSCoding
olacaktır. Ayrıca bu tür türlerin artık arabirime INSCoding
uygun bir Encode(NSCoder)
yöntemi vardır.
Düşük Etki: Çoğu durumda bu değişiklik eski, kaldırılan oluşturucular kullanılamadığı için uygulamaları etkilemez.
Daha fazla İpuçları
Dikkat edilmesi gereken ek değişiklikler, uygulamaları Birleştirilmiş API'ye güncelleştirme ipuçlarında listelenir.