teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

微修正

2019/08/20 14:35

投稿

hameji
hameji

スコア1380

answer CHANGED
@@ -36,6 +36,7 @@
36
36
  なぜなら、マネージドオブジェクトの変更なども混ざってくると、
37
37
  どこは外に書いてもOKなのか、
38
38
  どこをwriteの中に書かないといけないのかわかりずらくなると思いますので。
39
+ 全部writeの中に書くようにしておく方が安全だと思います。
39
40
 
40
41
  追伸③
41
42
  イメージがつきやすいようにサンプルを適当に作ってみました。
@@ -53,9 +54,9 @@
53
54
 
54
55
  class GPSPoint: Object {
55
56
  @objc dynamic var tripId: Int = 0
56
- @objc var timestamp: Date = Date()
57
+ @objc dynamic var timestamp: Date = Date()
57
- @objc var longitude: Double = 0.0
58
+ @objc dynamic var longitude: Double = 0.0
58
- @objc var latitude: Double = 0.0
59
+ @objc dynamic var latitude: Double = 0.0
59
60
  }
60
61
  ```
61
62
 
@@ -64,4 +65,8 @@
64
65
  MasterViewでタイ貧乏旅行を押したら、tripId=1をDetailViewにpushする。
65
66
  DetailViewではtripId=1で検索をかけて表示をする
66
67
  こういうのが一般的だと思います。
67
- List<*****>を持たせると、無駄に肥大化したデータを扱わないといけなくなると思います。
68
+ List<*****>を持たせると、無駄に肥大化したデータを扱わないといけなくなると思います。
69
+
70
+ GPXファイルの読み込みも、viewDidLoadや場合によっては違うViewで読み込み、Realmに保存し、
71
+ 表示はTableViewもしくはMapViewで行うのが普通だと思うので、
72
+ 別々の場所になると思いますよ。

4

例を追加

2019/08/20 14:35

投稿

hameji
hameji

スコア1380

answer CHANGED
@@ -32,4 +32,36 @@
32
32
  追伸②、
33
33
  RealmObjectに値を代入する時、アンマネージドオブジェクトならできますが、
34
34
  writeの中で行う方が安全ですよ。
35
- ex) routeItem.route = points とか
35
+ ex) routeItem.route = points とか
36
+ なぜなら、マネージドオブジェクトの変更なども混ざってくると、
37
+ どこは外に書いてもOKなのか、
38
+ どこをwriteの中に書かないといけないのかわかりずらくなると思いますので。
39
+
40
+ 追伸③
41
+ イメージがつきやすいようにサンプルを適当に作ってみました。
42
+ (一部RouteItem, PointsとなっているのをTrip, GPSPointと読み替えてください)
43
+
44
+ ![イメージ説明](522646a022de8f0ce5008e82fd6430a8.png)
45
+ ```swift
46
+ class Trip: Object {
47
+ @objc dynamic var id: Int = 0
48
+ @objc dynamic var name: String = ""
49
+ @objc dynamic var start: Date = Date()
50
+ @objc dynamic var end: Date = Date()
51
+ @objc dynamic var description: String = ""
52
+ }
53
+
54
+ class GPSPoint: Object {
55
+ @objc dynamic var tripId: Int = 0
56
+ @objc var timestamp: Date = Date()
57
+ @objc var longitude: Double = 0.0
58
+ @objc var latitude: Double = 0.0
59
+ }
60
+ ```
61
+
62
+ 例えば、タイ貧乏旅行(id=1)とすると、
63
+ タイ貧乏旅行でのGPSPointは全部tripId = 1で登録する。
64
+ MasterViewでタイ貧乏旅行を押したら、tripId=1をDetailViewにpushする。
65
+ DetailViewではtripId=1で検索をかけて表示をする
66
+ こういうのが一般的だと思います。
67
+ List<*****>を持たせると、無駄に肥大化したデータを扱わないといけなくなると思います。

3

微修正

2019/08/20 14:28

投稿

hameji
hameji

スコア1380

answer CHANGED
@@ -14,7 +14,9 @@
14
14
  それを元にRealm側で検索できるようにする方が便利なのではないかなって思います。
15
15
 
16
16
  目的の最大値の取得ですが、
17
+ ```swift
17
- routeItems = realm.objects(RouteItem.self).filter("id == '******'").sorted(byKeyPath: "latitude").first
18
+ let maxLatitude = realm.objects(Point.self).filter("id == '******'").sorted(byKeyPath: "latitude").first
19
+ ```
18
20
  などで取得できると思います。
19
21
 
20
22
  ちなみに順番はどうするんだという問題に関しては、gpsに記録されているDateを追加し、

2

変更

2019/08/20 05:41

投稿

hameji
hameji

スコア1380

answer CHANGED
@@ -1,20 +1,22 @@
1
- (2)(4)で取得できて、(3)で取得できない理由ははっきりと答えられません
1
+ (2)(4)で取得できて、(3)で取得できない理由は公式文書で記載箇所を確認した訳でないです
2
- 通常は、realmに保存したものを呼び出して使うので、
3
- realm.addの後にそのまま保存前にletで用意したrouteItemを使い続けはないです
2
+ realm.addされると、マネージドオブジェクト(realm側管理るオブジェクト)になり、
3
+ プロパティではなく、辞書型で管理されるってことだと思います。
4
+ なので、管理前(realm.add前)はrouteItem.route[0].latitude(プロパティ)とかけていたのが、
5
+ 途端に書けなくなり、辞書型で管理され、routeItem.route[0]["latitude"](辞書型)で表示となるようです。
4
6
 
5
- なので答えなってないような気もしますが
7
+ しかし保存前letで用意たrouteItemをそのま使い続けることは通常ないので
6
8
  そこを疑問に感じて解決しなくても、登場することはないと思います。
7
9
 
8
- 目的の最大値の取得ですが、
9
- routeItems = realm.objects(RouteItem.self).filter("id == '******'").sorted(byKeyPath: "latitude").first
10
- などで取得できると思います。
11
-
12
10
  RealmのListは使い勝手が少し悪い印象で、
13
11
  SQLなどと違い、RealmObjectのList以下を条件検索とか並び替えが簡単にできないからです。
14
12
 
15
13
  今回の場合は、RouteItemとList<Point>()のPoint**"s"**に共通IDを持たせて、Listを使わず管理し、
16
14
  それを元にRealm側で検索できるようにする方が便利なのではないかなって思います。
17
15
 
16
+ 目的の最大値の取得ですが、
17
+ routeItems = realm.objects(RouteItem.self).filter("id == '******'").sorted(byKeyPath: "latitude").first
18
+ などで取得できると思います。
19
+
18
20
  ちなみに順番はどうするんだという問題に関しては、gpsに記録されているDateを追加し、
19
21
  登録された順番を持たせるといいのではないでしょうか?
20
22
 
@@ -26,6 +28,6 @@
26
28
  private var realm: Realm!と入れ替えを。
27
29
 
28
30
  追伸②、
29
- RealmObjectに値を代入する時、
31
+ RealmObjectに値を代入する時、アンマネージドオブジェクトならできますが、
30
32
  writeの中で行う方が安全ですよ。
31
33
  ex) routeItem.route = points とか

1

情報追加

2019/08/20 05:38

投稿

hameji
hameji

スコア1380

answer CHANGED
@@ -1,4 +1,15 @@
1
+ (2)(4)で取得できて、(3)で取得できない理由ははっきりと答えられませんが
2
+ 通常は、realmに保存したものを呼び出して使うので、
3
+ realm.addの後にそのまま保存前にletで用意したrouteItemを使い続けることはないです。
4
+
5
+ なので、答えになってないような気もしますが、
6
+ そこを疑問に感じて解決しなくても、登場することはないと思います。
7
+
8
+ 目的の最大値の取得ですが、
9
+ routeItems = realm.objects(RouteItem.self).filter("id == '******'").sorted(byKeyPath: "latitude").first
10
+ などで取得できると思います。
11
+
1
- RealmのListは使い勝手が少し悪い印象です。
12
+ RealmのListは使い勝手が少し悪い印象で
2
13
  SQLなどと違い、RealmObjectのList以下を条件検索とか並び替えが簡単にできないからです。
3
14
 
4
15
  今回の場合は、RouteItemとList<Point>()のPoint**"s"**に共通IDを持たせて、Listを使わず管理し、
@@ -12,7 +23,7 @@
12
23
  追伸①、
13
24
  let realm = Realm()は何度も登場するものですし、
14
25
  privateなメンバー変数にしておいた方が便利ですよ。
15
- そうすると、private var realm: Realm!が不要になります
26
+ private var realm: Realm!と入れ替えを
16
27
 
17
28
  追伸②、
18
29
  RealmObjectに値を代入する時、