2017-04-05 12 views
2

私はRay Wenderlich(Link)のFirebaseチュートリアルに従い、observe-methodのスナップショットでオブジェクトを初期化する方法を採用しました。 :Firebase iOS:TableView - Best Practiceのダウンロードイメージ

クラス場所:

init(snapshot: FIRDataSnapshot) { 
    identifier = snapshot.key 
    let snapshotValue = snapshot.value as! [String : AnyObject] 
    type = snapshotValue["type"] as! String 
    name = snapshotValue["name"] as! String 
    address = snapshotValue["address"] as! String 
    latitude = Double(snapshotValue["latitude"] as! String)! 
    longitude = Double(snapshotValue["longitude"] as! String)! 
    avatarPath = snapshotValue["avatarPath"] as! String 

    ref = snapshot.ref 
} 

LocationsViewController:

databaseHandle = locationsRef?.queryOrdered(byChild: "name").observe(.value, with: { (snapshot) in 

     var newLocations:[Location] = [] 

     for loc in snapshot.children { 
      let location = Location(snapshot: loc as! FIRDataSnapshot) 

      newLocations.append(location) 
     } 

     self.locations = newLocations 
     self.tableView.reloadData() 
}) 

これは本当に魅力的ですが、ストレージ参照 "avatarPath"の下に保存されているイメージを読み込もうとしています。 私の試行はうまくいったが、イメージに読み込み時間がかかる。これらの画像を読み込むためのより良い方法/場所がありますか?

私の試み1:

databaseHandle = locationsRef?.queryOrdered(byChild: "name").observe(.value, with: { (snapshot) in 

     var newLocations:[Location] = [] 

     for loc in snapshot.children { 
      let location = Location(snapshot: loc as! FIRDataSnapshot) 

      newLocations.append(location) 
     } 

     self.locations = newLocations 
     self.tableView.reloadData() 

     //Load images  
     for loc in self.locations { 
      let imagesStorageRef = FIRStorage.storage().reference().child(loc.avatarPath) 
      imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in 
       if let error = error { 
        print(error.localizedDescription) 
       } else { 
        loc.avatarImage = UIImage(data: data!)! 
        self.tableView.reloadData() 
       } 
      }) 
     } 
}) 

(Locationクラス内の)私の第二の試み:

init(snapshot: FIRDataSnapshot) { 
    identifier = snapshot.key 
    let snapshotValue = snapshot.value as! [String : AnyObject] 
    type = snapshotValue["type"] as! String 
    name = snapshotValue["name"] as! String 
    address = snapshotValue["address"] as! String 
    latitude = Double(snapshotValue["latitude"] as! String)! 
    longitude = Double(snapshotValue["longitude"] as! String)! 
    avatarPath = snapshotValue["avatarPath"] as! String 

    ref = snapshot.ref 

    super.init() 
    downloadImage() 
} 

func downloadImage() { 
    let imagesStorageRef = FIRStorage.storage().reference().child(self.avatarPath) 
    imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in 
     if let error = error { 
      print(error.localizedDescription) 
     } else { 
      self.avatarImage = UIImage(data: data!)! 
     } 
    }) 
} 

事前にありがとうございます!ニコ

+0

なぜあなたはSDWebImageまたはAfnetworkingImageDownloaderのようなサードパーティのライブラリを使用することはできません。これらは実際にはキャッシュや画像表示にはうまくいきます。 –

+0

最初のケースでは時間がかかりすぎる理由がわかります。非同期タスクマネージャなしで1つずつダウンロードし、イメージがダウンロードされるたびにtableViewを再ロードしています。 2回目は多かれ少なかれ同じです。 –

答えて

1

最良の方法は、細胞機能の搭載内部で非同期ロードすることです。私は意味:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 
DispatchQueue.main.async { 
    let imagesStorageRef = FIRStorage.storage().reference().child(self.locations[indexPath.row].avatarPath) 
     imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in 
      if let error = error { 
       print(error.localizedDescription) 
      } else { 
       locations[indexPath.row].avatarImage = UIImage(data: data!)! 
tableView.reloadRows(at indexPaths: [indexPath], with animation: .none) 
      } 
     }) 
    } 

}

+0

ありがとうございます!完璧に動作します! –

+2

FYI:Firebase Storageのアップロードまたはダウンロードメソッドをディスパッチキューにラップする必要はありません。バックグラウンドでネットワーク要求を実行し、メインスレッドのコールバックを上げます(UIを更新できるように)。 –

+0

情報のための@MikeMcDonaldありがとう –

1

は最初の試みのようにコードを変更してみてください:あなたはそれを達成することができます

DispatchQueue.main.async { 
     for loc in self.locations { 
      let imagesStorageRef = FIRStorage.storage().reference().child(loc.avatarPath) 
      imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in 
       if let error = error { 
        print(error.localizedDescription) 
       } else { 
        loc.avatarImage = UIImage(data: data!)! 
        self.tableView.reloadData() 
       } 
      }) 
     } 
} 
+0

すぐにお返事ありがとうございます! :) –

+0

@NG_Locようこそ – ujjwal