Mac'te C# ile Android ve iOS Uygulaması Nasıl Yapılır
Yayınlanan: 2022-03-11Bir zamanlar en iyi araçlara sahip bir şirket vardı ve platformları için yazılım yazmak harikaydı. Ama yavaş yavaş kendi sorunlarına karşı kayıtsız hale geldiler. Sistemleri çökünce paniğe kapılmadılar, aksine evrenin bu durumunu hayatın bir gerçeği olarak kabul ettiler. Programlarının kendi içlerinde mükemmel, sakin ve zarif olduğuna, amaçlarının apaçık olduğuna inanıyorlardı.
Ah oğlum, ne kadar yanıldıklarını bir bilselerdi...
Hatalarını anladıklarında çok geçti ve CEO'ları platformlarından ayrılan ve yelken açan tüm geliştiricileri geri getirmek için ağladı. Şirket Microsoft'tu ve ben, bir kere, kaderlerinin mühürlendiğine ve teknoloji dünyasının ön saflarından yavaş ama kesin bir şekilde yok olacaklarına ikna olmuştum.
Yanıldığım için çok mutluyum!
Son birkaç yılda Microsoft, kollarından birkaç as çıkardı. Evet, Skype'ı mahvettiler (bunun için hala onlardan nefret ediyorum), akıllı telefonlarda başarısız oldular ve tabletlerle neredeyse başarılı oldular. Ama aynı zamanda gerçekten harika şeyler de yaptılar. Kapalı imparatorluk yaklaşımlarından vazgeçerek, .NET'i açık kaynaklı hale getirdiler, Linux Vakfı'na katıldılar, Linux için SQL Server'ı piyasaya sürdüler ve Mac için Visual Studio adlı bu harika yeni aracı yarattılar.
Bu doğru, Windows için değil, Mac için gerçek bir Microsoft IDE. Bunu hayal et!
Mac'te C# Kullanarak İlk Çapraz Platform Android ve iOS Uygulamanızı Yazma
Hemen hemen her tür uygulamayı oluşturmak için Mac için Visual Studio'yu kullanabilirsiniz. iOS, tvOS, Android, Mac, .NET Core ve hatta ASP.NET olabilir. Tüm havalı çocuklar artık mobil uygulamalar yazarken, Mac için Visual Studio'da Android ve iOS'ta çalışacak bir C# uygulaması oluşturmak için neler gerektiğini görelim.
Yapmanız gereken ilk şey, uygulama şablonunu seçmek. Basit bir "Single View Uygulaması" ile başlayalım.
Paket adını doldurduktan ve uygulamanızı önyükledikten sonra, Visual Studio üç proje ile bir çözüm oluşturacaktır. İlk proje, platformdan bağımsız kodu tutmanız gereken paylaşılan bir kitaplık olacak, diğer ikisi ise Android ve iOS uygulamaları olacak.
Uygulamanızı başlatmak için "Çalıştır" menüsünü veya uygulama çubuğundaki komutları kullanabilirsiniz.
Tebrikler! Bir satır Objective-C, Swift veya Java kodu yazmamış olmanıza rağmen artık bir iOS ve Android geliştiricisisiniz.
Yine de uygulamamızla henüz pek bir şey başaramadık. İşleri daha ilginç hale getirelim ve haritaları ve konum hizmetlerini dahil edelim.
Haritaları ve Konum Servislerini Kullanma
Mac için VS'nin hala “Önizleme” aşamasında olduğunu ve onu kullanırken bulabileceğiniz çok fazla yardım ve belge olmadığını unutmayın. İşlerin nasıl yapılacağına ilişkin referanslar için en iyi yer hala resmi Xamarin belgeleridir.
Mac için Visual Studio, bilgisayarda görmüş olabileceğiniz Xamarin araçlarıyla aynı çözümü ve uygulama yapısını kullanmaz. Çoğu durumda, örneklerin işe yaraması için birkaç engeli denemeniz ve aşmanız gerekecektir. Umalım ki Microsoft, Mac için VS'nin son sürümü yayınlandığında oyunlarının zirvesinde kalacak ve harika bir MSDN kaynakları koleksiyonu sağlayacaktır.
iOS'ta Geçerli Konumu Gösterme
Geçerli konum gibi mobil cihaz kaynaklarına erişim, kullanıcıların bu kaynakları kullanması için uygulamanıza "manuel" izinler vermesini gerektirir. iOS, bu ayarları saklamak için info.plist
dosyasını kullanır. Mac için VS, bu dosyayı düzenlemek için görsel bir arayüz sağlar. Yapmamız gereken ilk şey, NSLocationWhenInUseUsageDescription
adlı ayar için bir değer eklemek.
Not: Özellik adını ayarladığınızda VS, “NSLocationWhenInUseUsageDescription” için uzun bir ad gösterecektir. Bu bekleniyor ve bunun için endişelenmeyin.
Önyükleme uygulamamız, tıklamaları sayan basit bir düğme ile oluşturuldu. Yapmak isteyeceğiniz ilk şey, onu kaldırmak ve ekran içeriğini bir harita ile değiştirmek. Bunu yapmak için, çözüm tarayıcısında Main.storyboard
dosyasını arayın ve editörde açmak için üzerine çift tıklayın.
Storyboard'lar Apple tarafından tanıtıldı ve Xamarin tarafından da benimsendi. Daha fazla bilgi için Apple Belgelerine veya Xamarin Belgelerine bakın.
Düğmeyi kaldırın ve sayfaya bir Harita Görünümü bileşeni ekleyin.
“mapView” bileşeninizi doğru şekilde adlandırdığınızdan emin olun.
Şimdi geriye kalan tek şey ViewController.cs
dosyanızı temizlemek ve ViewDidLoad()
yöntemini aşağıdakilerle eşleşecek şekilde değiştirmek:
using CoreLocation; public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. CLLocationManager locationManager = new CLLocationManager(); locationManager.RequestWhenInUseAuthorization(); mapView.ShowsUserLocation = true; }
VS'nin CoreLocation kitaplığına otomatik olarak bir referans eklemesini sağlamak için “Hızlı düzeltme” özelliğini kullanabilir veya manuel olarak ekleyebilirsiniz.
iOS uygulamanızı çalıştırdıktan sonra, konumunuza erişme isteğini görmelisiniz. İzin verildiğinde, haritanız nerede olduğunuzu (veya iOS simülatörünü kullanarak neredeymiş gibi davrandığınızı :) gösteren standart bir mavi nokta ile yüklenir.
Android'de Geçerli Konumu Gösterme
Ne yazık ki Google ve Microsoft, bu basit görevi iOS'ta olduğundan biraz daha karmaşık hale getirmeye karar verdi. Haritaları Android uygulamasında kullanmak için Google Haritalar API anahtarı oluşturmanız ve bunu AndroidManifest.xml
dosyanıza eklemeniz gerekecektir.
Xamarin çalışanları, bir Google Haritalar API anahtarı almak için oldukça basit bir kılavuz oluşturdu. Devam etmeden önce lütfen kılavuzlarındaki adımları izleyin. İşiniz bittiğinde, AndroidManifest.xml
aşağıdaki gibi bir ayar içermelidir:
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR KEY" />
Artık uygulamanıza bir harita eklemeye hazırsınız.
VS for Mac'in en güzel yanı, tıpkı ağabeyi gibi NuGet tarafından desteklenmesidir. Harita işleme kitaplıkları varsayılan olarak dahil edilmediğinden, Xamarin.Forms.Maps
paketini yüklemeniz gerekir.
Ancak, "Etkinliğiniz"e sürükleyebileceğiniz bir "Harita Görünümü" bileşeni yoktur. Bunun yerine ekrana bir harita eklemek, Kaynaklar->düzen->Main.axml dosyanızı manuel olarak değiştirmenizi gerektirir. Daha önce oluşturulan düğmeyi silmek için tasarımcı görünümünü kullanabilir, ancak ardından “Kod Görünümü”ne geçebilir ve LinearLayout
aşağıdaki parça kodunu ekleyebilirsiniz:
<fragment xmlns:andro android: android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" />
iOS'ta olduğu gibi, uygulamanızı uygun izinleri isteyecek şekilde yapılandırmanız gerekecektir. Bunu yapmak için, düzenlemek için AndroidManifest.xml
açın ve düzenleyicinin sol alt tarafındaki “Uygulama” düğmesine tıklayın. VS, bu değerleri ayarlamak için size görsel bir arayüz gösterecektir. Aşağıda gösterildiği gibi etkinleştirmeniz gereken birkaç tane var.

