使用Swift从Firebase存储库检索图像

6

我正在寻找一个完整的代码示例,以从Firebase Storage检索图像,仅显示图像。可以作为图像视图或表格。我已经查看了这里的帖子和各种教程。总感觉缺少某些东西。如果我能看到整个过程,我就能更好地理解它。

附加的代码是我当前尝试将photo1从本地更改为从Firebase Storage获取的代码。

import UIKit
import Firebase
import FirebaseAuth
import FirebaseStorage
import FirebaseDatabase

class MainMenuTableViewController: UITableViewController {



var mainMenu = [Menu]()
var photo1 = UIImage()
override func viewDidLoad() {
    super.viewDidLoad()
    loadMenu()
}

func loadMenu() {

    let storage = FIRStorage.storage()
    // Create a storage reference from the URL
    let storageRef = storage.referenceForURL("https://firebasestorage.googleapis.com/v0/b/medicalpatientapp-7fd45.appspot.com/o/iconimages%2Ffile-medical-icons.png?alt=media&token=c95b9c51-67ae-4e93-b63c-62091015a9ff")
    // Download the data, assuming a max size of 1MB (you can change this as necessary)
    storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
        // Create a UIImage, add it to the array
        let pic = UIImage(data: data!)
        self.photo1 = pic!

    }


   //let photo1 = UIImage(named: "iconimages-file-medical-icons")!
    let menu1 = Menu(name: "My Notes", photo: photo1)!

    let photo2 = UIImage(named: "iconimages-file-medical-icons")!
    let menu2 = Menu(name: "View Patients", photo: photo2)!

    let photo3 = UIImage(named: "iconimages-add-medical-icons")!
    let menu3 = Menu(name: "Add Persons", photo: photo3)!

    mainMenu += [menu1, menu2, menu3]

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return mainMenu.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


    // Configure the cell...
    let cellIdentifier = "MenuTableViewCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MainMenuTableViewCell

    // Fetches the appropriate meal for the data source layout.
    let menu = mainMenu[indexPath.row]

    cell.menuLabel.text = menu.name
    cell.menuImage.image = menu.photo

    return cell
}

}

4个回答

11
我们强烈建议同时使用Firebase Storage和Firebase Realtime Database来实现这一目标。以下是一个完整的示例:

共享:

// Firebase services
var database: FIRDatabase!
var storage: FIRStorage!
...
// Initialize Database, Auth, Storage
database = FIRDatabase.database()
storage = FIRStorage.storage()
...
// Initialize an array for your pictures
var picArray: [UIImage]()

上传:

let fileData = NSData() // get data...
let storageRef = storage.reference().child("myFiles/myFile")
storageRef.putData(fileData).observeStatus(.Success) { (snapshot) in
  // When the image has successfully uploaded, we get it's download URL
  let downloadURL = snapshot.metadata?.downloadURL()?.absoluteString
  // Write the download URL to the Realtime Database
  let dbRef = database.reference().child("myFiles/myFile")
  dbRef.setValue(downloadURL)
}

下载:

let dbRef = database.reference().child("myFiles")
dbRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in
  // Get download URL from snapshot
  let downloadURL = snapshot.value() as! String
  // Create a storage reference from the URL
  let storageRef = storage.referenceFromURL(downloadURL)
  // Download the data, assuming a max size of 1MB (you can change this as necessary)
  storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
    // Create a UIImage, add it to the array
    let pic = UIImage(data: data)
    picArray.append(pic)
  })
})

了解更多信息,请参见从零到应用程序:使用Firebase进行开发以及其相关源代码,以获取如何实现此操作的实际示例。


谢谢。关于下载,是从“myfiles”中拉取所有内容还是需要每个文件都这样做?Firebase存储是否可以单独使用而不需要数据库?我之前看过“从零开始创建应用程序”的帖子,但目前我没有使用它来连接用户配置文件,并且它并不像你的示例那样直截了当。 - AC-X
Firebase Storage旨在独立使用。也就是说,如果与实时数据库一起使用,列出和检索文件会更容易。以下示例将检索存储在数据库位置"myFiles"的所有文件,该位置已由上传到"myFiles/{fileName}"中的文件填充。 - Mike McDonald

6

我强烈推荐使用内置的FirebaseUI函数sd_setImage。它具有内置的缓存功能,比使用存储数据库中的Data表示要快得多。

请确保导入FirebaseUI并将其添加到您的podfile中。

在Swift 4中,

let ref = Database.database().reference()
let uid = Auth.auth().currentUser?.uid
let userRef = ref.child("users").child(uid!)
var myImageView = UIImageView()

userRef.getDocument { (document, error) in
    if let document = document, document.exists {
        let myData = document.data()
        if let profileURL = myData["profileURL"] as? String {
            let storageRef = Storage.storage().reference(forURL: profileURL)
            myImageView.sd_setImage(with: storageRef, placeholderImage: UIImage(named: "placeholder.png"))
        }
        else {
            print("profileURL is nil")
        }
    } 
    else {
        print("Document does not exist")
    }
}

6

1. Swift 4.1从Firebase Storage检索图像 更新“STORAGE”左侧面板firebase选项的规则,仅使用您的应用程序名称:

service firebase.storage {
  match /b/MyApp-201223.appspot.com/o {
    match /{allPaths=**} {
      // Allow access by all users
      allow read, write;
    }
  }
}

2. 在你导入 Firebase 存储的类中创建一个带有回调函数的简单方法:

      func downloadImages(folderPath:String,success:@escaping (_ image:UIImage)->(),failure:@escaping (_ error:Error)->()){
        for i in 0 ..< 194{
            // Create a reference with an initial file path and name
            let reference = Storage.storage().reference(withPath: "\(folderPath)/0.jpg")
            reference.getData(maxSize: (1 * 1024 * 1024)) { (data, error) in
                if let _error = error{
                    print(_error)
                    failure(_error)
                } else {
                    if let _data  = data {
                        let myImage:UIImage! = UIImage(data: _data)
                        success(myImage)
                    }
                }
            }

        }
     }

3. 使用此方法无论您在何处使用:

      self.downloadImages(folderPath: "MyAppImages", success: { (img) in
            print(img)
        }) { (error) in
            print(error)
        }

5

在Swift 3中

    let ref = Database.database().reference()
    let uid = Auth.auth().currentUser?.uid
    let usersRef = ref.child("users").child(uid!)

    // only need to fetch once so use single event
    usersRef.observeSingleEvent(of: .value, with: { snapshot in

        if !snapshot.exists() { return }

        //print(snapshot)

        let userInfo = snapshot.value as! NSDictionary
        print(userInfo)
        print(userInfo["name"]!)
        let profileUrl = userInfo["profilePicUrl"] as! String

        print(profileUrl)
        let storageRef = Storage.storage().reference(forURL: profileUrl)
        storageRef.downloadURL(completion: { (url, error) in
            let data = Data(contentsOf: url!)
            let image = UIImage(data: data! as Data)
            self.profilePic.image = image
        })

这会从存储中下载图像。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接