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

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

ただいまの
回答率

87.49%

Realmのfilterが上手くいかない

解決済

回答 1

投稿

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

score 42

前提・実現したいこと

FScalendarを使って、カレンダーアプリを作っています。Realmに保存したイベントと日付をその日付がタップされたらセルにイベントが表示されるようにしたいです。

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

filterを使わずに、var result = realm.objects(Schedule.self)と書くと全て保存されたデータが(違う日付に保存されたデータも)表示されてしまいます。なので、filterを用いてvar result = realm.objects(Schedule.self).filter("duedate == '\(da)'")と書いてみたのですが、何も表示されません。

filter部分が上手くいっていないと思うのですが、どう書いたらいいのかよく分かりません。もし、教えていただけたらありがたいです。ちなみに、Realmの方にはちゃんと保存されています。

該当のソースコード

import UIKit
import RealmSwift

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var task: UITextField!

    @IBOutlet weak var goal: UITextField!

    @IBOutlet weak var duedate: UITextField!

    var datePicker: UIDatePicker = UIDatePicker()

    override func viewDidLoad() {
        super.viewDidLoad()

        dateselector()
        task.delegate = self
        goal.delegate = self
        duedate.delegate = self

        let realm = try! Realm()
        print(Realm.Configuration.defaultConfiguration.fileURL!)



    }

    func dateselector () {

        //ピッカー設定
        datePicker.datePickerMode = UIDatePicker.Mode.date

        datePicker.timeZone = NSTimeZone.local

        datePicker.locale = Locale(identifier: "ja-JP")


        //バーの設定
        let toolbar = UIToolbar()
        toolbar.sizeToFit()

        let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

        let todaybtn = UIBarButtonItem(title: "今日", style: .plain, target: nil, action: #selector(today))

        let donebtn = UIBarButtonItem(title: "完了", style: .done, target: nil, action: #selector(done))

        toolbar.setItems([flexibleSpace,todaybtn,donebtn], animated: true)

        duedate.inputView = datePicker
        duedate.inputAccessoryView = toolbar

    }
    @objc func today() {
        datePicker.date = Date()

        let formatter = DateFormatter()

        formatter.dateFormat = "yyyy年M月dd日"

        duedate.text = "\(formatter.string(from:Date()))"
    }

    @objc func done() {
        duedate.endEditing(true)

        //日付のフォーマット
        let formatter = DateFormatter()

        formatter.dateFormat = "yyyy年M月dd日"

        duedate.text = "\(formatter.string(from: datePicker.date))"


    }


    @IBAction func save (_sender:Any){

        if task.text!.count > 0 && (goal.text?.count)! > 0 && (duedate.text?.count)! > 0 {

        let realm = try! Realm()

        try! realm.write {
            let rel = [Schedule(value:["task":task.text!,"goal":goal.text!,"duedate":duedate.text!])]

            realm.add(rel)

            self.performSegue(withIdentifier: "toCalendar", sender: nil)

        }
    }
}

}
import UIKit
import FSCalendar
import CalculateCalendarLogic
import RealmSwift


class CalenderViewController: UIViewController, FSCalendarDelegate, FSCalendarDataSource, UITableViewDelegate, UITableViewDataSource, FSCalendarDelegateAppearance, UIGestureRecognizerDelegate {


    var CalendarArray = [Schedule]()

    var selectedText: String?

    @IBOutlet weak var tableView : UITableView!

    @IBOutlet weak var calendar : FSCalendar!


    override func viewDidLoad() {
        super.viewDidLoad()

        //tableView.tableFooterView = UIView()
        calendar.delegate = self

        calendar.dataSource = self

        tableView.delegate = self

        tableView.dataSource = self


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

    //表示する個数
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return CalendarArray.count

    }

    //セルがタップされた場合
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        print("\(indexPath.row)番目の行が選択されました.")



    }

    //表示する内容
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(13)
        //dequeueReusableCellとは、使い回し
        let cell = tableView.dequeueReusableCell(withIdentifier: "goalCell", for: indexPath)

        cell.textLabel?.text = CalendarArray[indexPath.row].task

        return cell

    }

    //データ取得

    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {

        print("hey there!")
        let tmpDate = Calendar(identifier: .gregorian)
        let year = tmpDate.component(.year, from: date)
        let month = tmpDate.component(.month, from: date)
        let day = tmpDate.component(.day, from: date)

        print("\(year)/\(month)/\(day)")
        let da = "\(year)/\(month)/\(day)"

        let realm = try! Realm()

        var result = realm.objects(Schedule.self)

        //var result = realm.objects(Schedule.self).filter("duedate == '\(da)'")

        CalendarArray.removeAll()

        for a in result {
            CalendarArray.append(a)
        }

        tableView.reloadData()

}
import Foundation
import RealmSwift

class Schedule: Object {

    @objc dynamic var task = ""

    @objc dynamic var goal = ""

    @objc dynamic var duedate = ""

}

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

Xcode version 10.1
Swift version 4.2.1

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

#1 filterの書式

「realm filter」でググりました。

filter("duedate == %@", da)

ref.
Realmでfilterの検索条件に変数を利用するには

#2 日付の形式

保存時の形式yyyy年M月dd日と、filter時の形式\(year)/\(month)/\(day)が違うので、同じ日付であってもfilterの条件に引っ掛かりません。同じ形式に統一して下さい。

例えば今日の場合だと、2019年4月18日2019/4/18という二つの文字列を比較することになります。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/18 10:10

    フォーマットを変更したらできました!ありがとうございます!

    キャンセル

  • 2019/04/18 11:38

    解決したのなら、「受付中」のまま放置せずに、「解決済」「ベストアンサー」を設定してください。

    キャンセル

  • 2019/04/18 11:59

    選ばれてしまったので吸収しておきました。

    キャンセル

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

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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