Author Archives: Ali Hıdımoğlu

Cocoapods’da Podfile Güncellenmeme Durumu

iOS Development yapıyorsanız muhtemelen siz de Cocoapods1 kullanmışsınızdır. Bu aracı kısaca anlatmak gerekirse; birden fazla mock-up ya da framework’ü GitHub üzerinden XCode projenize enregre edebiliyorsunuz. Bunu sadece bir tane Podfile adı verilen bir dosyaya ilgili framework’ün ismini ve varsa versiyonunu yazdıktan sonra terminal üzerinden bir command çalıştırarak yapabiliyorsunuz. Her şey çok basit gözüküyor ama benim gibi cocoapods’u uzun süreden sonra tekrar kullanmak isteyince sistem yanıt vermezse ne yapacağınızı şaşırıyorsanız işte orada sıkıntı var demektir.

Hata: “# Pod install” komutunu yazıyoruz ama tepki alamıyoruz.

İşte bu büyük bir hata. Komutu yazıyorsunuz ama arada 15dk geçse de ne sistem güncelleniyor ne de “Analysing dependencies” yazısı gidiyor.

Çözüm:

1- Cocoapods’un tekrar yüklenmesi gerekli
Bunun için $ pod setup yazmanızın yeterli olması gerek. Yazarken de sonuna --verbose eklersek en azından ne işlem yaptığını görebiliriz. Bendeki durumda dikkatimi çeken şey eski sürüm cocoapods yüklü olması (0.37.1) durumuydu.

Updating spec repo master

$ /usr/bin/git pull –ff-only

uyarısından sonra ekranın ilerlememesi durumu yani.

2- Cocoapods’un güncellenmesi
Bunun için önce eski dosyaları bir kaldırıyoruz $ rm -rf ~/.cocoapods; pod setup komutu bizim için eski dosyaları kaldıracak ve yeni dosyaları yükleme için indirmemizi sağlayacak.

Kurulum için $ gem install cocoapods komutunu kullanıyoruz ama o da ne, bize bir uyarı geliyor (uyarı gelmiyorsa zaten yürüyün gidin, setup kodu yazarsanız iş biter) uyarı geliyorsa, devam edelim.

Fetching: cocoapods-core-0.38.2.gem (100%)

ERROR: While executing gem … (Gem::FilePermissionError)

You don’t have write permissions for the /Library/Ruby/Gems/2.0.0 directory.

Bu uyarıyı alıyorsanız bilin ki Mac bilgisayarda yüklü olan Ruby sürümünüz güncel değil ve cocoapods ise yeni güncel Ruby’i istiyor. Ama user hakkınız olmadığı için bunu yapamıyorsunuz. Pek tavsiye edilmeyen ama istinasız herkesin kullandığı bir komuta başvuruyoruz burada: sudo

Bu bir best practice değildir!! uyarısını verdikten sonra geçici admin hakkı veren yeni komutumuzla deneme yapıyoruz: $ sudo gem install cocoapods

İşte istediğimiz güncelleme oluyor.

3- Pods’un yüklenmesi
Bu işlemden sonra yapacak bir şey yok. Projemizin folder’ına gidip usulca $ pod install yazıyoruz ve bize tane tane yüklemelerimizi yapıyor.

Bu sorunu yaşadığınızda farklı bir yöntemle mi çözdünüz, yoksa benim gibi sudo tarzı komutları kullanmak zorunda kaldınız mı?


  1. https://cocoapods.org 

Azure Mobile Services Update Error (1105 – The item provided did not have a valid id)

Azure Mobile Services iOS SDK kullanıp da Native iOS yazdığınız zaman, bazı hatalarla karşılaşa biliyorsunuz. Daha önce bahsetmiş olduğum 1 kendi projelerimden bir tanesinde ben de BackEnd kısmını Azure ile çözüp FrontEnd kısmını iOS Swift ile çözmeye çalıştığımı belirtmiştim.

Yazılımı kolay ve anlaşılır olmasına ve Azure SDK’nın da yeterince donanımlı olmasıyla bir çok sorunun üstesinden gelinse de yine 3.5 saatimi alan bir hata olmadı değil. Bu hata kimi yerlerde “1105 – The item provided did not have a valid id” kimi yerlerde de “1102 – The item provided did not have a valid id” olarak betimleniyor.

Araştırdığımızda ise, hata basitçe; “Sen bana data veriyorsun ama ben ID’yi yakalayıp güncelleme yapamıyorum” diyor. Azure Mobile Service’in PUSH methodu sırasında oluşan bir hata ve sanırım client dil seçeneklerinin bunda da etkisi büyük. Hatanın bulunmaması, yabancıların bunu yaşamadığını gösteriyor en azından :).

Hata?

Azure Mobile Services iOS SDK kullanarak PUSH yapılan method içerisinde Id parametresinin bulunamaması.

Çözüm

Aslında saatlerimi alsa da, çözüm gayet basit. Elinizdeki NSDictionary (ya da farklı bir liste de olur NSMutableArray gibi) listesinde (ki bu AMS üzerinden gelen Model’de olabilir) Id alanının düzgünce tanımlanmış olması gerek. Burada dikkat edilmesi gerekilen şey ise id değil, ID değil, tam olarak Id verilmesi lazım. Liste üzerinde id olsa da ID olsa da yakalamayacaktır.

   func UpdateData(itemToInsert: NSMutableDictionary, complete: ((Bool, NSDictionary) -> Void)!) {
        var isSuccess  = false

        var tid:String? = itemToInsert.valueForKey("Id") as? String
        if tid != nil {
            let uid:NSDictionary = [ "id": tid as String!]
            itemToInsert.addEntriesFromDictionary(uid as [NSObject : AnyObject])
        }

        self.table!.update(itemToInsert as [NSObject : AnyObject],
            completion: {
                updatedItem, error in
                if (error != nil){
                    println(error)
                    isSuccess = false
                    complete(isSuccess, updatedItem);
                }
                else{
                    isSuccess = true
                    complete(isSuccess, updatedItem);
                }
            }
        )
    }

