前提・実現したいこと
http://www.atmarkit.co.jp/ait/articles/1606/06/news020_3.html
上記のページを参考にしてswift3とFirebaseを使ってリアルタイムチャットアプリを作ろうとしています。
ViewContollor.swiftをswift3に対応させようと書き換えたのですが、
Firebaseのデータベースへ書き込みができないのでそれを解決したいと思い質問させていただきました。
cocoapodsを使ってFirebaseとJSQMessageViewControllerを導入し、
シミュレーターのキーボードからFirebaseのデータベースへ書き込みを行おうとしたところエラーが出てしまいました。
googleで調べたところ、ストーリーボードとコードの接続がうまくいっていない時にこのエラーが起こるようなので、
みてみたのですが、ストーリーボードには何もありませんでした。
どうか、ご助力をお願いいたします。
いつもありがとうございます。
PS:ご教授いただいた解決方法を質問の一番下に書いてあります。2016 11/2
発生している問題・エラーメッセージ
Thread 1: signal SIGABRT
該当のソースコード
AppDelegate
import UIKit
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?)
-> Bool {
FIRApp.configure()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
}
ViewControllerSwift
import UIKit
import JSQMessagesViewController
import Firebase
import FirebaseDatabase
class ViewController: JSQMessagesViewController {
var messages: [JSQMessage] = [
JSQMessage(senderId: "Dummy", displayName: "A", text: "こんにちは!"),
JSQMessage(senderId: "Dummy2", displayName: "B", text: "こんにちは♪")
]
override func viewDidLoad() {
super.viewDidLoad()
senderDisplayName = "A"
senderId = "Dummy"
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, messageDataForItemAt indexPath: IndexPath) -> JSQMessageData {
return messages[indexPath.item]
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath) -> JSQMessageBubbleImageDataSource? {
if messages[indexPath.row].senderId == senderId {
return JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImage(
with: UIColor(red: 112/255, green: 192/255, blue: 75/255, alpha: 1))
} else {
return JSQMessagesBubbleImageFactory().incomingMessagesBubbleImage(
with: UIColor(red: 229/255, green: 229/255, blue: 229/255, alpha: 1))
}
}
//cellForItemAtIndexPathのIndexPathを削除、whiteColor()、grayColor()のColor()を削除。
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as? JSQMessagesCollectionViewCell
if messages[indexPath.row].senderId == senderId {
cell?.textView?.textColor = UIColor.white
} else {
cell?.textView?.textColor = UIColor.darkGray
}
return cell!
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath) -> JSQMessageAvatarImageDataSource? {
return JSQMessagesAvatarImageFactory.avatarImage(
withUserInitials: messages[indexPath.row].senderDisplayName,
backgroundColor: UIColor.lightGray, textColor: UIColor.white,
font: UIFont.systemFont(ofSize: 10), diameter: 30)
}
override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
inputToolbar.contentView.textView.text = ""
let ref = FIRDatabase.database().reference()
ref.child("messages").childByAutoId().setValue(
["senderId": senderId, "text": text, "displayName": senderDisplayName])
}
}
補足情報(言語/FW/ツール等のバージョンなど)
Swift3 Xcode8 iOS10
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
+3
解決方法
fromageblancさんに教えていただいた下記のリンクよりbreakpointを設定したことで、原因がFIRDatabaseにあることが分かりました。
http://qiita.com/mono0926/items/bf70c7ef15db046ee163
次に、fuzzballさんより教えていただいたprint("文字列")を挟むデバッグ方法でどこまでコードが通っているのかを特定することができました。
print("A")
let ref = FIRDatabase.database().reference()
print("B")
ref.child("messages").childByAutoId().setValue(
["senderId": senderId, "text": text, "displayName": senderDisplayName])
print("C")
まずはAまで通っていました。
これをBまで通すために
AppDelegate.swiftをswift3に対応させ書き換え、FIRApp.configure()を追加しました。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
//FIRApp.configure()を追加
return true
}
その後、Cまで通すため
setValue(
["senderId": senderId, "text": text, "displayName": senderDisplayName])
に as [AnyHashable:Any]を追加し、
setValue(
["senderId": senderId, "text": text, "displayName": senderDisplayName]as [AnyHashable:Any])
としました。
Firebase側ではNS系のものしか格納出来ないので
ここでNSObjectとして指定する必要がありました。
swift2では [NSObject: AnyObject]
と書いていたものが
swift3では [AnyHashable: Any]
となっています。
以下ページ参照。
http://qiita.com/NemotoTaka/items/565b899dafed4b803a3d
ここまで追加することにより、
無事Firebaseへのデータ書き込みが完了いたしました。
ご教授いただいたfuzzballさま、fromageblancさま、
本当にありがとうございました。
ソースコードの修正部分を下に置いておきます。
AppDelegate.swiftの修正部分
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
//FIRApp.configure()を追加
return true
}
//上記部分をswift3に対応して修正 2016/11/02 1:03
ViewControllerSwiftの修正部分
override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
print("beforeA",text, senderId, senderDisplayName, date)
inputToolbar.contentView.textView.text = ""
print("A")
let ref = FIRDatabase.database().reference()
print("B")
ref.child("messages").childByAutoId().setValue(
["senderId": senderId, "text": text, "displayName": senderDisplayName]as [AnyHashable:Any])
//print文を挟み、どこまでコードが動いているかをコンソールの方へ出力。
//as [AnyHashable:Any]を最後に追加 2016/11/02 1:03
print("C")
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
ストボー以外でもそこで止まることはあります。
というか、落ちる時にここで止まるケースはかなりあります。
この辺参照してもうひと踏み不具合箇所を特定してください。これだけじゃさすがに厳しいです。
http://qiita.com/mono0926/items/bf70c7ef15db046ee163
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.37%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる