質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.22%

【Swift,Xcode】Firebaseに保存したデータが1つしか表示されない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 420

nekokichi

score 35

Firebaseを使って、テキストと画像を保存し、セルに表示させる機能を実装したいです。

3つの画面で構成されており、
・ログイン
・タイムライン
・投稿画面
の3つです。

上記のうち、投稿画面で問題が生じています。

問題とは、Firebaseにテキストや画像が[String:Any]で複数個も保存されてるのに、セルには1つしか表示されてないことです。

下記がDatabaseの中身で、

イメージ説明

実際に表示されてるのは、上記の真ん中だけです。

イメージ説明

いくら更新を繰り返しても、全く改善されません。

numberOfRowsInSectionの数も、データをまとめた配列データの数を指定してますし、numberOfSectionもreturn 1と記述しました。

なぜ1つしか表示されないのか?

なぜFirebaseのDatabaseにある1つしか取得してないのか?

どうか解決法をお教えいただきたいです。

import UIKit
import SDWebImage
import Firebase

class TimeLineViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    //Postクラスに関連する変数
    var posts = [Post]()
    var posst = Post()

    //refleshのインスタンス
    let reflesh = UIRefreshControl()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        reflesh.attributedTitle = NSAttributedString(string: "更新する")
        reflesh.addTarget(self, action: #selector(update), for: .valueChanged)
        tableView.addSubview(reflesh)

        // Do any additional setup after loading the view.
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        update_Firebase()

        tableView.reloadData()

    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

//        let daytimeLabel = cell.viewWithTag(1) as! UILabel
//        daytimeLabel.text = posts[indexPath.row].daytime

        let categoryLabel = cell.viewWithTag(2) as! UILabel
        categoryLabel.text = posts[indexPath.row].category

        let titleLabel = cell.viewWithTag(3) as! UILabel
        titleLabel.text = posts[indexPath.row].title

        let imageView = cell.viewWithTag(4) as! UIImageView
        let imageURL = URL(string: posts[indexPath.row].pictureURLString as String)!
        imageView.sd_setImage(with: imageURL, completed: nil)
        imageView.clipsToBounds = true

        let sentenceLabel = cell.viewWithTag(5) as! UILabel
        sentenceLabel.text = posts[indexPath.row].sentence


        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 460
    }

    //データ更新メソッドを実行
    @objc func update() {

        //データを更新
        update_Firebase()
        //更新をストップ
        reflesh.endRefreshing()

    }

    //データ更新メソッド
    func update_Firebase() {

        //データベースの参照URL
        let ref = Database.database().reference()

        //post階層のデータをsnapで取り出す
        //データを["???":データの型]で取得する
        ref.child("post").observeSingleEvent(of: .value) { (snap,error) in


            let snapData = snap.value as? [String:NSDictionary]

            if snapData == nil {
                return
            }

            for (_,post) in snapData! {

                self.posts = [Post]()
                self.posst = Post()

                print("表示します")

                if let title = post["title"] as? String, let sentence = post["sentence"] as? String, let pictureURLString = post["pictureURLString"] as? String, let category = post["category"] as? String {

                    print("表示されます") //ここは通ります。

                    self.posst.title = title
                    self.posst.sentence = sentence
                    self.posst.pictureURLString = pictureURLString
                    self.posst.category = category

                    //Databaseにあるデータを全て表示してくれてます。
                    print("\(self.posst.title), \(self.posst.sentence), \(self.posst.pictureURLString), \(self.posst.category)")

                }

                self.posts.append(self.posst)

            }

            self.tableView.reloadData()

        }


    }

}
import UIKit
import SDWebImage
import Firebase

class ShareViewController: UIViewController,UITextFieldDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextViewDelegate {

    //アルバムで選択した画像のURL
    var url = String()

    @IBOutlet weak var titleField: UITextField!
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var textView: UITextView!
    @IBOutlet weak var categoryField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    @IBAction func albumPicker(_ sender: Any) {
        let sourceType:UIImagePickerController.SourceType = UIImagePickerController.SourceType.photoLibrary

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
            let cameraPicker = UIImagePickerController()
            cameraPicker.sourceType = sourceType
            cameraPicker.delegate = self
            self.present(cameraPicker, animated: true, completion: nil)

        }
    }

    // 撮影が完了時した時に呼ばれる
    @objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        if let pickedImage = info[.originalImage] as? UIImage {

            imageView.image = pickedImage

        } else {

            print("画像を設定できませんでした。")

        }

        //カメラ画面(アルバム画面)を閉じる処理
        picker.dismiss(animated: true, completion: nil)

    }

    //投稿ボタン
    @IBAction func postButton(_ sender: Any) {

        //Firebaseにデータを保存する
        let rootRef = Database.database().reference(fromURL: "https://miniblogfirebase.firebaseio.com/").child("post").childByAutoId()
        //ストレージの参照URL
        let storageRef = Storage.storage().reference(forURL: "gs://miniblogfirebase.appspot.com")
        let key = rootRef.key
        let imageRef = storageRef.child("Users").child("\(key).jpg")

        var data = NSData()

        if let image = imageView.image {
            data = image.jpegData(compressionQuality: 0.01)! as NSData
            print("圧縮されました")
        }

        let uploadTask = imageRef.putData(data as Data, metadata: nil) { (metaData, error) in

            if error != nil {
                print("画像のエラーです")
                return
            } else {

                imageRef.downloadURL(completion: { (url, error) in

                    if url != nil {

                        let feed = ["title":self.titleField.text ?? "title",
                                    "sentence":self.textView.text ?? "sentence",
                                    "pictureURLString":url?.absoluteString ?? "url",
                                    "category":self.categoryField.text ?? "category"] as [String:Any]

                        rootRef.setValue(feed)

                    } else {
                        print("投稿できませんでした")
                    }

                })

            }

        }

        uploadTask.resume()
        dismiss(animated: true, completion: nil)

    }

    //キーボードを閉じる処理
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        titleField.resignFirstResponder()
        categoryField.resignFirstResponder()
        textView.resignFirstResponder()
    }

    @IBAction func backButton(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }



}
import UIKit

class Post: NSObject {

    var title = String()
    var sentence = String()
    var pictureURLString = String()
    var daytime = String()
    var category = String()

}

デバッグの結果

引用![イメージ説明fc5d17dc8ebab5e18f796cb14bd6b76a.png)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

            for (_,post) in snapData! {

                self.posts = [Post]()
                self.posst = Post()

ループの内側で毎回 posts配列を作ってるからでは?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる