Son günlerde birçok blog, forum, haber ve benzeri amaçlar
üzerine kurulmuş internet siteleri ya da portalları üzerinde RSS yayını adı
altında bir servis standart internet ziyaretçilerine hizmet vermektedir.
ikonu
bulunan sitelerde kullanıcılar diledikleri taktirde bu RSS kaynaklarını RSS
destekli uygulamalar üzerine kayıt ettirebilmekte ; site üzerinden herhangi bir
noktada gerçekleştirilen bir güncelleme ile ilgili bu RSS kaynağından ;
dolayısıyla RSS işleyen uygulamalar üzerinden haberdar edilmektedirler. Peki
nedir bu kadar meşhur olan bu RSS ? O’ nu bu kadar kullanılması cazip kılan
kavramlar nelerdir ? Bu noktada biraz bu soruların cevaplarını arayalım.
Öncelikle şunu belirtmek gerekirki RSS, belli bir zaman
süreci içerisinde isim açılımı bakımından belli bir değişime uğramıştır. İlk
standartatize versiyonundan itibaren RSS internet üzerinde ;
- Rich Site Summary (RSS 0.91)
- RDF Site Summary (RSS 0.9 and
1.0)
- Really Simple Syndication (RSS
2.0.0)
şeklinde ifade edilebilecek
farklı akronimler üzerinden tanımlanmaktadır.
RSS, temel amacı bakımından, “bu
kaynağı sunan internet sitelerinin bu kaynak üzerinden sunulan içeriklerini
daha rahat takip edebilmek için oluşturulmuş standartize bir XML dökümanı &
XML Formatı” olarak ifade edilebilmektedir.
RSS kaynağı üzerinden
içeriklerini dağıtan internet siteleri dünya üzerinde geliştirilmiş olan
neredeyse tüm RSS okuyucuları için standartize edilmiş bazı temel kuralları
uygulamış olmaları gerekmektedir.
Bu temel kuralların başında RSS
kaynağı üzerinden yayını yapılan XML dökümanının bazı temel element isimlerine
sahip olmaları gerekmektedir. Bu temel element isimleri üzerinden RSS
kaynağınızı dünya üzerindeki neredeyse birçok RSS okuyucusu destek verebilir ;
ziyaretçiler bu uygulamaları üzerinden siteniz üzerinden yayını yapılan RSS
kaynaklarına erişebilirler.
Peki nedir bu temel kurallar diye
sorarak makalemizin teorik kısmına bu noktada devam edelim. Bir önceki
paragrafta doğru bir RSS dökümanı içerisinde mutlak surette olması gereken bazı
elementlerden bahsetmiştik. Bu elementler dünya üzerinde birçok RSS kaynağı
tarafından kabul edilmiş ; birçok uygulama tarafından da tanınmaktadır. Bu
temel element isimlerini kısaca açıklamak gerekirse ;
Bir RSS dökümanı içerisinde
bulunması muhtemel XML Tag isimlerini ifade edebilmek açısından örnek bir RSS
çıktısı görüntülemek daha doğru olacaktır. Ekran görüntüsü makalemizde de
kullanacak olduğumuz Hürriyet Gazetesi RSS Kaynağı içerisindeki bir haberin RSS
çıktısıdır.

