首页 > 解决方案 > 照片上传到 Firebase 数据库和存储,但不在应用程序中保存照片

问题描述

所以我有一个编辑个人资料页面,用户可以在其中更改他们的个人资料图片和封面照片。一旦用户选择了他们的图像,我就将它带到了哪里,他们单击保存按钮并将照片上传到 Firebase 数据库和 Firebase 存储,然后编辑配置文件视图控制器被解除并返回到配置文件视图。我遇到的唯一问题是,虽然照片上传到 Firebase,但如果我关闭并重新打开它,它不会将图像保存在应用程序上。我不确定我缺少什么来实现这一点。下面是代码:

import UIKit
import Foundation
import Firebase
import FirebaseDatabase

class NewEditProfileViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var imageView1: UIImageView!
    @IBOutlet weak var imageView2: UIImageView!

    var ref = DatabaseReference.init()

    var imagePicker = UIImagePickerController()
    var imagePicked = 0

    var selectedImage1: UIImage?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.ref = Database.database().reference()
        self.saveFIRData()
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        imagePicker.allowsEditing = true


    }


    @IBAction func chooseImage1(_ sender: Any) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
            imagePicked = (sender as AnyObject).tag
            present(imagePicker, animated: true)
        }

        }

    @IBAction func chooseImage2(_ sender: Any) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
            imagePicked = (sender as AnyObject).tag
                present(imagePicker, animated: true)
    }

    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let pickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
        let pickedImage2 = info[UIImagePickerController.InfoKey.editedImage] as? UIImage

        if imagePicked == 1 {
            self.imageView1.image = pickedImage
        } else if imagePicked == 2 {
            self.imageView2.image = pickedImage2
        }
        dismiss(animated: true)
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true)
    }

@IBAction func saveButton(_ sender: Any) {
    self.saveFIRData()
    self.dismiss(animated: true, completion: nil)
    }

    @IBAction func backButton(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
        }
    @objc func saveFIRData() {
        guard let image = imageView1.image else { return }

        self.uploadProfileImage(image){ url in

            self.saveProfileImage(profileURL: url!){ success in
                if success != nil{
                    print("yes")
                }
            }
        }
    }
}

extension NewEditProfileViewController {


    func uploadProfileImage(_ image:UIImage, completion: @escaping (_ url: URL?)->()) {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let storageRef = Storage.storage().reference().child("users/\(uid)")
        let imageData = imageView1.image?.jpegData(compressionQuality: 0.8)
        let metaData = StorageMetadata()
        metaData.contentType = "image/jpeg"
        storageRef.putData(imageData!, metadata: metaData) { (metaData, error) in
            if error == nil{
                print("success")
                storageRef.downloadURL(completion: { (url, error) in
                    completion(url)
                })
            }else{
                print("error in save image")
                completion(nil)
            }
        }
    }


    func saveProfileImage(profileURL:URL, completion: @escaping ((_ url: URL?) -> ())){
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let databaseRef = Database.database().reference().child("users/profilePhotoURL/\(uid)")
        let userObject = [
            "photoURL": profileURL.absoluteString
        ] as [String:Any]

        self.ref.child("users").child(uid).setValue(userObject)
        }
    }

标签: iosswiftfirebasefirebase-storage

解决方案


正如我在您的功能 func saveProfileImage(profileURL:URL, completion: @escaping ((_ url: URL?) -> ())) 代码中的代码中看到的下载图像丢失,您必须更新您的saveProfileImage以支持下载然后保存到本地应用程序目录。

func saveProfileImage(profileURL:URL, completion: @escaping ((_ url: URL?) -> ())){
    guard let uid = Auth.auth().currentUser?.uid else { return }
    let databaseRef = Storage.storage().reference().child("users/profilePhotoURL/\(uid)")

    // Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes), Change it according to your need
    storageRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
      if let error = error {
        // Uh-oh, an error occurred!
      } else {
        // Save `data` to your local directory here
        let imageFilename = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/" + "\(uid).jpg"
        data.write(toFile: imageFilename, atomically: true) 
      }
    }

    let userObject = [
        "photoURL": profileURL.absoluteString
    ] as [String:Any]

    self.ref.child("users").child(uid).setValue(userObject)
    }
}

请参阅以下从 Firebase 指南下载到文件“在 iOS 上下载文件”页面上的本地部分的示例代码。

// Create a reference to the file you want to download
let islandRef = storageRef.child("images/island.jpg")

// Create local filesystem URL
let localURL = URL(string: "path/to/image")!

// Download to the local filesystem
let downloadTask = islandRef.write(toFile: localURL) { url, error in
  if let error = error {
    // Uh-oh, an error occurred!
  } else {
    // Local file URL for "images/island.jpg" is returned
  }
}

我希望它会有所帮助:)


推荐阅读