9 Şubat 2013 Cumartesi

IOS İnternetten Resim İndirme Asenkron

Merhaba . Önceki örnekte internette verilen linkten resimi indirme ve göstermeyi anlattım . Bu kez ise aynı işlemi asenkron yapmayı anlatıcam . Öncelikle asenkronun gerekliliğini anlatim .
Önceki örnekte resim indirilirken  Main Thread kullanılamaz olur ve kullanıcı resimi indirme esnasında hiçbir işlem yapamaz. İnternetin yavaş olması bu zamanın artmasına neden olur ya da uygulama hata verebilir. Bunun yerine aynı resmi asenkron indirerek Main Thread i kullanmadan yapabiliriz . Böylece kullanıcı istediği işlemi yapmaya devam edebilir . Kodlara tam anlamıyla hakim olabilmek için "dispatch_queue " ye biraz alışık olmak gerekir.

İndirme kodları önceki örneğin aynısı , o kodları anlatmıcam , sadece aynı işlemi asenkron yapmayı anlatıcam .

Fonksiyonumuzun adı bu kez "-(void)resimIndirASYNC:(NSString*)resimLink" .

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);


ile dispatch kullanarak queue oluşturuyoruz ve işlem asenkron olacağı için dispatch_get_global_queue yi kullanıyoruz ve bu fonksiyon 2 parametre alıyo . 1. parametre öncelik , yani işlemin önceliği . Bunu standart olarak "DISPATCH_QUEUE_PRIORITY_DEFAULT" diyoruz. Yani varsayılan . extra bi öncelik gerektirmeyecek şekilde .  2. parametre ise sistem Flag ı . Bu değer genellikle "0" olur . Zaten Apple dökümanlarına baktığınızda bu değerin 0 dan farklı olması durumunda geriye Null döndürülebileceği söyleniyo . Yani her zaman 0 yazıoruz .

dispatch_async fonksiyonu verilen işlemi oluşturduğumuz queue de asenkron olarak yapmamızı sağlıyo . Burada indirme işlemi yapıcak .  Bu fonksiyonda 2 parametre var . 1. parametre asenkron işlemin hangi queue üzerinde çalışacağı . Oluşturduğumuz "queue" değişkeni 1. parametremiz oluyo . 2. parametre ise bir blok yani asenkron olarak çalışacak fonksiyon . Yani indirme işleminin yapılacağı işlem .

Resmi asenkron olarak internetten indirdikten sonra bu resmi UIImageView de göstermek için Main Thread i kullanmamız gerekir . Çünkü kullanıcıyla iletişime geçilen tek thread main thread dir . Bu işlem senkron olarak yapılmalı , yani Main Thread etkilenmeli . Asenkron işlemin içinde senkron işlem yaptırmak için "dispatch_sync" metodu kullanılır ve bu metod da dispatch_async gibi 2 parametre alır . İşlemin senkron olması için 1. parametre "dispatch_get_main_queue()" , yani kodların main thread üzerinde çalışması . 2. parametre ise çalışacak kodlar . Burda basit olarak indirdiğimiz resmi UIImageview üzerinde gösteriyoruz .




- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *resimLinki = @"https://devimages.apple.com.edgekey.net/technologies/tools/images/new_hero20110308.jpg";
   
    [self resimIndirASYNC:resimLinki];
}





-(void)resimIndirASYNC:(NSString*)resimLink{

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
    
    dispatch_async(queue, ^{
       
       
         
        NSURL *resimUrl = [NSURL URLWithString:resimLink];
       
        NSData *resimData = [NSData dataWithContentsOfURL:resimUrl];
       
        UIImage *indirilenResim = [UIImage imageWithData:resimData];
       
   
       
        dispatch_sync(dispatch_get_main_queue(), ^{
          
            imageView.image = indirilenResim;
           
           
        });
       
       
    });





}


IOS İnternetten Resim İndirme Kodu

Merhaba . IOS de verilen linkten resim indirme ve bu resmi UIImageView de göstermeyi anlatıcam .  Bu örnek en basit örnek ve resim internetten indirilirken Main Thread kullanılıyo . Bu durumda diğer viewler (buton falan) kullanılamaz .

Ekranı kaplayan UIImageView ekledim ve indirilen resim burada gösterilecek .

  


@property(nonatomic,retain)IBOutlet UIImageView *imageView;
 
ile UIImageView için property oluşturuyoruz ve imageview imize bağlıyoruz . Böylece indirdiğimiz resim bu imageview de gösterilebilecek. Property i ".m" dosyasında synthesize etmemiz gerekiyo.

Resim indirme işlemini fonksiyona atadım ve bu link dışarıdan indirilecek resimin linkini alıyo .

   -(void)resimIndir:(NSString*)resimLink

NSString tipindeki link NSUrl oluşturmak için kullanılıyo .

    NSURL *resimUrl = [NSURL URLWithString:resimLink];

URLWithString metodu verilen linkten NSUrl oluşturmamızı sağlar .

     NSData *resimData = [NSData dataWithContentsOfURL:resimUrl];

ile de verilen url den NSData türünde bilgi gelir . NSData genel bir kavram ve birçok tip için kullanılır . Biz de resimimizin bilgisini burada tutucaz . Gerçek indirme işlemi burada yapılıyo

      UIImage *indirilenResim = [UIImage imageWithData:resimData];

ile de indirdiğimiz veriyi resime dönüştürüyoruz . Artık bu resmi kullanabiliriz

     imageView.image = indirilenResim;

bu adımda da resimin gösterilme aşaması var . Eğer ki herşey doğru çalışıyosa resmi görmeniz gerekir.

Yazdığımız fonksiyonu denemek için ViewDidLoad metodunda örnek olarak bir resim indirdim .

   NSString *resimLinki = @"https://devimages.apple.com.edgekey.net/technologies/tools/images/new_hero20110308.jpg";
    

  [self resimIndir:resimLinki];




İstediğiniz resimin linkini yazarak resimi indirebilirsiniz.

Birsonraki yazıda resmi asenkron olarak indirip ekranda göstermeyi anlatıcam


-(void)resimIndir:(NSString*)resimLink{
   
    NSURL *resimUrl = [NSURL URLWithString:resimLink];
   
    NSData *resimData = [NSData dataWithContentsOfURL:resimUrl];
   
    UIImage *indirilenResim = [UIImage imageWithData:resimData];
   
    imageView.image = indirilenResim;



}