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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Swift

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

Q&A

解決済

1回答

3151閲覧

JSONデータをChartsを使ってグラフ表示したい

退会済みユーザー

退会済みユーザー

総合スコア0

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Swift

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

0グッド

0クリップ

投稿2018/12/27 03:39

編集2018/12/27 03:42

前提・実現したいこと

JSONを使ってGoogleスプレッドシートのデータを取得し、それをグラフ表示するiOSアプリ作っています。

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

このページリンク内容を参考にさせてもらい、データの代入部分は自分で作ったJSONデータを取得するクラスに変えて、コンパイルは通るのですが、"Thread 1: signal SIGABRT"のエラーが出てアプリが動きません。
また、横軸の配列の型をDouble型ではなく、String型に変更したいのですが、どうすれば良いのかご教授いただければ幸いです。
以下、当該のソースコードです。

該当のソースコード

/*ViewController.swift*/ import UIKit import Charts class ViewController: UIViewController { var chart: CombinedChartView! var lineDataSet: LineChartDataSet! var bubbleDataSet: BubbleChartDataSet! override func viewDidLoad() { super.viewDidLoad() //combinedDataを結合グラフに設定する let combinedData = CombinedChartData() //結合グラフに線グラフのデータ読み出し combinedData.lineData = generateLineData() //グラフのサイズ設定、座標設定 chart = CombinedChartView(frame: CGRect(x: 0, y: 20, width: self.view.frame.width , height: self.view.frame.height - 20)) //chartのデータにcombinedDataを挿入する chart.data = combinedData //chartを出力 self.view.addSubview(chart) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func generateLineData() -> LineChartData { //リストを作り、グラフのデータを追加する方法(GitHubにあったCombinedChartViewとかMPAndroidChartのwikiを参考にしている //データを入れていく、多重配列ではないため別々にデータは追加していく let values: [Double] = GetFarmData().DateArray let date : [Double] = GetFarmData().TempArray //DataSetを行うために必要なEntryの変数を作る データによって入れるデータが違うため複数のentriesが必要になる? var entries: [ChartDataEntry] = Array() for (i, value) in values.enumerated(){ entries.append(ChartDataEntry(x: date[i], y: value, icon: UIImage(named: "icon", in: Bundle(for: self.classForCoder), compatibleWith: nil))) } //データを送るためのDataSet変数をリストで作る var linedata: [LineChartDataSet] = Array() //リストにデータを入れるためにデータを成形している //データの数値と名前を決める lineDataSet = LineChartDataSet(values: entries, label: "Line chart unit test data") lineDataSet.drawIconsEnabled = false //グラフの線の色とマルの色を変えている lineDataSet.colors = [NSUIColor.red] lineDataSet.circleColors = [NSUIColor.red] //上で作ったデータをリストにappendで入れる linedata.append(lineDataSet) //データを返す。 return LineChartData(dataSets: linedata) } }
/*GetFarmData/swift*/ import UIKit class GetFarmData { struct FarmData : Codable{ var Date : [String] var Temp : [Double] } var DateArray:[String] = [] var TempArray:[Double] = [] func GetData() { let UrlString = "https://script.googleusercontent.com/macros/echo?user_content_key=Ay52NkEmsTwP9m_g-4Nv7bfyqPzORn1CtkPpDI45PJKbmJkTErIIrLunc4oeUQRCd5toyTRnpgETSjloFsDHd0HfqGkKwZ5dm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnLoHBjeqZZOS6uDdoVZbaErJG4ILXd2YeBoAJC8FsHjBLhCJb1CRC6P4G-VDNPWQFw&lib=Mt8YZ4DmL8BZYB77Ydcy6Qd3x1ejDTiej" //WebアプリのURL if let url = URL(string: UrlString){ URLSession.shared.dataTask(with: url) { data, response, error in if let data = data{ do{ let FarmInfo = try JSONDecoder().decode(FarmData.self, from: data) DispatchQueue.main.async { self.DateArray = FarmInfo.Date self.TempArray = FarmInfo.Temp } }catch let error{ print(error) print(data) } } }.resume() } // Do any additional setup after loading the view, typically from a nib. } }

試したこと

普通のDouble型配列の代入はできたのですが、JSONから引っ張ってきたデータを代入することができません。
DateArrayに関してはString型なので、エラーが出るのは当然なのですが、Double型の配列にして実行した時でも、最初に述べた"Thread 1: signal SIGABRT"のエラーが出てしまいます。
また、GetFarmData.swiftのDateArrayとTempArrayにわざわざ一度代入しなくてもできるような気がするのですが、どうなのでしょうか。
お手数ですが、ご回答いただけると幸いです。よろしくお願いします。

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

Xcode 10.1
Swift4

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

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

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

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

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

takabosoft

2018/12/27 08:52 編集

ちょっと気がかりなのですが、ソース中にuser_content_keyのキーが含まれているようですが、これって他人に使われても大丈夫なキーですか?もし情報漏えいしているようなら質問自体の削除依頼を出したほうが良いです(編集しても編集履歴に残るので)問題無ければ無視してください。
guest

回答1

0

ベストアンサー

まだこちらの回答を探しているようならですが、
いくつかのブロックに分けて考えてみましょう。

1。jsonのファイルの読み取り、
2。データの作成
3。グラフへの表示

用意したDouble型配列の代入はグラフにできるということは、
1→2において、どこかに問題があるのではないですか?
自分が用意したDouble型配列と、jsonファイルを読み取ったものの配列に
違いがないか、printで表示して、確認してみてください。

投稿2019/01/02 02:45

hameji001

総合スコア639

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

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

退会済みユーザー

退会済みユーザー

2019/01/04 09:41

返信が遅くなってしまい申し訳ありません。 ご回答ありがとうございます。 ご指摘の通り、JSONファイルを受け取っている間にデータの作成が行われていました。 JSOファイルを受け取っている間データ作成を待つような処理をしなければならないことがわかったのですが、どのように書けばいいのかわからず、困っております。 よろしければ、それについてもご教授していただけないでしょうか?
hameji001

2019/01/04 09:57

JSONファイルは、ネットからDLしている?とかですかね? 通常使うべきセオリーとしては、非同期処理(JSONのDL、分解とか)の時に必要となる、 GCD(Grand Central Dispatch)というものです。 使い方は下記参照。概念はググってもっと調べてみてください。 https://qiita.com/shtnkgm/items/d9b78365a12b08d5bde1 しかし、自分にはGCDの概念?がまだ完全理解できていなくて、 自分はこのGCDを使ってない(使い切れていない)です。 (きっと使えれば便利なんだろうなといつも思っていますが。。。) 苦肉の策として使用しているのが、 変数+定数を一つずつ追加して、回数を数える方法です。 例えば、MapKitのMKLocalSearchや、 Firebase/FirestoreからのDLデータが 全部DLされてからの処理をしたい場合、 はじめに全部のデータの個数を定数に保存。 繰り返し文(for)などでデータを分解して、処理していく際に その回数を変数でカウントして、 最初に取得した全体の個数に達した時を条件にif文を作成し、 完了のタイミングを取得しています。 どうでしょう?きっと、そんなの邪道だ、GCDを使えと 怒られそうな気もしますが、自分はそうしてます。 ご参考までに。。。
退会済みユーザー

退会済みユーザー

2019/01/08 05:48

ご回答ありがとうございます! 教えていただいたページなどを参考にしながらやったところ思った動作ができるようになりました。 DispatchQueue.main.asyncのところをDispatchSemaphoreを使うことでできました。 ご丁寧に教えていただき本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問