Yukarıdaki kod basitçe gelen listede Id yoksa liste içerisindeki id olarak tanımlı olan veriyi Id olarak atayıp AMS’ye gönderiyor.

Umarım siz de benim gibi bu hata yüzünden saatlerinizi harcamazsınız :).

PS: I’m planning to write this post on english too…


English Version

When you write your project with a new programming language, it’s normal to have some little problems. But sometimes, it’s hard to find an answer to your little annoying bug. “1105 – The item provided did not have a valid id” or “1102 – The item provided did not have a valid id” that kind of bug that irritates you. But its easy to solve.

Problem

Problem is when you are connecting Azure Mobile Services service’s PUSH Method with Azure Mobile Services iOS SDK via swith. It’s not gets your Id value correctly. Even if you use received Model from AMS service.

Answer

It’s ridiculously easy. Send your parameters with Id :D, but it should be named Id (not id, or ID) even it has id field you should add new Id field with same value.

    func UpdateData(itemToInsert: NSMutableDictionary, complete: ((Bool, NSDictionary) -> Void)!) {
        var isSuccess  = false

        var tid:String? = itemToInsert.valueForKey("Id") as? String
        if tid != nil {
            let uid:NSDictionary = [ "id": tid as String!]
            itemToInsert.addEntriesFromDictionary(uid as [NSObject : AnyObject])
        }

        self.table!.update(itemToInsert as [NSObject : AnyObject],
            completion: {
                updatedItem, error in
                if (error != nil){
                    println(error)
                    isSuccess = false
                    complete(isSuccess, updatedItem);
                }
                else{
                    isSuccess = true
                    complete(isSuccess, updatedItem);
                }
            }
        )
    }

It’s normal to have bugs in Azure Mobile Services iOS SDK, it has lots of pros and little cons :).

Keep up the good work!


Versiyon 2.2.0’da bu sıkıntılar düzeltilmiş durumdadır.

Azure Mobile Services Backend ve iOS Frontend

Uzun bir aradan sonra yazmak biraz zor oluyor, yine de yazmadan da olmuyor arkadaşlar. Bu sefer kısa olarak bahsedeceğim ama ileride bol bol, siz sıkılıncaya kadar anlatacağım Azure Mobile Services konusu ile bir Swift iOS Backend olayına bakacağız. Hiç öyle ahım şahım bir olay değil baştan diyeyim hiç heyecan da yapmayın.

Hazır virtual makinem kendini restart ederken size yeni projemden bahsedeyim. Bir iOS app yazmaya çalışıyorum ama nasıl yazıyorum bir anlatabilsem derdimi. Son zamanlarda merakımdan değil, gerçekten bir girişim olabileceğini düşündüğüm için böyle bir şeye atladım diyebilirim.

1- Proje Kısmısı

Proje nedir, ne değildir? Hayatı insana sorgulatan projenin kendisi midir, yoksa sizin bu konudaki eğiliminiz midir? Bir sürü soru var insanın aklında olan prjeyi ortaya çıkarmak sadece. Olası sorunlardan bir tanesini siz daha başlamadan anlatayım; “Projeye o kadar çok yoğunlaşmak ki, projenin amacını unutmak!”

Maalesef start-up ya da kendi projenizi yaparken yaşayacağınız en büyük sorun bu ve bunun da kolay bir kurtuluşu yok. Her gün kendinize Neden bu projeyi yapmayı istedim? gibi bir soru sormanız ve bunu her gün istisnasız yanıtlamanız gerek. Neyse ki kendi projemin “Amaç noktası” bana kendisini her gün tekrar tekrar hatırlatan bir şey olduğundan kendisine odaklanmam bir şekilde mümkün olabildi diyebilirim.

2- Backend Kısmısı (Back-end)

Şimdi bir fikriniz var, ok bunu anladık. Peki bunu nasıl support edeceksiniz? DB1‘niz var mı? Programınızın arayüzü sizin DB ile nasıl haberleşecek? Genel bir API2 mi çıkacaksınız, yoksa WCF3 koyarım yeter ağa mı diyeceksiniz? Hadi WCF koydunuz bunun REST4 API’ye çevrilmesi var. Onu geçtim hani sizin app Asyncronious5 olarak request gönderdiğinde WCF onu destekleyecek mi? Onu da Web API6 ile yaparım diyeceksiniz ama hadi onun da Authentication7 olayı var, Onu nasıl desteklemeyi planlıyorsunuz?

Hepsini boşverin, bu backend olayını tutup da windows bir host içerisine atıp aylık ne kadar para bayılacağınızı hesapladınız mı? Daha proje başalmadan bir de!!

Vay benim başıma kaynar sular dökülsün, daha hayal aşamasında projeyi çöpe atmaya çalışmanızın sebebi, işte böyle şeylerin hesaplanmasıdır arkadaşlar. Bir gecede Facebook, Instagram çıkmıyor tabii. Hele hele hiç scability olaylarına girmiyorum oraya girdiğimde sizinle ayrıca mesajlaşırız :D.

