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

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

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

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

Q&A

0回答

2604閲覧

MessageKitとFirebaseを用いたチャットアプリについて

shisen-t

総合スコア21

Firebase

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

0グッド

0クリップ

投稿2019/07/26 09:26

MessageKitを用いてチャットアプリを作ろうと考えています。
こちらを参考にCloud FireStoreを用いながらデータのやり取りができるように進めています。
func updateViewWhenMessageAdded()のところで「unexpectedly found nil while unwrapping an optional value」エラーが出てしまいます。
ここをコメントアウトした時にInputBarに入力したテキストがFirebaseに送られることは確認できたのですが、取り出すことができずチャットのメッセージを見ることができない状態です。
解決の糸口になるページ等ご存知の方がいらっしゃいましたらご教授頂けると幸いです。

Swift

1class ViewController: MessagesViewController { 2 3 private var ref: Firestore! //Cloud Firestoreの情報を参照 4 private var user: User! //ユーザ情報 5 private var handle: DatabaseHandle! //オブザーバーの破棄を適切にする処理 6 var messageList: [Message] = [] //Message型のオブジェクトの入る配列 7 var sendData: [String: Any] = [:] //Cloud Firestoreに書き込む内容を格納する辞書 8 var readData: [[String: Any]] = [] //Cloud Firestoreからの読み込み 9 var deleteData: [[String: Any]] = [] 10 11 let dateFormatter:DateFormatter = DateFormatter() //日時のフォーマットを管理するもの 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 16 // データベース読み取り 17 self.setupFirebase() 18 19 //データベースを生成して参照情報をインスタンス化 20 ref = Firestore.firestore() //リファレンス(参照)の初期化 21 user = Auth.auth().currentUser //ユーザー認証した現在のユーザーを格納 22 23 24 25 26 //データの扱い 27 messagesCollectionView.messagesDataSource = self as MessagesDataSource 28 //レイアウト 29 messagesCollectionView.messagesLayoutDelegate = self as MessagesLayoutDelegate 30 //ディスプレイ 31 messagesCollectionView.messagesDisplayDelegate = self as MessagesDisplayDelegate 32 //Cellの扱い方 33 messagesCollectionView.messageCellDelegate = self as MessageCellDelegate 34 //文字入力の部分 35 messageInputBar.delegate = self as InputBarAccessoryViewDelegate 36 37 // メッセージ入力が始まった時に一番下までスクロールする 38 scrollsToBottomOnKeyboardBeginsEditing = true // default false 39 // 表示している画面とキーボードの重複を防ぐ 40 maintainPositionOnKeyboardFrameChanged = true // default false 41 42 //DateFormatter()で日付と時刻と地域を指定(今回は日本時間を指定) 43 dateFormatter.dateStyle = .medium 44 dateFormatter.timeStyle = .short 45 dateFormatter.locale = Locale(identifier: "ja_JP") 46 47 } 48 49 50 func setupFirebase() { 51 52 // 最新のデータが追加されるたびに最新データを取得する 53 self.updateViewWhenMessageAdded() 54 } 55 56 57 //Cloud Firestoreに書き込みをする際の処理 58 func sendMessageToFirebase(text: String){ 59 if !sendData.isEmpty {sendData = [:] } //辞書の初期化(送信データの中身がからじゃなければ空にする) 60 61 62 let sendRef = ref.collection("chats").addDocument(data: ["senderName": user?.displayName,//送信者の名前 63 "senderId": user?.uid, //送信者のID 64 "content": text, //送信内容(今回は文字のみ) 65 66 "createdAt": dateFormatter.string(from: Date()),//送信時刻 67 "messageId": messageList //送信メッセージのID 68 ]) 69 70 } 71 72 73 //データベースから読み込んだデータを配列(readData)に格納するメソッド 74 func snapshotToArray(snapshot: DataSnapshot){ 75 //中身を0にする 76 if !readData.isEmpty {readData = [] } 77 //スナップショットとは、ある時点における特定のデータベース参照にあるデータの全体像を写し取ったもの 78 if snapshot.children.allObjects as? [DataSnapshot] != nil { 79 let snapChildren = snapshot.children.allObjects as? [DataSnapshot] 80 //snapChildrenの中身の数だけsnapChildをとりだす 81 for snapChild in snapChildren! { 82 //要素を追加していく 83 //snapChildのvalueに値があったらreadDataに追加していく 84 if let postDict = snapChild.value as? [String: Any] { 85 self.readData.append(postDict) 86 } 87 } 88 } 89 } 90 91 //メッセージの画面表示に関するメソッド 92 func displayMessageHuman() { 93 //メッセージリストを初期化 94 if !messageList.isEmpty {messageList = []} 95 96 for itemHuman in readData { 97 print("Humanitem: (itemHuman)\n") 98 let message = Message( 99 sender: Sender(id: itemHuman["senderId"] as! String,displayName: itemHuman["senderName"] as! String), 100 messageId: itemHuman["messageId"] as! String, 101 sentDate: self.dateFormatter.date(from: itemHuman["createdAt"] as! String)!, 102 kind: MessageKind.text(itemHuman["content"] as! String) 103 ) 104 messageList.append(message) 105 } 106 } 107 108 //メッセージが追加された際に読み込んで画面を更新するメソッド 109 func updateViewWhenMessageAdded() { 110 ref.collection("chats").addSnapshotListener{(snapShot, error) in 111 if let err = error { 112 print("Error getting documents: (err)") 113 } else { 114 for document in snapShot!.documents { 115 print("(document.documentID) => (document.data())") 116 } 117 } 118// value.documentChanges.forEach { 119// diff in 120// if (diff.type == .added) { 121// print("New city: (diff.document.data())") 122// let snapshotValue = diff.document.data() 123// let text = snapshotValue["text"] as! String 124// let name = snapshotValue["name"] as! String 125// let date = snapshotValue["timestamp"] as! Date 126// self.messageList.append(self.sendMessageToFirebase(text: text, sender: name, name: name, date: date)) 127// } 128// if (diff.type == .modified) { 129// print("Modified city: (diff.document.data())") 130// } 131// if (diff.type == .removed) { 132// print("Removed city: (diff.document.data())") 133// } 134// } 135 } 136 137 messagesCollectionView.reloadData() 138 messagesCollectionView.scrollToBottom() 139 140 self.messageList.reverse() 141 142 } 143 144 override func viewWillAppear(_ animated: Bool) { 145 super.viewWillAppear(animated) 146 self.navigationController?.setNavigationBarHidden(false, animated: false) 147 } 148 149 override func viewDidAppear(_ animated: Bool) { 150 self.becomeFirstResponder() // inputバーを再表示 151 } 152 153 override func didReceiveMemoryWarning() { 154 super.didReceiveMemoryWarning() 155 } 156} 157 158 159 160 161

字数制限のため拡張部分のコードは省いています。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問