Artık gerçek bir kod yazmanın zamanı geldi. MainActivity.cs
dosyasını bulun, düzenlemek için açın ve aşağıdaki değişiklikleri yapın:
Ad alanı referansları ekleyin:
using Android.Gms.Maps.Model; using Android.Gms.Maps; using Android.Locations; Make your MainActivity also a ILocationListener. public class MainActivity : Activity, ILocationListener Implement the ILocationListener methods within your MainActivity: public void OnProviderEnabled(string provider) {} public void OnProviderDisabled(string provider) {} public void OnStatusChanged(string provider, Availability status, Bundle extras) {} public void OnLocationChanged(Android.Locations.Location location) { LatLng latLng = new LatLng(location.Latitude, location.Longitude); CameraPosition.Builder builder = CameraPosition.InvokeBuilder(); builder.Target(latLng); builder.Zoom(15); builder.Bearing(155); builder.Tilt(10); CameraPosition cameraPosition = builder.Build(); CameraUpdate cameraUpdate = CameraUpdateFactory.NewCameraPosition(cameraPosition); MapFragment mapFrag = (MapFragment)FragmentManager.FindFragmentById(Resource.Id.map); GoogleMap map = mapFrag.Map; if (map != null) { map.MoveCamera(cameraUpdate); } }
Aşağıdaki iki değişkeni sınıf düzeyinde değişkenler olarak ekleyin:
LocationManager locMgr; string locationProvider;
Ve OnCreate()
yöntemini şöyle görünecek şekilde temizleyin:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); locMgr = GetSystemService(LocationService) as LocationManager; Criteria locationCriteria = new Criteria(); locationCriteria.Accuracy = Accuracy.Coarse; locationCriteria.PowerRequirement = Power.Medium; locationProvider = locMgr.GetBestProvider(locationCriteria, true); locMgr.RequestLocationUpdates(locationProvider, 2000, 1, this); }
OnCreate()
yöntemi içinden GetSystemService'i çağırarak, MainActivity
bir ILocationListener
olarak etkinleştirilecek ve böylece yukarıda listelenen tüm olayları işleyebilecektir.
Android uygulamanızı çalıştırın ve aşağıdaki görüntüye benzer şekilde haritayı bulunduğunuz yere konumlandırmalısınız.
iOS ve Android için Paylaşılan Kitaplıkları Kullanma
VS for Mac'in en büyük özelliklerinden biri, iOS ve Android uygulamaları arasında paylaşılan koda sahip olma olasılığıdır. İdeal olarak, herhangi bir iOS ve Android'e özel kodu kullanıcı arayüzünün bir parçası olmakla sınırlayarak, uygulamanın tüm iş mantığına paylaşılan bir kitaplıkta sahip olabiliriz.
Eşzamansız olarak bir HTTP isteği gerçekleştirecek ve içeriği bir Hata Ayıklama konsolunda gösterecek paylaşılan bir Sınıf oluşturalım.
Aşağıdaki kodla RestClient.cs
adlı paylaşılan kitaplığınızda yeni bir sınıf dosyası oluşturun:
(Projenizden doğru ad alanını kullandığınızdan emin olun)
using System; using System.Net; namespace testshared { public delegate void callback(string responseText); class ReqState { public ReqState(HttpWebRequest req, callback cb) { request = req; callback = cb; } public HttpWebRequest request { get; set; } public callback callback; } public class RestClient { public RestClient() {} public void FetchPage(string url, callback cb) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.BeginGetResponse(new AsyncCallback(FinishWebRequest), new ReqState(request, cb)); } private void FinishWebRequest(IAsyncResult result) { ReqState reqState = (result.AsyncState as ReqState); HttpWebResponse response = reqState.request.EndGetResponse(result) as HttpWebResponse; using (var reader = new System.IO.StreamReader(response.GetResponseStream())) { string responseText = reader.ReadToEnd(); reqState.callback(responseText); } } } }
iOS'ta Kitaplığı Kullanma
iOS projesindeki ViewController.cs
dosyanızı aşağıdaki kodla eşleşecek şekilde değiştirin:
(Projenizden doğru ad alanını kullandığınızdan emin olun)
using System; using UIKit; using System.Diagnostics; namespace testshared.iOS { public partial class ViewController : UIViewController { RestClient rest = new RestClient(); public ViewController(IntPtr handle) : base(handle) {} public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. Button.AccessibilityIdentifier = "myButton"; Button.TouchUpInside += delegate { Button.SetTitle("Loading...", UIControlState.Normal); rest.FetchPage("http://www.google.com", doneCallback); }; } public void doneCallback(string content) { InvokeOnMainThread(() => { Debug.Write(content); Button.SetTitle("All Done", UIControlState.Normal); }); } public override void DidReceiveMemoryWarning() { base.DidReceiveMemoryWarning(); // Release any cached data, images, etc that aren't in use. } } }
iOS uygulamanızı çalıştırın, düğmeye tıklayın ve Visual Studio'da "Uygulama Çıktısı" sekmesini kontrol edin. Bunun gibi bir şey göstermelidir:
Android'de Kitaplığı Kullanma
Bir Android uygulamasında yapılması gereken değişiklikler, iOS'ta yapılması gerekenlere çok benzer. MainActivity.cs
dosyasını aşağıdakilerle eşleşecek şekilde değiştirin:
(Projenizden doğru ad alanını kullandığınızdan emin olun)
using Android.App; using Android.Widget; using Android.OS; namespace testshared.Droid { [Activity(Label = "testshared", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : Activity { RestClient rest = new RestClient(); protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); // Get our button from the layout resource, // and attach an event to it Button button = FindViewById<Button>(Resource.Id.myButton); button.Click += delegate { button.Text = $"Loading..."; rest.FetchPage("http://www.google.com", doneCallback); }; } public void doneCallback(string content) { RunOnUiThread(() => { Button button = FindViewById<Button>(Resource.Id.myButton); button.Text = "All done"; System.Diagnostics.Debug.WriteLine(content); }); } } }
Not: Her iki platformun da sistem mimarisi, Android ve iOS, tüm UI etkileşiminin ana uygulama dizisinde gerçekleşmesini gerektirir. Bu, UI öğelerinde yapılacak herhangi bir değişikliğin ana iş parçacığı içinden de gerçekleşmesi gerektiği anlamına gelir. İşte RunOnUiThread
ve InvokeOnMainThread
burada devreye giriyor. HTTP istekleri ayrı bir iş parçacığında yürütüldüğünden ve ana iş parçacığının dışında doneCallback()
çağrıldığından, düğmelere erişebilmek ve etiketi değiştirebilmek için bu yöntemleri kullanmamız gerekiyordu.
C# Geliştiricileri Android ve iOS'u Devralacak
Mac için Visual Studio'nun hâlâ çözülmesi gereken birkaç kırışıklığı var, ancak ilk bakışta geleceği konusunda çok heyecanlıyım. Mobil uygulamalara duyulan ihtiyaç her geçen gün artıyor ve Microsoft, Visual Studio for Mac ile bu ihtiyacı karşılamak için büyük bir C# geliştiricileri ordusunu daha da etkinleştirdi.