Şekilden de anlaşılabileceği
üzere, üzerinde çalışacak olduğumuz RSS kaynağının adresi, logosu ve
açıklamasıyla ilgili XML Tag’ lerinin altında standartize ve tekrar ederek
giden bir Tag betiği bulunmaktadır.
Her bir haber
<item></item> tag’ leri ile ifade edilirken her
<item></item> tag’ leri arasında bilginin başlığı, varsa
açıklaması, kaynak adresi ve yayınlanma tarihi bulunmaktadır.
Bu noktada belirtilmiş olması
gereken en önemli nokta ise bu sayılan tag’ lerin birçok RSS kaynağında
standart bir şekilde bulunacağı ; spesifik durumlarda yeni tag’ lerinde
eklenebileceği olduğudur.
Evet, RSS ile ilgili temel
seviyede bilgi sahibi olduktan sonra yavaş yavaş makalemizin asıl konusuna
doğru geçiş yapalım. Amacımız dünya üzerindeki standart bir RSS okuyucusunun
yaptığı gibi yukarıda örneği ifade edilen bir RSS kaynağını standartların
dışında çok farklı bir ortamdan ; “Mobil Cihazlar” üzerinden okuyup kullanıcıya
gün içerisinde yolda ya da bulunduğu herhangi bir lokasyonda haberleri takip
etmesini sağlayacak bir Mobil RSS Okuyucusu geliştireceğiz.
Bu makale süresince .Net Compact
Framework 2.0 üzerinde birçok farklı kavram üzerinde bilgi sahibi olup böyle
bir uygulama içerisinde uygulayarak tecrübe sahibi olacağız.
Hiç vakit kaybetmeden uygulama
senaryomuz üzerinde bilgi sahibi olalım.
Amacımız Mobil Cihaz kullanıcılarının
diledikleri her noktada Hürriyet Gazetesinin RSS Kaynağı üzerinden farklı
kategoriler üzerinden sunulan haber başlıklarına ulaşabilmeleri için bir RSS
Okuyucusu oluşturmak olacaktır. Bu noktada uygulama tasarımı bakımından
birtakım problemlere karşın bazı önlemler almamız gerekmektedir.
Üzerinde çalışacak olduğumuz
kavram internet erişiminin o anki performansı ile doğru orantılı olarak
çalışacağından uygulamayu kullanacak olan kullanıcılar RSS Servisine istekte
bulunduğunda sonuç gelene kadar beklememesi gerekmektedir. Bu noktada işin
içerisine Asenkron Mimari girmektedir. Uygulamamız içerisinde uzak noktaya
yapacak olduğumuz çağrıların tümü “Asenkron Mimari” üzerinden
geliştirilecektir. Böylece tek bir makale üzerinden Xml, Threading ve RSS
kavramlarını öğrenmiş olacağız.
Hiç vakit kaybetmeden makalemizin
konusunu oluşturan uygulamamızı geliştirmeye başlayabiliriz. Bu noktada
uygulamamız Windows Mobile 5.0 işletim sistemi ile çalışan Pocket PC cihazları
için geliştirilecektir. Bunun için sistemimize Mobile 5.0 SDK’ nın yüklü
olduğunu varsayarak bir C# Smart Device Mobile 5.0 Projesi açıyoruz.

Bir sonraki adımda ise yavaş
yavaş uygulama ekranımızı tasarlamaya başlayabiliriz. Bu noktada uygulama
içerisinde gerçekleştirmek istediğimiz senaryoda kullanıcı Hürriyet Gazetesinin
RSS Kaynaklarıyla ile ilgili kategorileri bir ComboBox içerisinden seçip ; bir
sonraki adımda ComboBox’ ın altında bulunan ListView kontrolü içerisinde kolon
bazlı bir yapı üzerinden seçilen kategorideki haberleri görüntüleyecektir. İşin
programatik kısmına geçmeden önce bu noktada Hürriyet Gazetesinin RSS Kaynağı
ile ilgili adreslerden bahsetmek daha doğru olacaktır.
Hürriyet Gazetesi RSS Kaynağı
olarak farklı adresler üzerinden farklı kategorilerde kaynaklar sunmaktadır.
http://dosyalar.hurriyet.com.tr/rss/
adresinde ifade edildiği üzere Hürriyet Gazetesi RSS Servisi şekildeki adresler
ve katerogiler üzerinden kullanıcılara RSS Kaynağı sunmaktadır.

Amacımız bu noktada kullanıcıya
ComboBox içerisinden şekilde sol tarafta sıralanmış olan kategorileri
seçtirtmek ; bir sonraki adımda ise sağ tarafta bulunan adresler üzerinden RSS
kaynağını almak olacaktır. Bu noktada şekildeki form tasarımı üzerinden
uygulamamıza devam ediyoruz :

