iPhone Kursu: Plist’lerle tablo oluşturmak-Bölüm1
İki haftadır iPhone kursumuzla ilgili yazı yazamadık. Bunun en büyük nedeni kurs dışındaki işlerimizin aşırı yoğun olmasıydı. Kursdaki konular da giderek daha karmaşık hale geldiği için malesef yazacak vakit bulamadım. Bir ara screen-recording ile video şeklinde hazırlayayım dedim ama sessiz bir ortamda boşluğa konuşmayı beceremedim. Bir kaç popüler video blog inceledim, ama bana göre değilmiş. Hasılı, klasik usüle devam.
Bugün sanırım 10. dersi gördük. Sayısı mühim değil, mevzusu mühim. Artık dışardan data alabileceğimiz konulara geldik. Hocamız önce plist denen dosyalardan nasıl veri okuyabileceğimizi anlattılar. Kısa fakat çok yararlı bir konu olduğundan blogda paylaşmak istedim.
Plist dosyaları, anahtar=>değer (key=>val) formatında veri içeren basit xml dosyalarıdır. Aslında bütün iPhone/iPad uygulamalarında zaten bir tane plist dosyası (uygulama_adi.plist) bulunmaktadır ve uygulamanın icon dosyaları, uygulamanın görünecek adı, ana nib dosyasının ne olduğu gibi bazı ayarlar bu dosyada tutulur.
Biz de istediğimiz kadar plist dosyası oluşturup projemizin resource kısmına koyabilir ve uygulamamızda bu dosyalardan faydalanabiliriz.
Basit bir örnekle konunun detaylarına girelim: Amacımız yine yemek tarifleri uygulaması yazmak olsun. Ama bu kez datamızı kodun içerisine değil bu plist dosyalara yazalım. İnşallah ileriki konularda da veritabanına yazarız. Uygulamamız “navigation based” bir uygulama olsun ve ilk açıldığında listede yemek kategorileri olsun, tıklandığında ikinci listede de o kategorilerdeki yemekler görünsün. Sonraki aşamaların mantığını zaten daha önceki yazılarda uzun anlatmıştık. O kısımlara hiç girmeyelim. Sadece birbiri ardınca iki listeyi plistlerle doldurmayı görelim.
Xcode’u açalım ve işimiz kolay olsun diye Navigation Based tipinde uygulamamızı oluşturalım. Projemizin adı LezizYemekler olsun. İlk işimiz yukarıda bahsettiğimiz plistleri oluşturmak. Bunun için resources klasörüne sağ tıklayıp Add->New File -> Resource (sol alt kısımda) -> Property List seçelim ve dosya adı olarak kategoriler.plist yazalım (Resim1). Aynı işlemi tekrar yapıp yeniden bir plist dosyası oluşturalım ve adına yemekler.plist yazalım.
Şimdi Xcode’umuzda Resources klasörü altında kategoriler.plist ve yemekler.plist diye iki boş plist dosyamız oluştu. Bunlardan ilkine çift tıklayarak plist editörünü açalım. Burda Key sütunundaki “Root” yazan satıra sağ tıklayınca gelen menüden “Add Row” deyince yeni bir satır oluşturabilirsiniz (Resim2). Key sütununa oge1, oge2, oge3 girip karşılıklarına da sırayla “Etli Yemekler”, “Zeyntinyağlı Yemekler” ve “Tatlılar” diye üç değer girip dosyayı kaydettim. Plist dosyalar (string) key=> (string) val tipinde değerlerin dışında (string) key=>(array) val, (string) key=>(date) val gibi değerler de tutabiliyor (Resim3). Fakat string tipinde tutulan plistlerin kullanışını anladıkdan sonra gerisini öğrenmek kolay diye düşünüyorum.
Yemekler.plist dosyasına karışmadan önce uygulamamızın ilk ayağını yapalım. Yani bu kategoriler.plist dosyasındaki içeriğe göre “navigation based” tipinde oluşturduğumuz uygulamamızın anaekranındaki tabloyu dolduralım.
Öncelikle RootViewController.h dosyamızı açıp NSDictionary *kategoriler; ifadesi ile NSDictionary tipinde bir değişken oluşturalım. Property’sini ve RootViewController.m dosyasında @synthesize ifadesini belirtelim.
Daha önceki yazılarda belirtmemiş olabiliriz, NSDictionary key=>val şeklinde değerler tutabilen bir çeşit dizidir. Normal diziden farkı indis olarak 0,1,2 değil de “eleman1″,”eleman2″,”eleman3″,”kitap”,”ad”,”soyad” vs. gibi string ifadeleri kullanabiliyor olmasıdır. Yeri gelmişken söyleyelim; normal bir dizinin herhangi bir elemanına erişmek için [arrDizi objectAtIndex: i] gibi bir ifade kullanıyorduk, örneğin i=2 ise arrDizi dizisinin üçüncü elemanını (0,1,2 diye gittiğinden üçüncü eleman oluyor) getir demiş oluyorduk. NSDictionary tipindeki bir diziden herhangi bir elemanı çekmek istiyorsak o elemanın key’ini aynen oraya koyabilmemiz gerekiyor. Bunun için dizilerin objectForKey methodu kullanılır. Örnek: [dicDizi objectForKey:@”ad”];
Devam edelim; RootViewController.h dosyamızda NSDictionary tipinde kategoriler isimli bir değişken oluşturduk. RootViewController.m dosyasında bunu synthesize ettik. Şimdi ViewDidLoad fonksiyonunu yorum satırlarından kurtarıp içerisine şu kodu yazalım ve sonra kodun ne olduğuna satır satır değinelim.
NSString *path=[[NSBundle mainBundle] pathForResource:@”kategoriler” ofType:@”plist”];
//plist dosyamızın yolu, Resources klasörüne attigimiz herhangi bir dosya için bu şekilde yol tanımı yapabiliriz.kategoriler=[[NSDictionary alloc] initWithContentsOfFile:path];
//RootViewController.h dosyasında tanımını yaptığımız kategoriler dizisini alloc deyimi ile bellekte oluşturuyoruz
//ve initWithContentsOfFile fonksiyonu ile yukarıda yolunu tanımladığımız dosyayı bu diziye aktarıyoruz.NSLog(@”plist: %@”,kategoriler);
//dizi gerçekten plist dosyasından çekilip oluşturuldu mu diye hemen bakmak isterseniz Xcode’un Run menüsündeki Console’yi çalıştırarak çıktıyı kontrol edebilirsiniz (Resim4).
Aslında yorum satırları gayet açık bir şekilde kodun ne yaptığını anlatıyor. Plist dosyamız key=>value tipinde veriler içerdiği için ordaki dataları karşılayabilecek olan bir diziyi NSDictionary tipinde yapmak zorundayız. NSDictionary tipindeki kategoriler dizimizi içerisini kategoriler.plist’deki datayla doldurur doldurmaz test etmek isterseniz Xcode’un Console’sinden yararlanabiliriz.
Datamızı çektik, sıra bunu anaekrandaki table’a yansıtmak kaldı. Bunun için RootViewController.m dosyasındaki table ile ilgili üç mühim fonksiyonu güncellemeliyiz (Table’ın şimdiye kadar 5 önemli fonksiyonunu gördük. Bunlardan ilk üçü hep beraber kullanılırlar, biri tablonun kaç grupdan oluşacağını, diğer grupların kaç elemandan oluşacağını döndürür., Üçüncüsü ise her hücre yüklenirken ne olup biteceğini (hücrelerde ne yazacağını) ifade eder ve hücre döndürür.
Table’in ilk fonksiyonun tablodaki grup sayısını döndürmesi beklendiği için o fonksiyona basitçe “return 1”; diyebiliriz. Table’in ikinci fonksiyonu olan grupdaki eleman sayısını döndüren fonksiyona ise, dizilerle tabloları beraber gördüğümüz yazıdan anlıştığımız üzere “return [kategoriler count]” ifadesini kullanarak kategoriler dizisinin eleman sayısını döndürmüş oluruz.
Table’in üçüncü ve en önemli fonksiyonuna “return cell”den önce ise şu ifadeyi koyuyoruz.
NSArray *keys=[kategoriler allKeys]; //kategoriler dizisinin keylerini keys dizisinde tut
cell.textLabel.text=[kategoriler objectForKey:[keys objectAtIndex:indexPath.row]]; //keys dizisinin i.ci //değerini kategoriler dizisine indis olarak ver
//ve ilgili elemanı çekip hücrenin yazısı olarak setle
Yazının ilk kısımlarında NSDictionary’den bahsederken indislerin “ad”, “soyad” gibi string ifadeler olduğunu yazmıştık. Tablo oluştururken her satıra dizimizin bir elemanı gelsin isiyoruz fakat dizimiz eskiden yaptığımız gibi 0,1,2 diye ilerlemiyor. Onun yerine elimizde “oge1”, “oge2”, “oge3” gibi strin ifadeler var. Bu indisleri hücre sayısını veren indexPath.row değeri ile ilişkilendirmek için minik bir takla atacağız.
NSArray *keys=[kategoriler allKeys];
Bu ifade ile keys diye klasik bir dizi oluşturup allKeys fonksiyonu ile kategoriler dizisinin “keylerini” bu keys dizisine çekiyoruz. keys dizisinin içeriği artık şu şekilde olmuştur:
0. eleman “oge1”, 1. eleman “oge2”, 2.eleman “oge3”
Bizim indexPath.row değeri de 0,1,2 diye ilerlediğinden artık kategoriler dizimizle elemanları eşleştirebiliriz. Bunun için yazmamız gerek ifade şu şekildedir:
cell.textLabel.text=[kategoriler objectForKey:[keys objectAtIndex:indexPath.row]];
Sondan başa doğru irdeleyelim; [keys objectAtIndex:indexPath.row] ifadesi klasik olarak bildiğimiz dizinin falanca numaralı indisinde oturan veriyi getir demektir. i=0 için bu ifade “oge1” dondurecek, i=2 için ise “oge3″ döndürecektir.
[kategoriler objectForKey:[keys objectAtIndex:indexPath.row]] ifadesinde ikinci kısıma @”oge1″, @”oge2” şeklinde string değerler oturacağından geriye kalan ifade yine klasik olarak kategoriler dizisinden “oge1” indisli veriyi getir demektir. Burdan gelen veriyi cell.textLabel.text değerine setleyip kodumuzu çalıştırabiliriz. Resim 5‘de ilk ekranımızın gayet güzel çalıştığını görmek mümkün.
Şimdi senaryomuz gereği bu satırlardan herhangi birine tıkladığımızda yeni bir table çağırıp o kategori altındaki yemekleri göstermek istiyoruz. Yazının başında değindiğimiz üzere Plist dosyalarında array veri de tutabiliriz. Örneğimizin daha gelişmiş olması için yemeklerin tutulduğu plist dosyasını bu şekilde hazırlayalım. Fakat bunu yeni yazımızda yapalım inşallah. Şimdilik bu kadar.
Cok iyi gidiyor. Bence sonunda bu notlardan iyi bir kitap cikabilir. Tekrar tesekkurler.
kaynak kod nerede acaba ?
teşekkürler….
Merhaba bu yazının devamını sabırsızlıkla bekliyoruz
Tekrardan teşekkürler …
Merhaba ,
iletişim mail adresinizi göremediğim için buradan yazıyorum.
iphone uygulama geliştirme eğitimini hangi kurumdan aldınz,süre ve fiyat olarak bilgi verebilirmisiniz ve memnun kaldınız mı?
iyi çalışmalar.
Merhaba,
Gelişim Platformu’nun düzenlediği 60 saatlik bir eğitim vardı. Fiyatı 920 TL idi. Kevser Temiz Hocamız eğitim verdi. Mevzu ile alakalı blogda baya bilgi var aslında. Kurs yeniden düzenlenecek bu yakınlarda, talep toplanıyor. Gelişim Platformu ile irtibata geçebilirsiniz.
merhaba,
öncelikle yazılarınızın devamını bekliyorum.
neden bilmiyorum ama plistlerdeki verileri göstermiyor. herhangi bir hata da yok yazdığım kodda. acaba kaynak koduda yazıya ekleyebilirmisiniz?
merhaba, yazilar biraz eskidi. firsat bulursak buradaki tum ornekleri kaynak kodlar seklinde yayinlamaya calisacagiz.