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

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

ただいまの
回答率

90.51%

  • Swift

    8752questions

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

  • Realm

    259questions

    RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Realmデータをidで検索したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 272

tatsuya_335

score 1

 前提

現在Realmを使用し、1対多のモデル定義を行い、アプリを作成しております。
旅行の計画を立てるようなアプリです。

下記が1対多のモデル定義になります。

import RealmSwift

class TravelData: Object {
    @objc dynamic var id = 0

    @objc dynamic var date = Date()

    @objc dynamic var travelTitle = ""

    @objc dynamic var departureData = ""

    @objc dynamic var returnData = ""

    @objc dynamic var travelImage = NSData()

    let plansDatas = List<PlanData>()

    let PackingDatas = List<PackingData>()

    let GiftDatas = List<GiftData>()

    let MemoDatas = List<MemoData>()

    override static func primaryKey() -> String? {
        return "id"
    }
}

class PlanData: Object {
    @objc dynamic var scheduleTitle = ""

    @objc dynamic var startTime = ""

    @objc dynamic var endTime = ""

    @objc dynamic var scheduleDate = ""

    @objc dynamic var scheduleImage = NSData()
}


PlanData以外のPackingDataクラスなどは、PlanDataと同じ構成になるので省略しています。

初めに表示されるCollectionViewで計画の一覧を表示しています。
各セルをタップすると画面遷移し、タップした計画のデータ(持ち物リストやスケジュール)が表示される仕組みになります。

 やりたいこと

初めに表示されるCollectionViewでタップした計画(TravelData)に保存されているPlanDataやPackingDataを表示したい。

 発生している問題

実際にタップした対象のTravelDataにPlanData等保存することができたが、データを取得してTableViewに表示させることができない。

 該当のソースコード

初めに表示される計画一覧画面

import UIKit
import RealmSwift

class ViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate {

    @IBOutlet var collectionView: UICollectionView!

    let realm = try! Realm()
    var travelDataArray = try! Realm().objects(TravelData.self).sorted(byKeyPath: "date", ascending: false)

    var planDatas = List<PlanData>()

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.delegate = self
        collectionView.dataSource = self

        collectionView.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "CustomCell")

        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: 157, height: 157)
        collectionView.collectionViewLayout = layout

        layout.sectionInset = UIEdgeInsetsMake(30, 15, 15, 15)


    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return travelDataArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell

        cell.imageView.layer.cornerRadius = 75
        cell.imageView.layer.masksToBounds = true

        let travelData = travelDataArray[indexPath.row]

        cell.titleLabel.text = travelData.travelTitle
        cell.departureDateLabel.text = travelData.departureData
        cell.returnDateLabel.text = travelData.returnData
        cell.imageView.image = UIImage(data: travelData.travelImage as Data)

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        self.planDatas = self.travelDataArray[indexPath.row].plansDatas
        self.performSegue(withIdentifier: "next", sender: nil)
            }


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier != "next" {
     let createViewController: CreateViewController = segue.destination as! CreateViewController
            let travelData = TravelData()

            let allTravelDatas = realm.objects(TravelData.self)
            if allTravelDatas.count != 0 {
                travelData.id = allTravelDatas.max(ofProperty: "id")! + 1
            }
            createViewController.travelData = travelData
        } else if segue.identifier == "next" {
            let scheduleViewController: ScheduleViewController = segue.destination as! ScheduleViewController
            scheduleViewController.planDatas = self.planDatas
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        collectionView.reloadData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


上記のCollectionViewセルをタップ後、スケジュール画面に遷移

import UIKit
import RealmSwift

class ScheduleViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet var tableView: UITableView!

    let realm = try! Realm()

    var planDatas = List<PlanData>()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.planDatas.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ScheduleCell", for: indexPath) as! ScheduleCell

        let planData = planDatas[indexPath.row]
        cell.scheduleTitle.text = planData.scheduleTitle
        cell.startTime.text = planData.startTime
        cell.endTime.text = planData.endTime
        cell.scheduleImage.image = UIImage(data: planData.scheduleImage as Data)

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        tableView.reloadData()
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()


    }

}

 試したこと

コードはあげていませんが、スケジュール追加画面でスケジュールを追加すると、問題なくタップした対象の計画にのみスケジュールを追加することはできています。(Realm studioで確認済)

 困っていること

最初の画面の、
var travelDataArray = try! Realm().objects(TravelData.self).sorted(byKeyPath: "date", ascending: false)
var planDatas = List<PlanData>()
self.planDatas = self.travelDataArray[indexPath.row].plansDatas
上記で、タップした計画のPlanDataクラスを取得できると思っていたんですが、
ScheduleViewにprepareで値を渡しても表示されませんでした。

idで対象のTravelDataを取得してそこに保存されているPlanDataをTableViweに表示できればいいのですが、うまくできませんでした。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

最初のViewでタップしたidを取得して、値を画面遷移時に渡して次のコードでできるようになりました。

let travelData = try! Realm().objects(TravelData.self).filter("id == %@", self.id).last

let travelData = try! Realm().objects(TravelData.self).filter("id == %@", self.id).last
let planDatas = travelData?.plansDatas

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Swift

    8752questions

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

  • Realm

    259questions

    RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。