Şekildende anlaşılabileceği üzere
form üzerine Bir ComboBox, View Özelliği “Details” olarak belirtilmiş bir
ListView ve En alta seçili haber ile ilgili detay bilgiyi gösterecek “ReadOnly”
bir metin kutusu ekledik. Bu noktada standart olarak eklenen MainMenu kontrolü
içerisine iki adet MenuItem eklemiş bulunmaktayız.
Ayrıca şunuda belirtmemiz
gerekmektedirki Details görünümünde çalıştırılacak olan ListView kontrolümüzün
içerisine RSS Kaynağı üzerinden getirilen bilgilerin Başlık Ve Tarih
bilgilerini ekran üzerinde gösterebilmemiz için iki adet kolon eklemiş
bulunmaktayız.

Ve sıra geldi kodların
geliştirilmesine. Bu noktada dikkatli olmamiz ; tasarimsal olarak herhangi bir
hataya maruz kalmamamız gerekmektedir.
Senaryoya baktığımızda ilk
noktadaki amacımız kullanıcıya ComboBox içerisinden RSS Kaynağı üzerinden
sunulan Haber Kategorilerini seçtirtmek olacaktır. Bu noktada gerçekleştirmemiz
gereken ilk eylem ComboBox’ ın içerisine bu kategorileri eklemek olacaktır.
Fakat ComboBox’ ın Items collection’ı içerisinde bulunan Add metoduna
baktığımızda metodun tek bir kere tanımlandığı ve bu tanımlanan versiyonunda uygulama
geliştiriciden “object” tipinde bir parametre beklediğini görmekteyiz.

Tasarımsal olarak bu noktadaki
amacımız, kullanıcının “AnaSayfa”, “Gündem” şeklinde anlaşılır kategori
isimlerini görmesini isterken, arka tarafta seçili kategorinin RSS Adresine
istekte bulunmak olacaktır. Olaya bu açıdan baktığımızda içerisinde iki adet
bilgiyi depolayabilen ; Adres Ve İsim bilgisini depolayabilen bir sınıf tipine
ihtiyaç duymaktayız.
Bu problemin çözülebilmesi için
.Net Compact Framework üzerinde Key – Value mantığıyla çalışan birçok tip
bulunmasına rağmen kendi özelleştirilmiş tipimizi oluşturmak tasarımsal oalrak
daha doğru olacaktır.
Şekildeki sınıfı oluşturarak
uygulamamıza devam ediyoruz :

Şekildende anlaşılabileceği üzere
standart olarak bir RSS Adresini ifade edebilecek özelliklere sahip bir sınıf
oluşturmuş bulunmaktayız. Sınıfın içerisinde bir RSS’ in görsel ismi ve
adresini barındırabilecek iki adet özellik ve parametreli bir yapıcı metot
(Constructer) bulunmaktadır.
Ayrıca “object isteyen görsel görsel
objelerinde kullanabilmesi amacı ile” ToString() metodunu override edere
metottan sınıfın içerisindeki Isim_ değişkeninin değerinin dönmesini sağlamış
bulunmaktayız.
Bir sonraki adımda Form’ umuzun
Load olayı gerçekleştiğinde ComboBox içerisine Hürriyet Gazetesi RSS Kaynağı
üzerinden sunulan adresleri geliştirdiğimiz sınıfın constructer’ ı üzerinden
oluşturarak ekliyoruz.

ComboBox içerisine eklenen
objelerin otomatik olarak ToString() metodunu çalıştıracak ve ekran üzerinde
eklenen RSS Kaynağının ismini görüntüleyecektir. Fakat bizimde bildiğimiz
üzere o noktada bir string olmadığı bir RssKaynagi objesi bulunmaktadır.
Gerektiğinde objeyi bulunduğu yerden çekeren tip dönüşümüne sokarak seçili
Kategorinin adresini alacağız.
Uygulamayı herhangi bir kod daha
yazmadan bu haliyle Emülatörümüz üzerinde çalıştırdığımızda :

Listeden Pocket PC Emulator ‘ u
seçiyoruz ve uygulamamızı Deploy ediyoruz.

Ve uygulama ekranı içerisinde
kategoriler başarıyla listelenmiştir. Bu noktada kullanıcılar ComboBox
içerisinde Kategori adlarını görmelerine rağmen bu liste elemanları arka
taraflarında adres bilgilerinide barındırmaktadırlar.
Hızlı bir şekilde kaldığımız
yerden devam edelim.
Uygulama içerisindeki amacımız
uzak noktadan gelen RSS bilgilerini mobil cihazın memory’ si üzerinde depolamak
ve bu depolanan verileri uygun noktalara eklemek olacaktır. Bu amaçla RSS
kaynağı üzerinden gelen XML verilerini mobil cihazın belleği üzerinde
depolayabilmek amacı ile System.Xml namespace’ i altında bulunan XmlDocument
sınıfından yararlanacağız.
XmlDocument sınıfı, yapısı gereği
instance’ ı oluşturulduktan sonra hafıza üzerinde DOM yapısına uygun
oluşturulan XML verileri üzerinde dolaşabilmektedir. Ayrıca içerisindeki –ki makalemizde
bu metot üzerinden yapıyı çalıştıracağız- GetElementsByTagName metodu üzerinden
uygulama geliştirici metoda parametre değeri olarak gönderilen element ismine
sahip tüm XmlNode objelerini XmlNodeList tipinde geri dönüş değeri olarak
alabilmektedirler.
Bu amacı gerçekleştirmek adına
globalde bir XmlDocument referansı ; uygulama ekranı yüklendiğinde ise bu
referansın instance’ ını oluşturuyoruz.
Ayrıca metot üzerinden gelecek
olan XmlNode dizisini taşıyabilmesi için bir XmlNodeList referansını yine
global’ de tanımlıyoruz.

Bir sonraki adımda Form
yüklendiğinde XmlDocument objesini oluşturuyoruz :

Bir sonraki adımda her kategori
seçiminde çalışacak olan Thread objesinin başlatılacağı zaman gidip
çalıştıracağı ; seçili kategorinin adres bilgisini kullanarak uzak noktadan RSS
bilgilerini çekecek olan HaberleriYukle() isimli bir metot ve bu metodun
çalıştırılmasında tetikleyici rolü oynayacak olan ComboBox’ ın seçili kategori
değeri değiştiğinde çalışacak olan kod bloklarını geliştiriyoruz. Şekildeki kod
bloğu üzerinden uygulamamıza devam ediyoruz :
Öncelikle globalde Thread
sınıfının bir referansını tanımlıyoruz.

Ve bir sonraki adımda ayrıntılı
açıklanacak olan şekildeki kod bloklarını geliştiriyoruz :

