Swift: извлечение данных из Firebase и отображение в виде таблицы - PullRequest
0 голосов
/ 27 июня 2018

Я делаю приложение, которое имеет новостную ленту изображений (HomeViewController). Пользователь может нажать на каждое изображение, которое переходит к SiteViewController , который имеет табличное представление пустых данных, и кнопку, при нажатии которой происходит переход к ContextSheetViewController , где пользователь может загрузить данные изображения что они нажали в ленте новостей. Затем пользователь нажимает кнопку загрузки, и эти данные ( siteCodeTextView , areaCodeTextView, trenchTextView) сохраняются в firebase и удаляются обратно в SiteViewController. Затем я хочу получить значение данных siteCodeTextView , которое только что было загружено из изображения в табличном представлении SiteViewController. Но когда я нажимаю кнопку Upload в ContextSheetViewController, возникает ошибка: Неожиданно обнаружен ноль при развертывании необязательного значения . И мой sheetId печатает ноль в SiteViewController, поэтому я не уверен, как правильно его получить? Любая помощь?

Вот моя раскадровка соответствующих контроллеров представления:

enter image description here

Код для SiteViewController:

class SiteViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!


    var sheets = [Sheet]()
    var users = [User]()
    var sheetId: String!

    var postId: String!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource = self
        loadSheets()

        print(postId)
        print(sheetId)
    }
    func loadSheets() {
        Api.Sheet.REF_SHEETS.child(self.postId!).observe(.childAdded, with: {
            snapshot in
            Api.Sheet.observeSheets(withSheetId: snapshot.key, completion: {
                sheet in
//                self.fetchUser(uid: sheet.uid!, completed: {
                    print("sheet id: \(sheet.id)")
                    print("sheet uid: \(sheet.uid)")
                self.sheets.append(sheet)
                self.tableView.reloadData()
//                })
            })
        })
    }

    func fetchUser(uid: String, completed:  @escaping () -> Void ) {

        Api.User.observeUser(withId: uid, completion: {
            user in
            self.users.append(user)
            completed()
        })
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SheetSegue" {
            let sheetVC = segue.destination as! SheetViewController
            let sheetId = sender as! String
            sheetVC.sheetId = sheetId

        }
    }
}

extension SiteViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sheets.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SheetCell", for: indexPath) as! SiteTableViewCell
        let sheet = sheets[indexPath.row]

        print("sheet id: \(sheet.id)")
        print("sheet uid: \(sheet.uid)")
//        let user = users[indexPath.row]
//        cell.user = user
        cell.sheet = sheet
        cell.delegate = self
        return cell
    }
}

extension SiteViewController: SiteTableViewCellDelegate {
    func goToSheetVC(sheetId: String) {
        performSegue(withIdentifier: "SheetSegue", sender: sheetId)

    }
}

Код для ContextSheetViewController:

class ContextSheetViewController: UIViewController {


    @IBOutlet weak var siteCodeTextView: UITextField!
    @IBOutlet weak var areaCodeTextView: UITextField!
    @IBOutlet weak var trenchTextView: UITextField!
    @IBOutlet weak var uploadArtefactImage: UIImageView!

    @IBOutlet weak var artefactImageView: UIImageView!

