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

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

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

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

Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

Xcode

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

Swift

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

Q&A

解決済

2回答

1377閲覧

Firestoreからのデータの取得を待ってから値を渡したい

swifty

総合スコア38

Firebase

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

Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2019/06/23 06:47

編集2019/06/30 13:29

前提・実現したいこと

Firestoreから取得したデータを使ってグラフを描写できるようにしたいと考えております。
自分で作った仮データであれば問題なく描画できるのですがFirestoreから取得したデータを使ってグラフの描画をすることができかねる状況です。

completionの中のrecordDataArrayを確認したところFirestoreから取得したデータが適切な形でセットできているのですが、これらの値を先頭部分のcreateDataによりlastTwoRecordsに渡すことができかねます。ご教授何卒よろしくお願いいたします。

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

警告①Constant 'lastTwoRecords' inferred to have type '()', which may be unexpected 警告②Expression of type '[RecordData]' is unused エラー③Value of tuple type '()' has no member 'map'

completionからrecordDataArrayを渡す際にデータがなくなってしまっているようなのはわかるのですが、どう対応すれば適切なデータのまま渡せるのかがわかりかねます。ご教授何卒よろしくお願い致します。

該当のソースコード

import Foundation import Macaw import Firebase import FirebaseFirestore class ChartView: MacawView { // 最下部のコメントアウトしてある仮データ+中部でコメントアウトされているcreateData() + 以下コメントアウトされているcreateData()を使えば問題なくグラフ描写は可能 // static let lastTwoRecords = createData()       // ここで警告①が表示される static let lastTwoRecords = createData { (recordDataArray) in      // ここで警告②が表示される return recordDataArray } static let maxValue = 20 static let maxValueinHeight = 20 static let lineWidth: Double = 385 static let dataDivisor = Double(maxValue/maxValueinHeight)    // ここでエラー③が表示される static let adjustedData: [Double] = lastTwoRecords.map({ Double($0.score) / dataDivisor }) static var animations: [Animation] = [] required init?(coder aDecoder: NSCoder) { super.init(node: ChartView.createChart(), coder: aDecoder) backgroundColor = .clear } // 〜グラフ描写のための長い記述が続くため中略〜 // private static func createData() -> [RecordData] { private static func createData(completion: @escaping (_ recordDataArray: [RecordData]) -> Void) { let todayDate = Date() let dateFormatter = DateFormatter() dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "y/M/d", options: 0, locale: Locale.current) let editedTodayDate = dateFormatter.string(from: todayDate) let calendar = Calendar.current let yesterday = calendar.date(byAdding: .day, value: -1, to: calendar.startOfDay(for: todayDate)) let editedYesterday = dateFormatter.string(from: yesterday!) dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "M/d", options: 0, locale: Locale.current) let editedTodayDateDisplay = dateFormatter.string(from: todayDate) let editedYesterdayDisplay = dateFormatter.string(from: yesterday!) var todayScore: Int16 = 0 var yesterdayScore: Int16 = 0 let db = Firestore.firestore() let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext var recordDataArray: [RecordData] = [] let dispatchGroup = DispatchGroup() let docRefToday = db.collection("recordData").whereField("recordDate", isEqualTo: editedTodayDate).order(by: "savedTime", descending: true) dispatchGroup.enter() docRefToday.getDocuments { (snapshot, error) in if snapshot?.documents.first?.data() == nil { todayScore = 0 dispatchGroup.leave() } else { todayScore = Int16((snapshot?.documents.first?.data()["score"]! as! NSString).integerValue) dispatchGroup.leave() } } let docRefYesterday = db.collection("recordData").whereField("recordDate", isEqualTo: editedYesterday).order(by: "savedTime", descending: true) dispatchGroup.enter() docRefYesterday.getDocuments { (snapshot, error) in if snapshot?.documents.first?.data() == nil { yesterdayScore = 0 dispatchGroup.leave() } else { yesterdayScore = Int16((snapshot?.documents.first?.data()["score"]! as! NSString).integerValue) dispatchGroup.leave() } } dispatchGroup.notify(queue: .main) { let newRecordDataOne = RecordData(context: context) newRecordDataOne.recordDate = editedYesterdayDisplay newRecordDataOne.score = yesterdayScore recordDataArray.append(newRecordDataOne) let newRecordDataTwo = RecordData(context: context) newRecordDataTwo.recordDate = editedTodayDateDisplay newRecordDataTwo.score = todayScore recordDataArray.append(newRecordDataTwo)         completion(recordDataArray) } // 仮データ // let newRecordDataOne = RecordData(context: context) // newRecordDataOne.recordDate = editedYesterdayDisplay // newRecordDataOne.score = 18 // recordDataArray.append(newRecordDataOne) // // let newRecordDataTwo = RecordData(context: context) // newRecordDataTwo.recordDate = editedTodayDateDisplay // newRecordDataTwo.score = 15 // recordDataArray.append(newRecordDataTwo) // return recordDataArray } }

試したこと

Firestoreからのデータの取得が完了してからデータを渡す必要があるため

①NSCondition
②NotificationCenter
③DispatchSemaphore
④Completion Handler
⑤DispatchGroup

の3つを始め様々な方法を試しましたがどれも望んだ結果が得られませんでした。

補足情報(FW/ツールのバージョンなど)

Swift 5.0.1
Xcode 10.2.1
Firestore

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

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

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

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

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

guest

回答2

0

自己解決

こちらの問題に関して無事解決することができました。

どう解決したかについてはもう1つ別に質問させていただいておりました以下の質問部分に記述させていただきました。

「クラスのプロパティを通信処理で得た値を使って定義する方法」
https://teratail.com/questions/197932

投稿2019/07/02 13:51

swifty

総合スコア38

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

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

0

completion で戻り値がないことが問題ではないでしょうか?
Voidの部分を配列の型にしてみては?

投稿2019/07/02 07:37

fathy

総合スコア254

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

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

swifty

2019/07/02 13:41

ご回答ありがとうございます。 そちらの問題ではありませんでした。 只今自分なりに格闘していて無事解決しました。 ポイントになったのはStoryboardを使わずコードで実装するUIViewのサブクラスの生成でした。
swifty

2019/07/02 13:49

申し訳ございません!こちらの質問に関してこちらが初期のものでもう1つ新たに質問をさせていただいておりましてそちらへの回答をしておりました。 Completionに関しては最終的には以下の記述でうまく挙動させることができました。 static func createData(completion: @escaping ([RecordData]) -> Void) { } ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問