Kod bloklarını ayrıntılı olarak
incelediğimizde ilk olarak ComboBox’ ın seçili indeks değeri değiştiğinde global
olarak tanımlı olan AktifRssAdresi isimli değişkene seçili olan ComboBox
objesini RssKaynagi tipine dönüştürdükten sonra Adres değerini alıp
eşitliyoruz. Bunu gerçekleştirmemizin sebebi bir sonraki adımda farklı bir
thread içerisinden farklı bir thread içerisindeki bir objenin özelliğine
erişmeye çalışırken yaşayacak olduğumuz CrossThreadOperationException’ dır.
Bunu yaşamamak adına kontrolün değerini diğer thread’ e geçmeden önce her iki
thread’ inde erişebileceği güvenli bir string değişken üzerine taşıyoruz.
Daha sonraki satırda global Thread
referansını oluşturup içerisine bizden istediği ThreadStart isimli delege
instance’ ını gönderiyoruz. Bu delege sadece parametre almayan ve void geri
dönüş değerine sahip metotları adresleyebilmektedir. Zaten HaberleriYukle
metodumuzun tanımlanma amacıda aslında bu olmaktadır. Thread’ i tanımladıktan
sonra sonra ise Thread sınıfının Start metodu üzerinden Thread’ i başlatıyoruz.
Bir sonraki adımda HaberleriYukle
isimli metodumuz oluşturulmuştur. Bu metot içerisinde Form yüklendiğinde objesi
oluşturulmuş olan XmlDocument sınıfının Load metodu içerisinden uzaktan gelen
RSS bilgilerini mobil cihazımızın memory’ si üzerinde oluşturulmasını
sağlıyoruz. Ve sıra geldi en önemli noktaya.
Şekilden de anlaşılabileceği üzer
rssDOC isimli XmlDocument objesinin GetElementsByTagName isimli metoduna
parametre değeri olarak “item” bilgisini vererek metodumuzu çalıştırıyoruz.
Metot sonucunda kullanıcıya kaynak üzerinden gelen tüm <item>
elementlerini içerisindeki diğer child element’ ler ile birlikte XmlNodeList
olarak döndürmektedirler.
Daha sonra bu XmlNodeList
referansı üzerinden içerisindeki her bir XmlNode objesi için yeni bir
ListViewItem objesi oluşturulmakta ; içerisine ikinci bir SubItem eklenmekte ve
bu SubItem’ ların Text’ lerine sırasıyla başlık ve yayınlanma tarihi bilgileri
eklenmektedir. Ayrıca ListViewItem üzerine tıklatıldığında tıklanan haberin
detayını alabilmek bakımından ListViewItem objesinin Tag özelliğine XmlNode
objesinin kendisi verilmektedir –ki gerektiği noktalarda haberin tüm
elementlerini bu özellik üzerinden gelen XmlNode objesi üzerinden alabilelim.
Son olarak enteresan bir yapı
üzerinden kod bloğunu tamamlıyoruz. Normal şartlarda listView1.Items.Add metodu
üzerinden yeni oluşturulmuş olan ListViewItem objesini Add metoduna göndermemiz
bu noktada yeterli olacaktır. Fakat bu işlemleri farklı thread üzerinde
gerçekleştirdiğimizi göz önünde bulundurur isek Main Thread üzerinde
oluşturulmuş olan listView1 kontrolüne Worker Thread üzerinden “Thread
Güvenliği” bakımından erişememekteyiz. Bu amaca uygun olarak işlemi listView1
kontrolünün ilk oluşturulmuş olduğu Thread üzerinde gerçekleştirebilmek için listView1
kontrolünün Invoke metodunu kullanmamız gerekmektedir. Bu metodun sonucunda
işlem listView1 kontrolünün ilk olarak oluşturulduğu thread üzerinde
gerçekleştirilecektir.
Invoke metodunun yapısına
baktığımızda ise hangi metodun Invoke edileceği ile ilgili Invoke edilecek olan
metodun adresini üzerinde barındıran bir delege objesi bizden istemektedir.
Amacımız listView1 kontrolünün Add metodunu kullanmak ise Add metoduna uygun
parametre ve geri dönüş değerine sahip bir delege tanımlamamız ve instance’ ını
oluşturup bunu parametre değeri olarak Invoke metoduna göndermemiz
gerekmektedir. Bu amaca uygun olarak globalde Add metodunun parametre
kombinasyonu ve geri dönüş değerine uygun bir delege tanımlıyoruz ve hemen
altına bu delegenin global referansınız tanımlıyoruz. Global değişkenlerin son
durumu şekildeki gibidir :

Bu delegenin objesini form
yüklendiğinde oluşturuyoruz ve adres olarak listView1 kontrolünün Add metodunu
veriyoruz.

Son olarak ise listView1.Invoke
metodu üzerinden ilk parametresine delegemizin kopyasını, ikinci parametresine
ise li isimli ListViewItem objesini göndererek ekleme işlemini Main Thread
üzerinde gerçekleştiriyoruz.
Bir sonraki ve son adımda ise
listView1 kontrolü üzerinde seçili haber bilgisi değiştiğinde Tag özelliği
üzerinden XmlNode objesini çektik ve “description” element’ inin değerini
TextBox içerisinde görüntüledik. Diper kısımları standart MessageBox.Show kod
satırları olarak ifade edilebilir.

MessageBox ile ilgili kısımlar :

Ve sıra geldi makalemizin en
heyecanlı kısmına. Uygulamamızı hiç vakit kaybetmeden mobil cihaz emülatörü
üzerinde çalıştırıyoruz. Bu noktada Mobil Cihaz Emülatörümüzün internet
ayarlarının yapılı olduğunu varsayıyoruz.

Sonuç Mükemmel ! Farklı
kategorileri seçtikte haberleri kaynak üzerinden Mobil Cihazımıza
yüklenecektir. Ayrıca haberlerin üzerinde gezindiğimiz sürece Metin Kutusunun
içerisinde haber detayı gösterilmektedir.
Bu makalemizde Asenkron Bir Mobil
RSS Okuyucusu geliştirdik. Başka bir makalede daha görüşmek üzere.