前提・実現したいこと
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
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。