    var selectedImage: UIImage?
    var postId: String!
    override func viewDidLoad() {
        super.viewDidLoad()
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleSelectPhoto))
        uploadArtefactImage.addGestureRecognizer(tapGesture)
        uploadArtefactImage.isUserInteractionEnabled = true

    }

    @objc func handleSelectPhoto() {
        let pickerController = UIImagePickerController()
        pickerController.delegate = self
        present(pickerController, animated: true, completion: nil)
    }

    @IBAction func uploadButton_TouchUpInside(_sender: Any) {

        if let profileImg = self.artefactImageView.image, let imageData = UIImageJPEGRepresentation(profileImg, 0.1) {
            let photoIdString = NSUUID().uuidString
            print(photoIdString)
            let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("sheets").child(photoIdString)
            storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
                if error != nil {
                    ProgressHUD.showError(error!.localizedDescription)
                    return
                }
                let photoUrl = metadata?.downloadURL()?.absoluteString
                self.sendDataToDatabase(photoUrl: photoUrl!)
            })
        } else {
            ProgressHUD.showError("Sheet Image can not be empty!")
        }
    }

    func sendDataToDatabase(photoUrl: String) {
//        let ref = Database.database().reference()
        let sheetsReference = Api.Sheet.REF_SHEETS
//        let sheetsReference = ref.child("sheets")
        let newSheetId = sheetsReference.childByAutoId().key
        let newSheetReference = sheetsReference.child(newSheetId)
        guard let currentUser = Auth.auth().currentUser else {
            return
        }
        let currentUserId = currentUser.uid
        newSheetReference.setValue(["uid": currentUserId, "photoUrl": photoUrl, "siteCodeTextView": siteCodeTextView.text!, "areaCodeTextView": areaCodeTextView.text!, "trenchTextView": trenchTextView.text!], withCompletionBlock: {
            (error, ref) in
            if error != nil {
                ProgressHUD.showError(error!.localizedDescription)
                return
        }
            let postSheetRef = Api.Sheet.REF_SHEETS.child(self.postId!).child(newSheetId)
//            let postSheetRef = Api.Sheet.REF_SHEETS.child("post-sheets").child(self.postId).child(newSheetId)
            postSheetRef.setValue(true, withCompletionBlock: { (error, ref) in
                if error != nil {
                    ProgressHUD.showError(error!.localizedDescription)
                    return
                }
            })


            ProgressHUD.showSuccess("Success")
            self.clean()
            self.navigationController?.popViewController(animated: true)
        })
    }

    func clean() {
        self.siteCodeTextView.text = ""
        self.uploadArtefactImage.image = UIImage(named: "upload")
        self.artefactImageView.image = UIImage(named: "image")
    }
}

extension ContextSheetViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        print("did Finish Picking Media")
        if let image = info["UIImagePickerControllerOriginalImage"] as? UIImage{
            artefactImageView.image = image
//            selectedImage = image
//            uploadArtefactImage.image = image
        }
        dismiss(animated: true, completion: nil)
    }
}

Код для SiteTableViewCell:

protocol SiteTableViewCellDelegate {
    func goToSheetVC(sheetId: String)

}

class SiteTableViewCell: UITableViewCell {


    @IBOutlet weak var profileImageView: UIImageView!
    @IBOutlet weak var siteSheetLabel: UILabel!
    @IBOutlet weak var nameLabel: UILabel!

    var delegate: SiteTableViewCellDelegate?

    var sheet: Sheet? {
        didSet {
            updateView()
        }
    }

    var user: User? {
        didSet {
            setupUserInfo()
        }
    }

    func updateView() {
        siteSheetLabel.text = sheet?.siteCodeTextView

    }


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func setupUserInfo() {
        nameLabel.text = user?.username
        if let photoUrlString = user?.profileImageUrl {
            let photoUrl = URL(string: photoUrlString)
            profileImageView.sd_setImage(with: photoUrl, placeholderImage: UIImage(named: "placeholderImg"))
        }
    }


    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.siteSheetLabel_TouchUpInside))
        siteSheetLabel.addGestureRecognizer(tapGesture)
        siteSheetLabel.isUserInteractionEnabled = true
    }

    @objc func siteSheetLabel_TouchUpInside() {

        print(sheet?.id)

        if let id = sheet?.id{
            delegate?.goToSheetVC(sheetId: id)
        }
    }
    override func prepareForReuse() {
        super.prepareForReuse()
        profileImageView.image = UIImage(named: "placeholderImg")
    }

}

enter image description here

1 Ответ

0 голосов
/ 27 июня 2018

Из того, что вы показали, виновником является postId, вы используете его для извлечения данных из Firebase, и все же вы нигде не показали, каково его значение. Когда пользователь нажимает на изображение, postId не передается в SiteViewController.

В SiteViewController удалите ! и замените его на ?, поместите инициализатор, который будет принимать postID в качестве параметра.

var postId:String?

func initPost(forImage postId: String) {
    self.postId=postId
}

В предыдущем новостном канале VC внутри segue или didSelectForRow (я не знаю, что вы используете для перехода, инициализируйте SiteViewController, поэтому, когда он представлен, он знает, для какого идентификатора нужно извлечь данные.

Еще одна вещь, о которой стоит упомянуть, это то, что вы используете observe, но вы не удаляете наблюдателей.

РЕДАКТИРОВАТЬ: этот ответ был основан на том, что я не знал, как выглядел ваш HomeVC.

     if segue.identifier == "SiteSegue" {
        let siteVC = segue.destination as! SiteViewController
        let postId = sender as! String
        siteVC.postId = postId

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...