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

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

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

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

Q&A

0回答

699閲覧

一度は表示されますが再びロードするとUnexpectedly found nilとなります

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

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

0グッド

0クリップ

投稿2021/02/02 09:12

編集2021/02/03 08:43

前提・実現したいこと

MessageKitによるメッセージ機能の実装を実現したいと考えています。最終的にmessagesの中にデータを入れることができれば画面に表示されるだろうと考えており、MessageKitMessageにデータを入れる必要があると考えました。その際initを設定してデータを入れた方がいいのでは無いかと考えました。が、String以外の変数の初期設定?の仕方が分からずつまずきました。

発生している問題・エラーメッセージ

ビルドは成功するのですが以下のようなエラ〜メッセージが表示され、クラッシュします。

Could not cast value of type '__NSCFString' (0x7fff873ff068) to 'MessageKit.MessageKind' (0x10947f828).

as以降に問題があるのでは無いかと考えたのですが、どのように修正をしなければならないのか検討がつきません。

self.kind = dic["kind"] as! MessageKind self.sentDate = dic["senderId"] as! Date

試したこと

as以降の部分にいろんなものを入れたり試したりしました。
他にはinit丸々無くしてやろうとしたのですがオプショナル?の問題で上手くいきませんでした。

用語の定義が自分の中でイマイチ理解できていない部分があり説明が上手くできません。ごめんなさい。

### 一部動くコード

