2017-11-07 10 views
1

DispatchQueueに関する質問があります。私のビューコントローラの1つでは、Webから画像をダウンロードしてUIImageViewに表示する必要があります。アプリケーションが画像をダウンロードしている間、私はDispatchQueueを使用してUIをブロックしないようにしています。以下のコードは動作しないようです。なぜ誰かが説明できますか?どのようにこれを正しく行うには?Swiftでデータをダウンロード中にUIをブロックしないでください

let store_id = self.store!._id 

DispatchQueue.global().async { 
let imageUrl = URL(string: "www.image.com") 
self.storeImageData = imageUrl != nil ? try? Data(contentsOf:imageUrl!) : nil 

    if self.storeImageData != nil { 
     DispatchQueue.main.async { 
      self.topBackgroundImageView.image = UIImage(data:self.storeImageData!) 
     } 
    } 
} 
+0

'てみてくださいを追加しますか?データ(contentsOf:imageUrl!) 'がデータを同期してダウンロードする代わりに、URLSessionまたはAlamofireを使用してコンテンツを非同期にダウンロードする必要があります。 – Lamar

+0

@Lamarしかし、非同期ブロック内のデータをダウンロードしています。まだUIをブロックしていますか? – eChung00

+0

はい、私は答えが – Lamar

答えて

0

私は、ネットワーク経由でダウンロードするrecommendあなたの方法ではないでしょう、URLSessionまたはAlamofireのいずれかを使用します。あなたが従うことができるコードは次のとおりです。

func downloadImageFrom(urlString:String, completion:@escaping(Data?)->()) { 
    guard let url = URL(string:urlString) else { return } 
    let request = URLRequest(url: url) 
    URLSession.shared.dataTask(with: request) { (data, _, err) in 
     if err != nil { 
      // handle error if any 
     } 
     // you should check the reponse status 
     // if data is a json object/dictionary so decode it 
     // if data is regular data then pass it to your callback 
     completion(data) 
    }.resume() 
} 

func doWork() { 
    DispatchQueue.global(qos: .background).async { [weak self] in 
     guard let strongSelf = self else { return } // to avoid reference cycle 
     strongSelf.downloadImageFrom(urlString: "http://www.image.com", completion: { (data) in 
      if let _data = data { 
       // now you have the data 
       DispatchQueue.main.async { 
        // display your imageView with the data 
       } 
      } 
     }) 
    } 
} 
+0

上記の "try?Data(contentsOf:imageUrl!)はデータを同期してダウンロードしていますが、代わりにURLSessionまたはAlamofireを使用してコンテンツを非同期的にダウンロードする必要があります" コードはasyncでグローバルキューそれはどのように非同期で行うのですか? –

+0

@RajanMaheshwariリンゴのドキュメントは、私たちがそれをしないことを示唆しています。私は参照に追加しました – Lamar

+0

Appleの医者はメインキューでそれをしないことを提案します。しかし、質問によると、OPはすでにDispatchQueue.global()。async'を使ってデフォルトのqoSバックグラウンドスレッドを取得しています。 –

0

希望するのは、Webから画像をダウンロードしてUIImageViewに表示することです。

SDWebImageは、デフォルトで非常に積極的なキャッシュを行います。 HTTPサーバーによって返されるすべての種類のキャッシングコントロールヘッダーを無視し、返されたイメージを時間制限なしでキャッシュします。あなたの画像のURLは決して変化しない画像を指している静的URLです。指示された画像が変化した場合、URLのいくつかの部分がそれに応じて変化するはずです。

import SDWebImage 

imageView.sd_setImage(with: URL(string: "http://www.image.com/image.jpg"), placeholderImage: UIImage(named: "placeholder.png")) 

// Or using this code 
[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.image.com/image.jpg"] 
     placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"] 
        options:SDWebImageRefreshCached]; 

進行状況インジケータ

imageView.sd_setShowActivityIndicatorView(true) 
imageView.sd_setIndicatorStyle(.Gray) 
関連する問題