Aracılığıyla paylaş


Bölüm 5 - Pratik Kod Paylaşma Stratejileri

Bu bölümde, yaygın uygulama senaryoları için kod paylaşma örnekleri verilmiştir.

Veri Katmanı

Veri katmanı, bir depolama altyapısından ve bilgileri okuma ve yazma yöntemlerinden oluşur. Performans, esneklik ve platformlar arası uyumluluk için Xamarin platformlar arası uygulamalar için SQLite veritabanı altyapısı önerilir. Windows, Android, iOS ve Mac gibi çok çeşitli platformlarda çalışır.

SQLite

SQLite bir açık kaynak veritabanı uygulamasıdır. Kaynak ve belgeler SQLite.org bulunabilir. SQLite desteği her mobil platformda kullanılabilir:

  • iOS : İşletim sisteminde yerleşik olarak bulunur.
  • Android – Android 2.2'den (API Düzeyi 10) bu yana işletim sisteminde yerleşiktir.
  • Windows : bkz. Evrensel Windows Platformu uzantısı için SQLite.

Tüm platformlarda kullanılabilen veritabanı altyapısıyla bile veritabanına erişmek için kullanılan yerel yöntemler farklıdır. Hem iOS hem de Android, Xamarin.iOS veya Xamarin.Android'den kullanılabilecek SQLite'e erişmek için yerleşik API'ler sunar, ancak yerel SDK yöntemlerini kullanmak kod paylaşma olanağı sunmaz (dize olarak depolandığı varsayılarak SQL sorguları dışında). iOS veya Android SQLiteOpenHelper sınıfında yerel veritabanı işlevselliğiyle ilgili ayrıntılar için CoreData arama yapın; bu seçenekler platformlar arası olmadığından bu belgenin kapsamı dışındadır.

ADO.NET

Hem Xamarin.iOS hem de Xamarin.Android desteği System.Data ve Mono.Data.Sqlite (daha fazla bilgi için Xamarin.iOS belgelerine bakın). Bu ad alanlarını kullanmak, her iki platformda da çalışan ADO.NET kod yazmanızı sağlar. Projenin başvurularını eklemek System.Data.dll ve Mono.Data.Sqlite.dll kodunuza deyimleri kullanarak eklemek için düzenleyin:

using System.Data;
using Mono.Data.Sqlite;

Ardından aşağıdaki örnek kod çalışır:

string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal),
        "items.db3");
bool exists = File.Exists (dbPath);
if (!exists)
    SqliteConnection.CreateFile (dbPath);
var connection = new SqliteConnection ("Data Source=" + dbPath);
connection.Open ();
if (!exists) {
    // This is the first time the app has run and/or that we need the DB.
    // Copy a "template" DB from your assets, or programmatically create one like this:
    var commands = new[]{
        "CREATE TABLE [Items] (Key ntext, Value ntext);",
        "INSERT INTO [Items] ([Key], [Value]) VALUES ('sample', 'text')"
    };
    foreach (var command in commands) {
        using (var c = connection.CreateCommand ()) {
            c.CommandText = command;
            c.ExecuteNonQuery ();
        }
    }
}
// use `connection`... here, we'll just append the contents to a TextView
using (var contents = connection.CreateCommand ()) {
    contents.CommandText = "SELECT [Key], [Value] from [Items]";
    var r = contents.ExecuteReader ();
    while (r.Read ())
        Console.Write("\n\tKey={0}; Value={1}",
                r ["Key"].ToString (),
                r ["Value"].ToString ());
}
connection.Close ();

ADO.NET gerçek dünya uygulamaları açıkça farklı yöntemlere ve sınıflara bölünür (bu örnek yalnızca gösterim amaçlıdır).

SQLite-NET – Platformlar Arası ORM