import UIKit import MessageKit import MessageInputBar import InputBarAccessoryView import FirebaseFirestore import FirebaseAuth import FirebaseStorage import Nuke struct Sender: SenderType{ var senderId: String var displayName: String init(dic: [String: Any]){ self.senderId = dic["senderId"] as? String ?? "" self.displayName = dic["displayName"] as? String ?? "" } } struct MessageKitMessage: MessageType{ var sender: SenderType var messageId: String let sentDate: Date var kind: MessageKind // init(dic: [String: Any]){ // // self.sender = Sender(dic: dic) // self.messageId = dic["messageId"] as? String ?? "" // self.kind = dic["kind"] as! MessageKind // self.sentDate = dic["senderId"] as! Date // // // } } class MessageKitChatViewController: MessagesViewController, InputBarAccessoryViewDelegate, MessageInputBarDelegate, MessagesDataSource{ var senderUser = Auth.auth().currentUser! var messages = [MessageType]() // let currentUser = Sender(senderId: Auth.auth().currentUser!.uid, displayName: Auth.auth().currentUser!.displayName ?? "Name not found") var passedId: String! var passedDisplayName: String! var currentUser: Sender! = nil var otherUser: Sender! = nil var passedChatroomId: String! override func viewDidLoad() { super.viewDidLoad() messagesCollectionView.messagesDataSource = self messagesCollectionView.messagesLayoutDelegate = self messagesCollectionView.messagesDisplayDelegate = self messageInputBar.delegate = self // otherUser = Sender(senderId: passedId, displayName: passedDisplayName) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) loadBothUsersInfo { self.loadMessages() } } func loadBothUsersInfo(completion: @escaping () -> Void) { guard let currentUserId = Auth.auth().currentUser?.uid else { return } print("currentUserId") print(currentUserId) print("currentUserId") Firestore.firestore().collection("users").document(currentUserId).getDocument { (snapshot, error) in if error != nil{ print(error) }else{ guard let dic = snapshot?.data() else { return } let user = User(dic: dic) let currentUserName = user.userName // self.currentUser = Sender(senderId: currentUserId, displayName: currentUserName) let dic2 = ["senderId": dic["userId"], "displayName": dic["userName"]] self.currentUser = Sender(dic: dic2 as [String : Any]) } } Firestore.firestore().collection("users").document(passedId).getDocument { (snapshot, error) in if error != nil{ print(error) }else{ guard let dic = snapshot?.data() else { return } let user = User(dic: dic) let otherUserName = user.userName let dic2 = ["senderId": dic["userId"], "displayName": dic["userName"]] self.otherUser = Sender(dic: dic2) } } completion() } func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) { Firestore.firestore().collection("chatRooms").document(passedChatroomId).collection("messages").addDocument(data: ["senderId": currentUser.senderId, "displayName": currentUser.displayName, "messageId": "", "sentDate": Timestamp().dateValue(), "kind": text]) { (error) in if error != nil{ print(error) }else{ print("メッセージの保存、送信が完了") inputBar.inputTextView.text = nil self.messagesCollectionView.reloadData() self.messagesCollectionView.scrollToLastItem() } } } func loadMessages(){ Firestore.firestore().collection("chatRooms").document(passedChatroomId).collection("messages").getDocuments { (snapshots, error) in if error != nil{ print(error) }else{ snapshots?.documents.forEach({ (snapshot) in let dic = snapshot.data() let kind = dic["kind"]! let senderId = dic["senderId"]! let sentDate = dic["sentDate"]! as! Timestamp let convertedSentDate = sentDate.dateValue() let displayName = dic["displayName"]! let messageId = dic["messageId"]! let sender = Sender(dic: dic) let dic2 = ["sender": sender, "messageId": dic["messageId"]!, "sentDate": convertedSentDate, "kind": MessageKind.text(dic["kind"] as! String)] // print("'''''''''''''''") // print(sender) // print("'''''''''''''''") // print(kind) // print(senderId) print("dic2") print(dic2) print("dic2") // print(displayName) // print(messageId) self.messages.append(MessageKitMessage(sender: sender, messageId: messageId as! String, sentDate: convertedSentDate, kind: MessageKind.text(dic["kind"] as! String))) self.messagesCollectionView.reloadData() // self.messagesCollectionView.scrollToLastItem() // MessageKitMessage(sender: sender, messageId: dic["messageId"] as! String, sentDate: dic["sentDate"], kind: dic["kind"]) // self.messages.append(MessageKitMessage(dic: dic)) print("messages") print(self.messages) print("messages") // MessageKitMessage(sender: sender, messageId: dic["messageId"] as! String, sentDate: sentDate as! Date, kind: kind) // let sender = Sender(senderId: senderId!, displayName: displayName!) // if senderId != nil { // if displayName != nil{ // let sender = Sender(senderId: senderId!, displayName: displayName!) // } // // } // Sender(senderId: senderId, displayName: displayName) // self.messages.append(MessageKitMessage(dic: dic)) }) } } } func currentSender() -> SenderType { return currentUser } func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType { return messages[indexPath.section] } func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int { return messages.count } } // //extension MessageKitChatViewController: MessagesDataSource{ // // // func currentSender() -> SenderType { // return currentUser // } // // func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType { // print("000000000000000") // print(messages[indexPath.section].sentDate) // print(messages.count) // print("000000000000000") // return messages[indexPath.section] // } // // func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int { // return messages.count // } // // // // //} extension MessageKitChatViewController: MessagesLayoutDelegate{ } extension MessageKitChatViewController: MessagesDisplayDelegate{ }

上の一部動くコードはチャットルームをクリックした後しっかり動作しチャットメッセージがロードされ表示されるのですが、その後戻るボタンを押してチャットルーム一覧に戻り、同じ部屋をクリックすると

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file

というエラーが

func currentSender() -> SenderType { return currentUser

のreturn currentUserに対して表示され原因が分かりません。

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

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

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

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

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

hoshi-takanori

2021/02/02 19:32

適切な型の値を用意する必要がありますね。 そもそも、init の引数に dic: [String: Any] を渡すのが良くない気がします。
退会済みユーザー

退会済みユーザー

2021/02/03 08:45

お返事ありがとうございます。 上記のコードで一度メッセージの表示に成功するのですが、チャットルームを退出したのちに再び同じ部屋に入るとメッセージが表示されず、クラッシュする新たな症状に直面するようになったのですが、やはり init の引数に dic: [String: Any]を渡しているからなのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問