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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

2085閲覧

Firebase × TableViewCell データ読み取り時にエラーが発生する

wakebear

総合スコア15

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/03/10 10:48

編集2018/03/11 03:51

みなさまいつもありがとうございます。

表題のエラーについて質問させてください。
Firebaseと接続し、アップロードしたデータをCellに表示するコードを
サイトを参照して作成しました。

ビルド時に以下のエラーがでてしまい、原因がさっぱりわかりません。。
どなたか分かる方いらっしゃいますでしょうか?

以下がエラーです。
イメージ説明

コードは以下の通りに記述しています。

swift4

1import UIKit 2import Firebase 3 4 5class ListViewController: UIViewController { 6 7 @IBOutlet weak var tableView: UITableView! 8 9 //Fetchしたデータを入れておく配列。この配列をTableViewで表示する 10 var contentArray: [DataSnapshot] = [] 11 12 //FetchしたSnapshotsを格納する変数 13 var snap: DataSnapshot! 14 15 //Firebaseのルートを宣言する 16 var ref = Database.database().reference() 17 18 //変更したいデータのための変数、CellがタップされるselectedSnapに値が代入される 19 var selectedSnap: DataSnapshot? 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 24 self.read() 25 26 //TableViewCellをNib登録、カスタムクラス作成 27 tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "ListCell") 28 29 tableView.delegate = self 30 tableView.dataSource = self 31 32 } 33 34 override func viewWillAppear(_ animated: Bool) { 35 super.viewWillAppear(animated) 36 37 //画面が現れるときに、Cellの高さを調節する 38 tableView.estimatedRowHeight = 80 39 tableView.rowHeight = UITableViewAutomaticDimension 40 41 } 42 43 override func viewDidDisappear(_ animated: Bool) { 44 super.viewDidDisappear(animated) 45 46 //画面が消えたときに、Firebaseのデータ読み取りのObserverを削除しておく 47 ref.removeAllObservers() 48 } 49 50 override func didReceiveMemoryWarning() { 51 super.didReceiveMemoryWarning() 52 53 } 54 55 56 @IBAction func didSelectAdd(_ sender: Any) { 57 transition() 58 } 59 60 func transition() { 61 performSegue(withIdentifier: "toView", sender: self) 62 } 63 64 65 func read() { 66 //DataEventTypeを.Valueにすることにより、なにかしらの変化があった時に、実行 67 //今回はChildでユーザーIDを指定することで、ユーザーが投稿したデータの一つ上のChildまで指定することになる 68 ref.child((Auth.auth().currentUser?.uid)!).observe(.value, with: {(snapShots) in 69 if snapShots.children.allObjects is [DataSnapshot] { 70 //いくつのデータがあるかプリント 71 print("snapShots.children...(snapShots.childrenCount)") 72 73 //読み込んだデータをプリント 74 print("snapShots...(snapShots)") 75 76 self.reload(snapShots) 77 } 78 }) 79 } 80 81 //読み込んだデータは最初すべてのデータが一つにまとまっているので、それらを分割して、配列に入れる 82 func reload(_ snap: DataSnapshot) { 83 if snap.exists() { 84 print(snap) 85 //DataSnapShotが存在するか確認 86 contentArray.removeAll() 87 //一つになっているDataSnapShotを分割し、配列に入れる 88 for item in snap.children { 89 contentArray.append(item as! DataSnapshot) 90 } 91 //ローカルのデータベースを更新 92 ref.child((Auth.auth().currentUser?.uid)!).keepSynced(true) 93 //テーブルビューをリロード 94 tableView.reloadData() 95 } 96 } 97 98 //timestampで保存されている投稿時間を、年月日へと表示形式を変換する 99 func getDate(number: TimeInterval) -> String { 100 let date = Date(timeIntervalSince1970: number) 101 let formatter = DateFormatter() 102 formatter.dateFormat = "yyyy/MM/dd HH:mm" 103 return formatter.string(from: date) 104 } 105 106 //選択されたCellの番号を引数に取り、contentArrayからその番号の値を取り出し、selectdSnapに代入 107 //その後遷移する 108 func didSelectRow(selectedIntdexPath indexPaht: IndexPath) { 109 //ルートからのChildをユーザーのIDに指定 110 //ユーザーIDからのChildを選択されたCellのデータのIDに指定 111 self.selectedSnap = contentArray[indexPaht.row] 112 self.transition() 113 } 114 115 //Cellがタップされると呼ばれる 116 //上記のdidSelectにタップされたCellの値のIndexPathを渡す 117 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 118 self.didSelectRow(selectedIntdexPath: indexPath) 119 } 120 121 122 123 124} 125 126 127 128extension ListViewController: UITableViewDataSource { 129 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 130 return contentArray.count 131 } 132 133 //返すセルを決める 134 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 135 let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell")as! CustomTableViewCell 136 //配列の該当のデータをitemという定数に代入 137 let item = contentArray[indexPath.row] 138 //itemの中身を辞書型に変換 139 let content = item.value as! Dictionary<String, AnyObject> 140 //contentという添字で保存していた投稿内容を表示 141 cell.contentLabel.text = String(describing: content["content"]!) 142 //dateという添字で保存していた投稿時間をtimeという定数に代入 143 let time = content["date"] as! TimeInterval 144 //getDate関数を使って、時間をtimestampから年月日に変換して表示 145 cell.postDateLabel.text = self.getDate(number: time/1000) 146 147 return cell 148 } 149} 150 151extension ListViewController:UITableViewDelegate { 152 153}

データ生成は別のファイルで以下の通り記述します。

Swift4

1 self.ref.child((Auth.auth().currentUser?.uid)!).childByAutoId().setValue(["user": (Auth.auth().currentUser?.uid)!, 2 "content": text, 3 "date": ServerValue.timestamp()]) 4 5 self.transionToView()

大変長く申し訳ありません(;_;)

追記

申し訳ありません!!
以下がビルド時にでてくるエラーの内容と
スクリーンショットです。

Swift4

1calls to begin/end appearance transitions for <UINavigationController: 0x7ff778813200>. 2snapShots.children...14 3snapShots...Snap (xpGOjrV8ePPFm12G96tiNtN282F2) { 4 "-L741ruh-2V5Jc8JyihY" = { 5 content = 1857; 6 date = 1520503062341; 7 user = xpGOjrV8ePPFm12G96tiNtN282F2; 8 }; 9 "-L743BfY6nS3KD5hdZwV" = { 10 content = 1903; 11 date = 1520503409530; 12 user = xpGOjrV8ePPFm12G96tiNtN282F2; 13 }; 14 "-L74aGpB6OUKVzghP_OQ" = { 15 content = 2132; 16 date = 1520512343532; 17 user = xpGOjrV8ePPFm12G96tiNtN282F2; 18 }; 19 "-L74jJXou71InYselPRO" = { 20 content = 2211; 21 date = 1520514713941; 22 user = xpGOjrV8ePPFm12G96tiNtN282F2; 23 }; 24 "-L74loFVdOKupZ5Q3LmW" = { 25 content = aaa; 26 date = 1520515368123; 27 user = xpGOjrV8ePPFm12G96tiNtN282F2; 28 }; 29 "-L77Q67_aY9XtULPTZgn" = { 30 content = 1042; 31 date = 1520559747771; 32 user = xpGOjrV8ePPFm12G96tiNtN282F2; 33 }; 34 "-L77_uPjeDYSkcxOUp8k" = { 35 content = aa; 36 date = 1520562579310; 37 user = xpGOjrV8ePPFm12G96tiNtN282F2; 38 }; 39 "-L77dJj0EfKRmtr-7us6" = { 40 content = "\U305f\U306a\U306f\U3086\U306b"; 41 date = 1520563473497; 42 user = xpGOjrV8ePPFm12G96tiNtN282F2; 43 }; 44 "-L77gtf6L9gHG2wVWcjT" = { 45 content = "\U306b"; 46 date = 1520564411235; 47 user = xpGOjrV8ePPFm12G96tiNtN282F2; 48 }; 49 "-L7EEAGShGhvObA5CqhT" = { 50 content = "\U3042"; 51 date = 1520674186946; 52 user = xpGOjrV8ePPFm12G96tiNtN282F2; 53 }; 54 "-L7EGT9GrEYrINh6a44w" = { 55 content = t; 56 date = 1520674661202; 57 user = xpGOjrV8ePPFm12G96tiNtN282F2; 58 }; 59 content = "\U306d\U306f"; 60 date = 1520502494403; 61 user = xpGOjrV8ePPFm12G96tiNtN282F2; 62} 63Snap (xpGOjrV8ePPFm12G96tiNtN282F2) { 64 "-L741ruh-2V5Jc8JyihY" = { 65 content = 1857; 66 date = 1520503062341; 67 user = xpGOjrV8ePPFm12G96tiNtN282F2; 68 }; 69 "-L743BfY6nS3KD5hdZwV" = { 70 content = 1903; 71 date = 1520503409530; 72 user = xpGOjrV8ePPFm12G96tiNtN282F2; 73 }; 74 "-L74aGpB6OUKVzghP_OQ" = { 75 content = 2132; 76 date = 1520512343532; 77 user = xpGOjrV8ePPFm12G96tiNtN282F2; 78 }; 79 "-L74jJXou71InYselPRO" = { 80 content = 2211; 81 date = 1520514713941; 82 user = xpGOjrV8ePPFm12G96tiNtN282F2; 83 }; 84 "-L74loFVdOKupZ5Q3LmW" = { 85 content = aaa; 86 date = 1520515368123; 87 user = xpGOjrV8ePPFm12G96tiNtN282F2; 88 }; 89 "-L77Q67_aY9XtULPTZgn" = { 90 content = 1042; 91 date = 1520559747771; 92 user = xpGOjrV8ePPFm12G96tiNtN282F2; 93 }; 94 "-L77_uPjeDYSkcxOUp8k" = { 95 content = aa; 96 date = 1520562579310; 97 user = xpGOjrV8ePPFm12G96tiNtN282F2; 98 }; 99 "-L77dJj0EfKRmtr-7us6" = { 100 content = "\U305f\U306a\U306f\U3086\U306b"; 101 date = 1520563473497; 102 user = xpGOjrV8ePPFm12G96tiNtN282F2; 103 }; 104 "-L77gtf6L9gHG2wVWcjT" = { 105 content = "\U306b"; 106 date = 1520564411235; 107 user = xpGOjrV8ePPFm12G96tiNtN282F2; 108 }; 109 "-L7EEAGShGhvObA5CqhT" = { 110 content = "\U3042"; 111 date = 1520674186946; 112 user = xpGOjrV8ePPFm12G96tiNtN282F2; 113 }; 114 "-L7EGT9GrEYrINh6a44w" = { 115 content = t; 116 date = 1520674661202; 117 user = xpGOjrV8ePPFm12G96tiNtN282F2; 118 }; 119 content = "\U306d\U306f"; 120 date = 1520502494403; 121 user = xpGOjrV8ePPFm12G96tiNtN282F2; 122} 123Could not cast value of type '__NSCFString' (0x10edf4168) to 'NSDictionary' (0x10edf51a8). 1242018-03-11 12:46:54.596560+0900 Everest-Project[90064:696323] Could not cast value of type '__NSCFString' (0x10edf4168) to 'NSDictionary' (0x10edf51a8). 125(lldb)

イメージ説明

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

black_sleepman

2018/03/10 16:08

エラーが起きた際に、コンソール部に詳細なエラー文が表示されていると思いますが、スクリーンショットなどはありますか?
wakebear

2018/03/11 03:54

ありがとうございます。詳細なエラー内容を追記いたしました。キャストができない・・とあります。実際のところ、最初はこのコードのままでもビルドできていました。Firebase Database上から直接Chilld配下の要素を消した後にビルドしたらエラーがでてしまいました。。
guest

回答2

0

もう解決されているかもしれませんが、補足で回答します。

ログを拝見したところ、取得したデータの内容に一部おかしなところがあります。

snapShots...Snap (xpGOjrV8ePPFm12G96tiNtN282F2) { // このあたりはobject(SwiftでいうDictionary)形式なので、問題ありません "-L741ruh-2V5Jc8JyihY" = { content = 1857; date = 1520503062341; user = xpGOjrV8ePPFm12G96tiNtN282F2; }; ...(省略) // ここに、object形式ではないデータが入っています content = "\U306d\U306f"; date = 1520502494403; user = xpGOjrV8ePPFm12G96tiNtN282F2; }

この場合、↑のcontentにあたるsnapshotへとアクセスすると、snapshot.valueは "\U306d\U306f" なのでDictionary型ではなくString型が返ります。なので無理やりDictionary型へとキャストしようとした際にクラッシュします。

おそらく作業中に誤って混入したデータなどだと思いますので、データを確認し不要なら削除した上で再実行してみてください。

投稿2018/03/15 16:50

kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wakebear

2018/04/18 07:34

遅くなりすみません!追記頂きありがとうございます。String型のデータが誤って混入してしまった結果、Dinctionary型へキャストする処理でクラッシュした、ということですね。助かります。
wakebear

2018/04/18 07:34

遅くなりすみません!追記頂きありがとうございます。String型のデータが誤って混入してしまった結果、Dinctionary型へキャストする処理でクラッシュした、ということですね。助かります。
guest

0

ベストアンサー

Could not cast value of type '__NSCFString' (0x10edf4168) to 'NSDictionary' (0x10edf51a8).

となっているので、

//itemの中身を辞書型に変換

let content = item.value as! Dictionary<String, AnyObject>

この部分原因だと思われます。item.valueの型を確認してみてください。

投稿2018/03/11 12:29

black_sleepman

総合スコア220

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wakebear

2018/03/19 05:46

なるほど!!ありがとうございます。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問