ORM (veya Nesne-İlişkisel Eşleyici) sınıflarda modellenen verilerin depolanmasını basitleştirmeye çalışır. SıNıF alanlarından ve özelliklerinden el ile ayıklanan, TABL'ler veya SELECT, INSERT ve DELETE verileri oluşturan SQL sorgularını el ile yazmak yerine, ORM bunu sizin için sağlayan bir kod katmanı ekler. Bir ORM, sınıflarınızın yapısını incelemek için yansıma kullanarak otomatik olarak bir sınıfla eşleşen tablolar ve sütunlar oluşturabilir ve verileri okumak ve yazmak için sorgular oluşturabilir. Bu, uygulama kodunun orm'a nesne örnekleri göndermesine ve almasına olanak tanır ve bu da arka planda tüm SQL işlemlerini gerçekleştirir.

SQLite-NET, SQLite'te sınıflarınızı kaydetmenize ve almanıza olanak sağlayan basit bir ORM işlevi görür. Derleyici yönergeleri ve diğer püf noktalarının bir bileşimiyle platformlar arası SQLite erişiminin karmaşıklığını gizler.

SQLite-NET özellikleri:

  • Tablolar, Model sınıflarına öznitelikler eklenerek tanımlanır.
  • Bir veritabanı örneği, SQLite-Net kitaplığındaki ana sınıfın bir alt SQLiteConnection sınıfıyla temsil edilir.
  • Veriler nesneler kullanılarak eklenebilir, sorgulanabilir ve silinebilir. SQL deyimi gerekmez (gerekirse SQL deyimleri yazabilirsiniz).
  • Temel Linq sorguları SQLite-NET tarafından döndürülen koleksiyonlarda gerçekleştirilebilir.

SQLite-NET için kaynak kodu ve belgeler github'daki SQLite-Net'te mevcuttur ve her iki örnek olay incelemesinde de uygulanmıştır. SQLite-NET kodunun basit bir örneği (Tasky Pro örnek olay incelemesinden) aşağıda gösterilmiştir.

İlk olarak, TodoItem sınıfı veritabanı birincil anahtarı olacak bir alan tanımlamak için öznitelikleri kullanır:

public class TodoItem : IBusinessEntity
{
    public TodoItem () {}
    [PrimaryKey, AutoIncrement]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Notes { get; set; }
    public bool Done { get; set; }
}

Bu, bir örnekte aşağıdaki kod satırıyla (ve SQL deyimi olmadan) bir TodoItem SQLiteConnection tablo oluşturulmasını sağlar:

CreateTable<TodoItem> ();

Tablodaki veriler üzerinde diğer yöntemlerle de işlenebilir (sql deyimlerine SQLiteConnection gerek kalmadan):

Insert (TodoItem); // 'task' is an instance with data populated in its properties
Update (TodoItem); // Primary Key field must be populated for Update to work
Table<TodoItem>.ToList(); // returns all rows in a collection

Tüm örnekler için örnek olay incelemesi kaynak koduna bakın.

Dosya Erişimi

Dosya erişiminin herhangi bir uygulamanın önemli bir parçası olduğu kesindir. Bir uygulamanın parçası olabilecek yaygın dosya örnekleri şunlardır:

  • SQLite veritabanı dosyaları.
  • Kullanıcı tarafından oluşturulan veriler (metin, resimler, ses, video).
  • Önbelleğe alma için indirilen veriler (resimler, html veya PDF dosyaları).

Doğrudan Erişim System.IO

Hem Xamarin.iOS hem de Xamarin.Android, ad alanında sınıfları kullanarak dosya sistemi erişimine System.IO izin verir.

Her platformun dikkate alınması gereken farklı erişim kısıtlamaları vardır:

  • iOS uygulamaları, çok kısıtlı dosya sistemi erişimine sahip bir korumalı alanda çalışır. Apple, yedeklenen belirli konumları (ve yedeklenmemiş diğer konumları) belirterek dosya sistemini nasıl kullanacağınızı da belirler. Daha fazla ayrıntı için Xamarin.iOS'ta Dosya Sistemi ile Çalışma kılavuzuna bakın.
  • Android ayrıca uygulamayla ilgili belirli dizinlere erişimi kısıtlar, ancak dış medyayı da destekler (örn. SD kartları) ve paylaşılan verilere erişme.
  • Windows Phone 8 (Silverlight) doğrudan dosya erişimine izin vermez; dosyalar yalnızca kullanılarak IsolatedStoragedeğiştirilebilir.
  • Windows 8.1 WinRT ve Windows 10 UWP projeleri yalnızca diğer platformlardan farklı olan API'ler aracılığıyla Windows.Storage zaman uyumsuz dosya işlemleri sunar.