Kişisel olarak bu sorunları Azure Mobile Services ile (REST, Asyncronios, Authenticated) ile çözmeye çalışıyorum.

3- Frontend Kısmısı (Front-end) (iOS APP)

Hadi bir şekilde arka tarafı kotardınız, peki programınızın arayüzü nasıl olacak? Yo yo tasarım demiyorum, ön yüzün arkasındaki programlama dilinden bahsediyorum. Native yani entegre app mı olacak, yoksa bir web sayfası yapıp onu mu gömeceksiniz programın içerisine? Hadi Native oldu, Objective-C mi olacak Swift mi olacak?

Objective-C ve Swift Farkı

Programatik farkları değil başka bir farkı size anlatmak istiyorum. iOS olacak olan app’ın desteklenme arayüzü nasıl olacak? Yani Objective-C olayı yakında sonlanacak ve Apple buna destek vermemeye başlayacak, bunun için zaten geçen yıl Swift dilini ortaya çıkarttılar. Fakat internette azıcık da olsa araştırma yapınca karşınıza Swift ile bir şey çıkmamakta, ne varsa insanlar objective-c kasmış.

Swift dediğimiz dil de iOS 8’den sonra destekmeye başlanan bir dil bunu da belirtelim. Tabii her makinede iOS 8 yok (Bu yılın analizine göre %85 iOS 8 kurulu makinalarda).

Şahsi görüşüm yine burada Swift dilini kullanmak. Çünkü syntax olarak hem kolay, hem de geleceği olan bir dil.

4- Sonuç

Sonuç olarak öyle “Kanka gel de program yazalım”, “Hadi gel start-up olalım”, “Abilerle Mobile App Keyfi” gibi şeyler kolay olmuyor arkadaşlar. Bir hayaliniz olduğunda o hayali mümkün kılmak için gerekli altyapıyı da öğrenmeniz gerek. Ben bu ölçüde şanslı birisiyim ama bu konuda şanslı olmayanlar ne yapabilir? Tabii ki dünyanın sonu değil. Yazılımcı kiralama, ya da projenizi Angel Investor’lara sunma gibi bir yola gidebilirsiniz. Onlar sizin için düzgün teknik yol çizecek ya da çizecek kişileri sizin karşınıza çıkartacaktır.

Yeni bir şeyler üretmekten korkmayın, aksine üretin ve hayatınızda nadiren yaşayacağınız duyguları doay doya yaşayın.

Devamı gelecektir…


  1. Database: Hani şu dataları sakladığımız zımbırtı. 
  2. Application Programming Interface: Kısaca bizim programla esas kodların iletişim kuracağı arayüz. 
  3. Windows Communication Foundation: Çok popüler olan ve bir çok iletişim formatını destekleyen servis programlama altyapısı. 
  4. Representational State Transfer: Kısaca HTTP üzerinden çalışan servis mantığı. 
  5. Programlamada işlemler syncronious (senkronize) ve asyncronious (sırasız) olarak gönderilirler. Sıralı olaylarda önceki bitmeden sonraki işlem yapılmaz. Sırasızlarda aynı anda işlem gönderilir, en kısa sürede biten tamamlanmış olur. 
  6. Web API: Yeni çıkan REST altyapısı ile MVC teknolojisini birleştiren MS servis altyapısı. 
  7. Yetkilendirme: Öyle her şeyi kabul edip de heckırları sisteme davet mi edeceksiniz? 

Adres Değişikliği

Selam arkadaşlar,
Blog adresimi ilk açtığım günden sonra gidip domain almama rağmen oturup da adam akıllı bir aktarı gerçekleştirememiştim. Zaten kim uğraşacaktı bu kadar işle, wordpress.com zaten herşeye yetiyordu falan da yetmiyormuş sonra fark ettim olayı. Google Analytics eklemek istediğinizde sistem paralı olmanızı istiyor, font değiştirmek istiyorsunuz sizden para istiyor. Az buz da para istemiyor yani haliyle ben de bununla uğraşmak yerine direk elimde olan adresi de taşıma kararıyla blogumu yeni adresi olan (http://bosisleryazilimcisi.com)‘a taşımış bulunmaktayım.

Bundan sonra daha geniş içerikli yazılar yazacak olup, hali hazırda başladığım güzel bir Mobile App projesi ile de sizinle daha fazla detay paylaşacağım.

Falanlar filanlar hayatınızdan eksik olmasın…

“Request entity is too large.” konusu

Eğer siz de “The page was not displayed because the request entity is too large.” hatası alıyorsanız, öyle internette her bulduğunuz şeyi denemeyin bazen bulduğunuz çözüm, çözüm olmayabilir. Bu konuyu çok uzatmayacağım ki kısaca çözüme geçelim.

Olay

SSL kullandığınız projelerinizin requestlerinin boyutları IIS’in applicationhost.config ayarı ile çatışması. Bu boyutun arttırılması, dosya yüklerken ya da büyük resultlar dönerken tip tip hatalar görmeniz tamamen buna delalettir.

Çözüm

Önce C:WindowsSystem32inetsrv adresine girip applicationhost.config dosyasının bir yedeğini aldın ki diliniz yanmasın. Sonra nette bulduğunuz klasik örneği kullanarak arttırım yapmayın, önce bir bakın adamlar ne yapmış örneklerinde;

appcmd set config "https://mysite" /section:system.webserver/serverruntime /uploadreadaheadsize:1048576 /commit:apphost demişler. Bi bakalım sırayla;

  • https://mysite buraya kendi sitenizin adını yazın, bu ad nedir diyorsanız hiç sitenin urlsini yazmayın, IIS’i açıp Sites kısmındaki ismini yazın arkadaşın…
  • 1048576 hep buradan yanıyor başımız. 1048576 = 1024 * 1024 = 1mb yani adam 1mb için örnek yazmış, sen de git kopyala hemen mal gibi, yapmayın tabii böyle. Max: 2147483647 verin ki bu da 1.99GB’a denktir.

Sonuç

Yükleme kısmınız varsa bu sorunu çözüyor bir de limiti 2gb’a kadar çıkartıyorsunuz da, 2GB’dan daha fazla yükleme yapmak için ayarlar .Net’de gelmiş olsa da IIS’de henüz gelmediğinden, 2GB’dan fazla doküman yükleyecekseniz, beklemeniz gerekmektedir.

Unit of Work Pattern

Uzundur yazılım tasarım kalıpları hakkında yazmayalı olmuştu. Bu sefer size benim de çok işime yarayan ve büyük üstan Martin Fowler tarafından bize yönlendirilen – aslında tam kaynağı konusunda tam bir fikrim yok ama Fowler’ın PoEAA1 kitabında bahsi geçmekte – bir pattern.

Bu tasarım kalıbının amacı ve uygulaması çok basit, bu yüzden projelerimde kullanmaya özen gösteriyorum, aslında basit bir sorunu gidermesine rağmen uygulama açısından çok büyük bir amaca hizmet etmekte. Sonuçta tasarım kalıbı dediğimiz şeyler de kusura bakmayın gereksiz şeyler değiller.

Nedir, Amacı, Katmanı

Çok basit bir amacı var;

Veritabanında yapılan tüm işlemlerin tek bir bağlantı üzerinden yürümesi ve bir yerde hafızada tutulması.

Farkına vardığınız gibi bu bir DAL (Data Access Layer) kalıbı. Adından da anlaşılabileceği gibi her yapılan işlemin bir işlem birimi (unit of work) olarak ele alınmasını, bunların saklanmasını ele alan sınıf. Daha sonrasında bu işlemlerin toplu olarak kaydedilmesini (Save), geri alınmasını (Rollback), ya da iptal edilmesini (Dispose) sağlamaktadır. Detaylı açıklamayı Unit of Work Design Pattern makalesinde bulabilirsiniz.

Kullanımı

Kullanımı için çoğu kaynak Repository Pattern (Depolama tasarım kalıbı) kullanılmasını önermektedir. Aksine bir repository nesnesine ihtiyacınız yoktur. Her hangi bir bağlantı için, gerekli işlemleri içeren bir Unit of Work yazılabilir. Hiç de zor değil sonuçta. Ama tam olarak nasıl yazılması gerektiğini anlatayım.

Öncelikle elinizin altında, DAL için yazılmış bir data işlemleri nesnesi olmalı. Bu Repository Pattern olur, Generic Repository Pattern olur ya da CRUD işlemlerinin toplandığı bir sınıf olabilir. Bu sınıfın temel bağlantı alan yerini, dışarıdan bir kaynaktan alacak şekilde ayarlarsanız işlemlerimiz neredeyse tamamlanmış olur. Esas kafa karıştıran noktaları özetlersek;

  • Bağlantı dışarıdan, içerideki CRUD işlemi yapan sınıfa girmeli,
  • CRUD işlemi yapan sınıf kaydetme işlemlerini anlık olarak yapmamalı, kendi içinde Commit yapacak bir fonksiyon kullanmalı ve bu fonksiyon çağırılmadan işlem yapmamalı,
  • Transaction kullanılacaksa Rollback işlemleri için gerekli fonksiyonları içermeli,
  • CRUD fonksiyonlarını içeren sınıflar birden fazla olabilirler ki olmaları her zaman tercih edilendir.

Repository Pattern ile yazılmış sınıflar otomatikman Unit of Work için uygun olduğundan bu örneklerin hepsi onun üzerinden veriliyor. Fakat elinizde yukarıda yazdığım dört özelliğe sahip bir nesneniz varsa – teorik olarak zaten bu da repository pattern kullanmanızı sağlar fakat isminde repository yazmıyor diye kabul etmeyen arkadaşlarınız olabilir, oluyor öyle – siz de gayet Unit of Work kullanabilirsiniz.

Mimarisi

Basitçe yapılacak işlemi anlatayım; Tüm data işlemi yapan sınıflarınız Unit of Work içerisinde birer property olarak tutulur. Bu propertylere aynı DB connection ya da DB Context gönderilir. Property olarak gösterdiğimiz her sınıf kendi içinde değişmiş tüm datayı saklar. Unit of Work içinde bir “Save Changes” methodu olur. Bu method çağırıldığında tüm propertyler üzerindeki Save işlemleri çağırılır. Bu sayede işlemler yapılmış olur.

Avantaj olarak konuşursak, tüm DB işlemleri için dağıtık yapılarınızı tek bir sınıfta toplarsınız, transaction için rollback fonskiyonlarını ve kaydetme için save fonksiyonlarını tek bir method içinde kullanmış olursunuz. Bu da bir üst katman olan Service Layer ya da Business Intelligance Layer üzerinde işlem yaparken kolaylık sağlar. Eğer Dependency Injection kullanıyorsanız, küçük bir modifikasyonla hemen tüm DAL katmanınızı bu yapıya uygun hale getirebilirsiniz, zira çözülmesi gereken sadece DBContext nesnenizdir ve bu işlemlerin hepsi için sadece Unit of Work sınıfını güncellemeniz yeterli olacaktır. Ayrıca bir loglama yapısı kuracaksanız bunu da Unit of Work içerisine koyabilirsiniz. Hatta ve hatta DB’niz yoksa ve sadece XML işlemler yapıyorsanız, Service katmanının istediğiniz gibi yazılmasını ve dataların proje bitene kadar XML’de saklanmasını sağlayabilirsiniz. Anlat anlat bitmez bu işlemler, örneğe geçelim isterseniz.

Örnek

Bu kısımları internetten çok beğendiğim bir kaynaktan direk yapıştırıyorum, gerçi tüm örnekler aynı internette.

//IUnitOfWork.cs
public interface IUnitOfWork : IDisposable
{
    IProductRepository ProductRepository { get; }
    IOrderRepository OrderRepository { get; }
    void Save();
    // Gerekiyorsa buraya RollBack eklenebilir...
}

//UnitOfWork.cs
public class UnitOfWork : IUnitOfWork
{
    private readonly MyDataContext _context; // En önemli yer burası!!!
    private IProductRepository productRepository;
    private IOrderRepository orderRepository;

    public UnitOfWork()
    {
        this._context = new MyDataContext();
    }

    public IProductRepository ProductRepository
    {
        get { return this.productRepository ?? (this.productRepository = new ProductRepository(_context)); }
    }

    public IOrderRepository OrderRepository
    {
        get { return this.orderRepository ?? (this.orderRepository = new OrderRepository(_context)); }
    }

    public void Save()
    {
        _context.SaveChanges();
    }

    private bool disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

Bu arada service katmanında kullanımına gelirsek;

IUnitOfWork _uow = new UnitOfWork();
public void SaveProduct(Product _product)
{
    _uow.ProductRepository.Add(_product);
    _uow.Save();
}

Sonuç

Bu pattern’in kullanılması bu kadar basit, daha sonrasında ister Generic Repository kullanın, ister kendi “repository” nesnenizi içeren barklı bir bağlantı türünüzü kullanın fark etmeyecektir. En önemli noktanız her zaman MyDataContext kısmı olduğunu da aklınızdan çıkarmayın. Bir ara Generic Repository Pattern ile bu Unit of Work’ü nasıl genişleteceğinizi de anlatacağım. Boş vaktinizi iyi değerlendirmeniz dileğiyle. Ha bu arada tabii bir de Generic Unit of Work Pattern diye bir şey de var…


  1. Patterns of Enterprise Application Architecture (Martin Fowler) 

Doğru bil(me)diklerimiz neler?

Dediğim gibi bir sürü boş vaktim olmasa da bir sürü boş işe harcadığım vaktim olduğu için bir çok gereksiz konuda yazı yazabiliyorum. Aynen bir sürü gereksiz yazılım yazmak gibi ama biraz daha farklı. Bus efer ki konu, esasta doğru bildiğimiz yanlışlar ile alakalı. Bildiğiniz gibi, yazılım üzerine çalışınca, yazılım hakkında bir çok diyaloğun da içerisinde oluyorsunuz. Bu yazının ortaya çıkmasında sebep aynı böyle bir tartışmaydı; **“Object Oriented Programming kullanmıyorsunuz!” lafından çıktı hepsi, beni suçlamayın onu suçlayın.

Ne Bil(mi)iyoruz?

Pek tabii ki yazılımcılar olarak biz her şeyi biliyoruz! Aksi ispat edilemez, edilecekse gelsin çıksın karşıma. Biz bu meslekte dirsek çürüttük, her şeyini biliyoruz tabii ki. Ne biliyoruz peki? OOP biliyoruz, Pattern biliyoruz, Nesne biliyoruz, Polimorfizm biliyoruz, her bir şeyi biliyoruz. Açıkcası bir kaç güne kadar ben de böyle diyordum ki, piyasadan bir üstadımız beni yerin yedi kat dibine sokuncaya kadar. Sonrasında kendime geldim, nefes aldım bir oh çektim falan.

Peki gerçekten bu terimlere hakim miyiz?

Konuşmanın biraz daha heyecanlandığı noktada, benim otomatikman muhalefete geçme gibi bir özelliğim olduğundan, konu genelde farklı boyutlara taşınır. Konuşmada arkadaşın yukarıda belirttiği OOP kullanmıyorsunuz, bir nefi bilmiyorsunuz lafı sonrasında, sinirler arttı benim. “OOP Nedir?” dedim arkadaşa, basitçe bana OOP tasarım kalıplarıdır dedi o da. Bir kere öyle değil bu işler. OOP dediğimiz, nesne tabanlı programlamadır. Yani nedir? Nesne olması gerekir, yani senin nesneler yaratman, basitçe bu nesneleri yönetecek katmanları yazman ve buna bağlı programlama yapmanı anlatır. Peki ben hiç tasarım kalıbı ya da güzel adıyla Design Pattern kullanmamışsam? O zaman ben hiç OOP kullanmamış mı olurum? Ekmeğe, şeklini verirken franzile şekil vermediysem ortaya çıkan ürün ekmek değil midir? Aynı mantıkta yanıtlanabilecek bir cümle.

Eğer sen nesnelerini oluşturup, katmanlarını koyduysan, SOLID mantığını biraz da olsun yakaladıysan o zaman zaten OOP yapmışsın ne mutlu sana. Pattern kullanmadıysan OOP yapmadın diye bir algı yok, olmamalıdırda. Pattern kullanmadım diyorsunuz da peki o konuda da emin misiniz?

Pattern olayı

Ya şimdi bir gerçek var, Design Patterns popüler olduğundan beri, herkes bu terimi kullanır oldu hayatında. Adı üzerinde, tasarım kalıbı bu, yani kalıplaşmış kod yapısı. Hiç kullanamadan adam akıllı kod yazmanız için çömez olmanız lazım, kullanıp adını bilmezseniz normal developersınızdır. Fakat insanlar sizden ismini ve cismini bilmenizi bekler. Yeni dünya diye bir meyva var, ismini tam olarak bilmem. Alırım, yerim. Tutup da sen bana bunu yerken, “hiç yeni dünya yememişsin, çok süper meyva” dersen, yemiş olsam bile yemedim psikolojisi oluşur üzerimde.

Kod açısından örnek verirsek, yıllarca data fonksiyonlarını yazdıktan sonra, datayı ele alan DAL yani Data Access Layer’ı yazarken nesnelere uygun tekil sınıflar yazdım. Yani bir tablo varsa, o tabloya data girişini sağlayan. DataTablosuBase.Save() ya da DataTablosuBase.Insert(DataTablosu _dataTablosu) kodlarını içeren sınıfı yazdım ve datalarımı öyle kaydettim. Şimdi yıllar sonra öğreniyorum ki bu yöntem Repository Pattern olarak ele alınıyormuş. Şimdi aynı konuşmada, arkadaş bana onu da dedi “Hiç pattern kullanmadan OOP yazılmaz”. Bu arkadaşı ilk arayan 20 kişiye postayla göndermeye karar verdim. Bildiğin bas baya kullanmışım işte.

Bu pattern’in üç temel prensibi var; Data erişiminde tek noktanın olması, Tablolarınızla alakalı tek bir sorumlu yer olması, Olası altyapı değişimlerinde sistemin minimum değişimle işlemesi. E ben bunu gayet yerine getirmişim, sadece “DataTablosuBase” yerine “DataTablosuRepository” dememişim. Ha bir de EF kullanmamışım ama o kontaya girersem çok olaylar çıkar.

Sonuç

Demem odur ki, asla bir insanla beraber adam akıllı kod yazmadan ona şunu yapmamışsın, bunu yapmamışsın demeyin. Yapmıştır, illa yapmıştır da bilmiyordur. Yapmıştırsın da bilmiyorsundur diyin. Bu sayede siz de o insandan biraz kod öğrenebilir, o insanla aranızı bozmazsınız. Dünya daha güzel bir yere gelir. Fakat konunun başında da dediğim gibi biz yazılımcılar her şeyi bildiğimiz için bu konuda burnu havada insanlarız. Arada bir kendinizden daha iyi olan insanlar tarafından alaşağı edilin de, kendinize gelin vallaha.

Composite Application Architecture ve Service Oriented Architecture

Bu sefer de biraz servis tabanlı mimariler üzerine bir yazı yazayım istedim. Belki bildiğiniz üzere, son zamanlarda her insan SOA demeye başladı yazılım firmalarında, fakat bu terime aşina mıyız? SOA diye bahsettiğiniz şey CAA Composite Application Architecure olmasın ya da SaaS Software as a service de olabilir. Bu terimler üzerine biraz düşmek ve aklımızda bazı şeyleri netleştimek istiyorum.

Bu yazının sonrasında detaylı olarak açıklancak şeyleri burada listeleyeyim ki sonradan açıklanmamış şeyler kalmasın;

  • CAA – Composite Application Architecture (Bileşik Yazılım Mimarisi) Nedir?
  • SOA – Service Oriented Architecture (Servis Tabanlı Mimari) Nedir?
  • SaaS – Software as a Service (Bir Servis Olarak Yazılım) Nedir?

Yukarıda belirtiğim konulara özgü detaylı makaleleri sonradan anlatacağım pek tabii ki. Şimdilik ben SOA ve CAA üzerinde durmak ve aklınızda oluşan sorulardan kurtulmak istiyorum.

CAA Nedir?

CAA dediğimiz olay bileşik yazılım mimarisini temsil etmektedir. Adından da anlaşılacağı gibi bazı temel faktörlerin, yazılım mimarisini oluştururken birleştirilmesi temeline yatar. Oluşturulan sistemin bel kemiğine Composite Solution Platform (Bileşik Çözüm Altyapısı) diyebiliriz, diğer programlar ya da programcıklar buraya bağlanır ve yönetilirler. Şöyle detaylıca anlatmaya çalışayım. Programlama temelleri üzerinden gidersek, bir programın illa birleşim yapması için service olmasına gerek yok. Her hangi bir dille yazılmış, dışarıya data verirken belirli limitasyonlar ve standartlar altında alınmış programlara Composite Application diyebiliriz. Bu programlar ister servis olsun – SOA üzerinden – ister dll olsun – CBD component based development üzerinden – bir şekilde projeye entegre olabilmelidirler.

Belirtilen entegrasyonu sağlayan bir Governance (Yönetim) altyapısı çıkar. Bu yönetim altyapısı, bileşik altyapıların entegrasyonu ve yönetimini sağlamakta ayrıca diğer programlar ile data alışverişi, mesaj alışverişi gibi kontrolleri sağlamalıdır. İstenilen dilde ve istenilen altyapıda buna uygun bir yöntem bulabilirsiniz.

Bu programlama modeli, yazılım mimarisinde üç temel noktayı ele almaktadır;

  • İşin ya da çalışmanın dizaynından tam yarar alabilmek,
  • İşin ya da çalışmanın, olabildiğince efektif evrim geçirmesine destek olmak,
  • Var olan sistemlerin yerine yenilerini yapmak yerine, onlara destek vererek tekrar kullanmak (reusability).

Kısaca bu programlama modelinde amaç; esnek, adapte edilebilir ve iş ile IT arasında yüksek oranda verim sağlayacak şekilde mimariler oluşturmak.

SOA Nedir?

Bu geyiği burada yapmazsam tabii ki kafayı yerim; One person successfully described SOA completely, and immediately died. Tabii ki böyle bir olay yok, SOA aslında anlatılabilir ve anlaşılabilir bir yapıda. SOA’nın açılımı Service Oriented Architecture, yani servis tabanlı mimari. Buradan da anlayabileceğimiz gibi, program altyapımız servisler (.net için WCF, Web Service, Web API).

Bu mimariyi kısaca özetlersek; Bir Enterprise Application geliştirdiğimizi düşünelim, CMS olur, ERP olur, HRP olur. Bu tip sistemler için daha önceden yazılmış, başka sistemlerde de kullandığınız küçük programlar olsun, SMS gönderimi, Mail SMTP sunucusu, acil durumlarda gerekli kişilere haber verecek Code Red altyapısı ya da bir Report programı. Bu programların büyük seviye programlar ile iletişime geçmesi için önce hepsini servis olarak yani entegre edilebilir, bağımsız programcıklar olarak kodlayıp, gerekli kısımlara entegre etmemiz işleminin planlanmasına SOA denir.

Daha detaylı örnek olarak ele alalım; Report servisi, düzenli olarak her hafta sonunda ilgili haftanın ilgili datalarını almak için ERP’ye HRP’e gidebilir. ERP’de HRP’de bu programın çalışması ya da çalışmaması bağımsız olacak şekilde datalarını ona verirler. Bu Report servisine bir de önemli bir rapor çıktığı için Code Red servisi bağlayabilirsiniz ki bu datanın gelmemesi durumlarını kontrol eder, eğer data gelmiyorsa Code Red sistemine bağlı SMS gönderim servisi – ki bu servis daha önceden ERP ve HRP sistemlerine bağlanmıştır – acil durum çağrısını ilgili birimlere gönderir.

Tekrar tekrar kod yazmadan ne kadar çok işlemi yapabildiğimizi görebildiniz mi? ERP ve HRP genel arayüzü oluştururken, SMS gönderim gerekli bildirimi, Reporting ise gerekli raporlamaları sağlamaktadır. Code Red ise datanın bütünlüğünü ve acil durumların kontrolünü sağlamaktadır. Bu arada yaptığımız Seperation of Concerns olayına da dikkatinizi çekmek isterim.

Lafı uzatmadan, SOA’nın dört ana maddesini de ele alalım istiyorum;

  • Sınırlarınız kesin olmalıdır.
  • Servisler özerk yapılarda, kendini idare edebilir olmalıdır.
  • Servisler schema ve contract paylaşır, class paylaşmaz.
  • Servis uyumluluğu belirli politikalarla belirlenir.

Bu dört kurala bağlı şekilde yazdığınız servisleri, birbirleri ile entegre hale getirebilir, projelerinizi genişletebilirsiniz. Daha detaylı olarak SOA kısmından daha sonra bahsedeceğim.

SaaS Nedir?

Aslında SaaS’ın konu ile hiç bir alakası yok, fakat tartışmalar sırasında insanların aklına alakalıymış gibi gelmesin diye burada bahsediyorum. SaaS yani Software as a Service olayı, bir yazılımın servis olarak sunulmasıdır. Yukarıda bahsettiğimiz SOA olayı değil, bildiğiniz ücretli ya da ücretsiz bir işlem yapan kapalı kutulardan bahsediyoruz. Online Task Yönetimi ya da Online Project Management araçları bunlara örnek verilebilir. Kendi API’leri ile diğer programlarla konuşabilirler ama bu demek değildir ki bizim SOA altyapımıza uygun olacaklar. SaaS olayını kendi içinizde geliştirirseniz bir servis olur, parayla satılan servis olmaz. Burada Türkçe karmaşası yaşıyoruz, ilk servis dediğim nokta bir iş yapan programı analtırken, diğer servis kelimesi hizmet veren programı kast etmektedir.

Sonuç

Bu yazıda biraz tanımları size aşina olması için ele almak istedim. Halen aklınızda sorular olabilir ki bu soruları Yorum kısmında yazarsanız, elimden geldiğince yanıt vermek isterim. CAA ile SOA aslında bağlantılı sistemler olmasına rağmen SOA daha kalıplaşmış bir tanıma sahiptir, CAA ise daha genel ve daha eski bir teridir. Neticesinde günümüz programlama mantığı SOA’yı bile eskitmiş olmasına rağmen, geleneksel yazılım mimarilerinden yeni kurtulan Türk Yazılım Piyasası anca SOA terimini yeni kabul etmeye başladı. Belki yıllardır kullanıyorsunuz fakat emin olabilirsiniz ki çoğu firma daha terimi ilk defa duyuyor.

SOA ve CAA konusunda daha detaylı analiz makalelerini daha sonra yazacağım, şimdilik iyi kodlamalar…

Mobili yakalamak / IsMobileDevice / 51 Degrees

Daha önce bahsettiğim mobil uygulama çilesini bilenler bilir (bilmeyenler için; Android Üzerine). Bu uygulama tabii ki her ne kadar küfretmek istesem de edemediğim bir sorunla karşı karşıya kaldı geçenlerde. Güvenli kontrol ve download istatistiği sağladığımız için belirli bir download sayfasından verilen izinli dosyaların, mobil cihazlarda indirilememesi. Ben de yeter artık diyerek, mobil gelen cihazlara direk dosyayı link olarak atamaya karar verdim ve bu sorunun daha üstesinden gelecektim ki – ayrıca bu karara 6 saatlik iş gücü sonrasında ulaştım – bir sorunla karşılaştım. .Net Bowser Request.Browser.IsMobileDevice özelliği, tabletleri yakalamıyor!!!

Sorun

Sorun belli, sisteme talepte bulunan bir cihazın mobil olup olmadığını anlamak için eklenen eklenti tabletleri yakalamıyor. Ayrıca bunun güncel olduğunu da pek sanmıyorum. Cihazın tabletde olsa neden mobil olarak algılanmasını istememin sebebi de, üzerinde o harika Android işletim sisteminin olması. Bu arada belirtmem gerekir ki; iOS aletlere hiç bir sorun yok, Android’in en güncel sürümlerinde de hiç bir sorun yok yani download yönlendirme sayfamızdan indirme yapabiliyorlar. Fakat Andorid’in eski sürümünü kullanan %35’lik bir kesim olunca ve bu arkadaşlar sürekli Play Store’a “dosyalar açılmıyor, ne kötü program” diye yazınca insan görmezden gelemiyor işte.

Çözüm 1

Baştan diyeyim bu sorunu çözmedi :D. (http://detectmobilebrowsers.com)’a girip oradan browser agent ile yakalarım ben ne olacak ki yaa dedim ben de. Demez olaydım, sonuçta Chrome tarayıcısı tablet ve desktop arayüzünde benzer agent info bilgisini kullandığı için bu ihtimal de bir çırpıda son buldu. Dedim ki media query koysam falan, gizlesem göstersem linkleri. O kadar da düşmedin sen dedim kendi kendime. Bunun üzerine araştırma yapınca bu tip dataların en güncel halinin (WURFL)[http://wurfl.sourceforge.net] denen açık kaynaklı bir DB’den geldiğini öğrendim. Fakat bunu nasıl implemente edebilirdim ki, ayrıca tek istediğim sadece IsMobileDevice yazıp, if koyup link göstermek yani gerek var mı bu karada eziyete? (YAGNI) 1

Esas Çözüm

İşte tam bu düşüncelerin arasında bir çözüm buldum 51degrees (http://51degrees.codeplex.com). Başta open source yazılan ve daha sonra paralı versiyonu da çıkan bir library. Ayrıca sadece .net için değil diğer diller için de çözümleri bulunmakta. Kurulumunu da NuGet üzerinden yapabildiğimiz için direk atladım diyebilirim. Bu arada yükleyeceğim sistem de kıçıkırık bir sistem değil, anlık responce timeların istatistiğini tuttuğumuz büyük bir ERP çözümü. Yine de seçenekleri bitince insan her yolu denemeye başlıyor.

NuGet üzerinden yükledikten sonra kendi configurasyon ayarı ve dll dosyası ile sisteme dahil olan bu çözüm üzerinde bir ayar yapmadım. Açıkcası Login yönlendirmesi ve gereksiz iki üç dosya vardı, bunları kaldırmaya ayar denemez bile. Sonuçta sistemi çalıştırdığımda her şey istediğim gibiydi. Tablette test edince yine Mobile olarak algılıyor ve her şey mükemmel çalışıyordu. Size tavsiyem bu ürünü eğer sitenizin mobil kısmını yapacaksanız kullanmanız. Zira açık lisanslı hali ile gayet güzel kullanılabiliyor.

Sadece bu özelliğe yaramayan 51degrees’in diğer özelliklerini ele alırsak;

  • ScreenWidth ve ScreenHeight değerlerini alabilmek.
  • Request.Browser.IsMobileDevice özelliğini genişlettiği için ekstra bir kod yazmamak.
  • Paralı versiyonunda IsTablet gibi bir değişkene sahip olmak,
  • Free hali ile haftada bir güncelleme geçirdiği ve bu da standart mobil cihazlar için yeterli bir güncelleme olduğundan pek de bir sorun teşkil etmemek,
  • Paralı versiyonu ile tarayıcınızın bir çok özelliğine erişmek; renkler, falan filan,
  • Paralı versiyonunda gelen kullanıcının Celluar mı yoksa Wi-Fi üzerinden geldiğini bulmak.

Açıkcası bana free versiyonu yettiği için pek de diğer özelliklerini araştırmadım. Eğer gerçekten hızlı ve sürekli güncellenen – bu arada WURFL DB’sine bağlayabiliyor ve oradan güncellenmesi sağlanabiliyor – bir sistem istiyorsanız ve Request.Browser.IsMobileDevice kodu sizi deli ediyorsa, bu tam da sizin aradığınız çözüm.

Size kafayı sıyırmadan iyi mobil kodlamalar…


  1. You aren’t gonna need it! prensibi.