iOS ve Android örneği

Aşağıda bir metin dosyası yazan ve okuyan önemsiz bir örnek gösterilmiştir. kullanarak Environment.GetFolderPath aynı kodun iOS ve Android'de çalıştırılmasına olanak tanır ve her birinin dosya sistemi kurallarına göre geçerli bir dizin döndürmesi gerekir.

string filePath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal),
        "MyFile.txt");
System.IO.File.WriteAllText (filePath, "Contents of text file");
Console.WriteLine (System.IO.File.ReadAllText (filePath));

iOS'a özgü dosya sistemi işlevselliği hakkında daha fazla bilgi için Xamarin.iOS Dosya Sistemi ile çalışma belgesine bakın. Platformlar arası dosya erişim kodu yazarken, bazı dosya sistemlerinin büyük/küçük harfe duyarlı olduğunu ve farklı dizin ayırıcıları olduğunu unutmayın. Dosya veya dizin yolları oluştururken dosya adları ve Path.Combine() yöntemi için her zaman aynı büyük/küçük harf kullanımını kullanmak iyi bir uygulamadır.

Windows 8 ve Windows 10 için Windows.Storage

Xamarin.Forms ile Mobil Uygulama Oluşturma kitabıBölüm 20. Zaman Uyumsuz ve Dosya G/Ç, Windows 8.1 ve Windows 10 için örnekler içerir.

DependencyService Desteklenen API'leri kullanarak bu platformlardaki dosyaları okumak ve dosya oluşturmak mümkündür:

StorageFolder localFolder = ApplicationData.Current.LocalFolder;
IStorageFile storageFile = await localFolder.CreateFileAsync("MyFile.txt",
                                        CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(storageFile, "Contents of text file");

Daha fazla ayrıntı için kitap bölümü 20'ye bakın.

Windows Phone 7 ve 8'de Yalıtılmış Depolama (Silverlight)

Yalıtılmış Depolama, tüm iOS, Android ve eski Windows Phone platformları arasında dosya kaydetmeye ve yüklemeye yönelik yaygın bir API'dir.

Ortak dosya erişim kodunun yazılması için Xamarin.iOS ve Xamarin.Android'de uygulanan Windows Phone'da (Silverlight) dosya erişimi için varsayılan mekanizmadır. Sınıfına System.IO.IsolatedStorage Paylaşılan Projedeki üç platformda da başvurulabilir.

Daha fazla bilgi için Windows Phone için Yalıtılmış Depolamaya Genel Bakış'a bakın.

Yalıtılmış Depolama API'leri Taşınabilir Sınıf Kitaplıklarında kullanılamaz. PCL için bir alternatif, PCLStorage NuGet'tir

PCL'lerde platformlar arası dosya erişimi

Xamarin tarafından desteklenen platformlar ve en son Windows API'leri için platformlar arası dosya erişimi sağlayan PCL uyumlu bir NuGet ( PCLStorage ) de vardır.

Ağ İşlemleri

Çoğu mobil uygulamanın ağ bileşeni olur, örneğin:

  • Görüntü, video ve ses indirme (örn. küçük resimler, fotoğraflar, müzik).
  • Belgelerin indirilmesi (örn. HTML, PDF).
  • Kullanıcı verilerini (fotoğraflar veya metinler gibi) karşıya yükleme.
  • Web hizmetlerine veya üçüncü taraf API'lere (SOAP, XML veya JSON dahil) erişme.

.NET Framework, ağ kaynaklarına erişmek için birkaç farklı sınıf sağlar: HttpClient, WebClientve HttpWebRequest.

HttpClient

HttpClient Ad alanında System.Net.Http sınıfı Xamarin.iOS, Xamarin.Android ve çoğu Windows platformunda kullanılabilir. Bu API'yi Taşınabilir Sınıf Kitaplıklarına (ve Windows Phone 8 Silverlight) getirmek için kullanılabilecek bir Microsoft HTTP İstemci Kitaplığı NuGet vardır.

var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://xamarin.com");
var response = await myClient.SendAsync(request);

WebClient

sınıfı, WebClient uzak sunuculardan uzak verileri almak için basit bir API sağlar.

Xamarin.iOS ve Xamarin.Android zaman uyumlu işlemleri (arka plan iş parçacıklarında yapılabilir) desteklese de Evrensel Windows Platformu işlemleri zaman uyumsuz olmalıdır.

Basit bir zaman uyumsuz WebClient işlemin kodu şöyledir:

var webClient = new WebClient ();
webClient.DownloadStringCompleted += (sender, e) =>
{
    var resultString = e.Result;
    // do something with downloaded string, do UI interaction on main thread
};
webClient.Encoding = System.Text.Encoding.UTF8;
webClient.DownloadStringAsync (new Uri ("http://some-server.com/file.xml"));

WebClientayrıca ikili verileri almak için ve'ye DownloadFileAsync sahiptirDownloadFileCompleted.

HttpWebRequest

HttpWebRequest daha fazla özelleştirme WebClient sunar ve sonuç olarak kullanmak için daha fazla kod gerektirir.

Basit bir zaman uyumlu HttpWebRequest işlemin kodu:

var request = HttpWebRequest.Create(@"http://some-server.com/file.xml ");
request.ContentType = "text/xml";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
    if (response.StatusCode != HttpStatusCode.OK)
        Console.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        var content = reader.ReadToEnd();
        // do something with downloaded string, do UI interaction on main thread
    }
}

Web Hizmetleri belgelerimizde bir örnek verilmiştir.

Ulaşılabilirlik

Mobil cihazlar, hızlı Wi-Fi veya 4G bağlantılarından zayıf alım alanlarına ve yavaş EDGE veri bağlantılarına kadar çeşitli ağ koşulları altında çalışır. Bu nedenle, uzak sunuculara bağlanmaya çalışmadan önce ağın kullanılabilir olup olmadığını ve varsa hangi ağ türünün kullanılabilir olduğunu algılamak iyi bir uygulamadır.

Bir mobil uygulamanın bu durumlarda gerçekleştirebileceği eylemler şunlardır:

  • Ağ kullanılamıyorsa kullanıcıya öneride bulunın. El ile devre dışı bırakmışlarsa (örn. Uçak modu veya Wi-Fi'yi kapatma) bu durumda sorunu çözebilirler.
  • Bağlantı 3G ise, uygulamalar farklı davranabilir (örneğin, Apple 20 Mb'tan büyük uygulamaların 3G üzerinden indirilmesine izin vermez). Uygulamalar, büyük dosyaları alırken kullanıcıyı aşırı indirme süreleri hakkında uyarmak için bu bilgileri kullanabilir.
  • Ağ kullanılabilir olsa bile, diğer istekleri başlatmadan önce hedef sunucuyla bağlantıyı doğrulamak iyi bir uygulamadır. Bu, uygulamanın ağ işlemlerinin art arda zaman aşımına uğramasını engeller ve ayrıca kullanıcıya daha bilgilendirici bir hata iletisi görüntülenmesine izin verir.

Web Hizmetleri

Xamarin.iOS kullanarak REST, SOAP ve WCF uç noktalarına erişimi kapsayan Web Hizmetleri ile çalışma hakkındaki belgelerimize bakın. Web hizmeti isteklerini el ile oluşturmak ve yanıtları ayrıştırmak mümkündür, ancak Azure, RestSharp ve ServiceStack gibi çok daha basit hale getirmek için kullanılabilir kitaplıklar vardır. Temel WCF işlemlerine bile Xamarin uygulamalarından erişilebilir.

Azure

Microsoft Azure, mobil uygulamalar için veri depolama ve eşitleme ile anında iletme bildirimleri dahil olmak üzere çok çeşitli hizmetler sunan bir bulut platformudur.

Ücretsiz denemek için azure.microsoft.com ziyaret edin.

RestSharp

RestSharp, web hizmetlerine erişimi basitleştiren bir REST istemcisi sağlamak için mobil uygulamalara dahil edilebilen bir .NET kitaplığıdır. Veri istemek ve REST yanıtını ayrıştırmak için basit bir API sağlayarak yardımcı olur. RestSharp yararlı olabilir

RestSharp web sitesi, RestSharp kullanarak REST istemcisi uygulama hakkında belgeler içerir. RestSharp, github'da Xamarin.iOS ve Xamarin.Android örnekleri sağlar.

Web Hizmetleri belgelerimizde bir Xamarin.iOS kod parçacığı da vardır.

ServiceStack

RestSharp'ın aksine, ServiceStack hem bir web hizmetini hem de bu hizmetlere erişmek için mobil uygulamalarda uygulanabilen bir istemci kitaplığını barındırmak için bir sunucu tarafı çözümüdür.

ServiceStack web sitesi projenin amacını açıklar ve belge ve kod örneklerine bağlantılar içerir. Örnekler, bir web hizmetinin sunucu tarafı uygulamasının yanı sıra buna erişebilen çeşitli istemci tarafı uygulamalarını içerir.

WCF

Xamarin araçları bazı Windows Communication Foundation (WCF) hizmetlerini kullanmanıza yardımcı olabilir. Genel olarak Xamarin, Silverlight çalışma zamanıyla birlikte gelen WCF'nin istemci tarafı alt kümesini destekler. Bu, WCF'nin en yaygın kodlama ve protokol uygulamalarını içerir: kullanarak HTTP aktarım protokolü BasicHttpBindingüzerinden metin kodlanmış SOAP iletileri.

WCF çerçevesinin boyutu ve karmaşıklığı nedeniyle, Xamarin'in istemci alt kümesi etki alanı tarafından desteklenen kapsamın dışında kalacak geçerli ve gelecekteki hizmet uygulamaları olabilir. Ayrıca WCF desteği, ara sunucuyu oluşturmak için yalnızca Windows ortamında kullanılabilen araçların kullanılmasını gerektirir.

İş Parçacığı Oluşturma

Uygulama yanıt hızı mobil uygulamalar için önemlidir; kullanıcılar uygulamaların hızla yüklenmesini ve gerçekleştirilmesini bekler. Kullanıcı girişi kabul edilmeyi durduran bir 'donmuş' ekran, uygulamanın kilitlendiğini gösterir, bu nedenle kullanıcı arabirimi iş parçacığını ağ istekleri veya yavaş yerel işlemler (örneğin, dosyanın sıkıştırmasını açma) gibi uzun süre çalışan engelleme çağrılarıyla bağlamamak önemlidir. Özellikle başlatma işlemi uzun süre çalışan görevler içermemelidir; tüm mobil platformlar yüklenmesi çok uzun süren bir uygulamayı öldürür.

Bu, kullanıcı arabiriminizin hızla görüntülenebilen bir 'ilerleme göstergesi' veya başka bir şekilde 'kullanılabilir' kullanıcı arabirimi ve arka plan işlemlerini gerçekleştirmek için zaman uyumsuz görevler uygulaması gerektiği anlamına gelir. Arka plan görevlerinin yürütülmesi için iş parçacıklarının kullanılması gerekir; bu da arka plan görevlerinin ilerleme durumunu veya ne zaman tamamlandığını belirtmek için ana iş parçacığına geri iletişim kurmak için bir yönteme ihtiyacı olduğu anlamına gelir.

Paralel Görev Kitaplığı

Paralel Görev Kitaplığı ile oluşturulan görevler zaman uyumsuz olarak çalışabilir ve çağrı iş parçacığında döndürülebilir, bu da kullanıcı arabirimini engellemeden uzun süre çalışan işlemleri tetiklemede çok yararlı olmalarını sağlar.

Basit bir paralel görev işlemi şöyle görünebilir:

using System.Threading.Tasks;
void MainThreadMethod ()
{
    Task.Factory.StartNew (() => wc.DownloadString ("http://...")).ContinueWith (
        t => label.Text = t.Result, TaskScheduler.FromCurrentSynchronizationContext()
    );
}

Anahtar, TaskScheduler.FromCurrentSynchronizationContext() yöntemini çağıran iş parçacığının SynchronizationContext.Current öğesini (burada çalışan MainThreadMethodana iş parçacığı) bu iş parçacığına geri çağrıları hazırlamanın bir yolu olarak yeniden kullanacak olan anahtardır. Bu, yöntemi ui iş parçacığında çağrılırsa, ui iş parçacığında ContinueWith işlemi yeniden çalıştıracağı anlamına gelir.

Kod görevleri diğer iş parçacıklarından başlatıyorsa, kullanıcı arabirimi iş parçacığına başvuru oluşturmak için aşağıdaki deseni kullanın; görev yine de buna geri çağrı yapabilir:

static Context uiContext = TaskScheduler.FromCurrentSynchronizationContext();

Kullanıcı Arabirimi İş Parçacığında Çağırma

Paralel Görev Kitaplığı'nı kullanmayan kodlar için her platformun, işlemleri ui iş parçacığına geri hazırlamaya yönelik kendi söz dizimi vardır:

  • iOSowner.BeginInvokeOnMainThread(new NSAction(action))
  • Androidowner.RunOnUiThread(action)
  • Xamarin.FormsDevice.BeginInvokeOnMainThread(action)
  • WindowsDeployment.Current.Dispatcher.BeginInvoke(action)

Hem iOS hem de Android söz diziminin kullanılabilir olması için bir 'context' sınıfı gerekir; bu da kodun bu nesneyi ui iş parçacığında geri çağırma gerektiren herhangi bir yönteme geçirmesi gerektiği anlamına gelir.

Paylaşılan kodda UI iş parçacığı çağrıları yapmak için IDispatchOnUIThread örneğini izleyin (@follesoe izniyle). Paylaşılan koddaki bir IDispatchOnUIThread arabirime bildirin ve programlayın ve ardından burada gösterildiği gibi platforma özgü sınıfları uygulayın:

// program to the interface in shared code
public interface IDispatchOnUIThread {
    void Invoke (Action action);
}
// iOS
public class DispatchAdapter : IDispatchOnUIThread {
    public readonly NSObject owner;
    public DispatchAdapter (NSObject owner) {
        this.owner = owner;
    }
    public void Invoke (Action action) {
        owner.BeginInvokeOnMainThread(new NSAction(action));
    }
}
// Android
public class DispatchAdapter : IDispatchOnUIThread {
    public readonly Activity owner;
    public DispatchAdapter (Activity owner) {
        this.owner = owner;
    }
    public void Invoke (Action action) {
        owner.RunOnUiThread(action);
    }
}
// WP7
public class DispatchAdapter : IDispatchOnUIThread {
    public void Invoke (Action action) {
        Deployment.Current.Dispatcher.BeginInvoke(action);
    }
}

Xamarin.Forms geliştiricileri ortak kodda (Paylaşılan Projeler veya PCL) kullanmalıdır Device.BeginInvokeOnMainThread .

Platform ve Cihaz Özellikleri ve Düşüşü

Platform Özellikleri belgelerinde farklı özelliklerle ilgilenmeye ilişkin daha ayrıntılı örnekler verilmiştir. Farklı özellikleri algılama ve uygulama tam potansiyeliyle çalışamazken bile iyi bir kullanıcı deneyimi sağlamak için bir uygulamayı düzgün bir şekilde nasıl düşürebileceğinizi ele alır.