jammyman34
jammyman34

Reputation: 1409

How to query realm swift for a specific object

Edited to simplify my question...

I'm new to Realm and so far, it's pretty cool, but I'm having an extremely hard time figuring out how to querying my Realm DB to check if a specific item exists in it.

Here's my Realm Model:

import Foundation
import RealmSwift

class ChartCount: Object{

    dynamic var date: Date = Date()
    dynamic var count: Int = Int(0)
}

In my main ViewController I'm storing a series of ChartCount objects for the 7 days of the current week using the following function:

// function to check if this weeks days have been created in Realm DB yet and creates them if not
    let realm = try! Realm()
    lazy var visitors: Results<VisitorCount> = { self.realm.objects(VisitorCount.self)}()
    let startOfWeekDate = Date().startOfWeek(weekday: 1)
    let nextDay = 24 * 60 * 60

    var startOfWeek = try! Realm().objects(VisitorCount.self)

func setThisWeeksDays(){
            if charts.count == 0 {
                try! realm.write() {


                    let defaultVisitorDates = [startOfWeekDate, startOfWeekDate + TimeInterval(nextDay), startOfWeekDate + TimeInterval(nextDay*2), startOfWeekDate + TimeInterval(nextDay*3), startOfWeekDate + TimeInterval(nextDay*4), startOfWeekDate + TimeInterval(nextDay*5), startOfWeekDate + TimeInterval(nextDay*6)]

                    for visitors in defaultChartrDates {
                        let newChartDate = ChartCount()
                        newChartDate.date = visitors
                        self.realm.add(newChartrDate)
                    }
                }

                visitors = realm.objects(ChartCount.self)
            }
        }

And this to create the StartOfWeekDate

// Finds the start/end of the current week ----------------------------------------------- //
extension Date {
    func startOfWeek(weekday: Int?) -> Date {
        var cal = Calendar.current
        var component = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
        component.to12am()
        cal.firstWeekday = weekday ?? 1
        return cal.date(from: component)!
    }

    func endOfWeek(weekday: Int) -> Date {
        let cal = Calendar.current
        var component = DateComponents()
        component.weekOfYear = 1
        component.day = -1
        component.to12pm()
        return cal.date(byAdding: component, to: startOfWeek(weekday: weekday))!
    }

    func monthDay() -> String? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMM dd"
        return dateFormatter.string(from: self)
    }
}
internal extension DateComponents {
    mutating func to12am() {
        self.hour = 0 + 24
        self.minute = 0
        self.second = 0
    }

    mutating func to12pm(){
        self.hour = 0
        self.minute = 0
        self.second = 0
    }
}// </end> Finds the start/end of the current week ------------------------------------------ //

All I want to do is check the 'date' column of my ChartDate model to see if there is an object in it that contains the first day of this week (e.g. startOfWeekDate).

Upvotes: 5

Views: 17033

Answers (3)

Matjan
Matjan

Reputation: 3607

For anyone looking to access Realm objects by Primary Key (Like I was) here's the code:

let specificPerson = realm.object(ofType: Person.self, forPrimaryKey: myPrimaryKey)

Upvotes: 4

jammyman34
jammyman34

Reputation: 1409

OK, I think I've got it working. This is what I did:

To check if the Realm DB has the startOfWeekDate record I created this function:

func searchForStartOfWeek(findDate: Date) -> ChartCount?{
        let predicate = NSPredicate(format: "date = %@", findDate as CVarArg)
        let dateObject = self.realm.objects(ChartCount.self).filter(predicate).first

        if dateObject?.date == findDate{
            return dateObject
        }
        return nil
    }

Then I used it to check if it exists:

func setThisWeeksDays(){
        if searchForStartOfWeek(findDate: startOfWeekDate) == nil {
            try! realm.write() {


                let defaultChartDates = [startOfWeekDate, startOfWeekDate + TimeInterval(nextDay), startOfWeekDate + TimeInterval(nextDay*2), startOfWeekDate + TimeInterval(nextDay*3), startOfWeekDate + TimeInterval(nextDay*4), startOfWeekDate + TimeInterval(nextDay*5), startOfWeekDate + TimeInterval(nextDay*6)] // 3

                for charts in defaultChartDates {
                    let newChartDate = ChartCount()
                    newChartDate.date = charts
                    self.realm.add(defaultChartDates)
                }
            }

            visitors = realm.objects(ChartCount.self)
        }
    }

Thanks for everyones help!

Upvotes: 0

Josh Homann
Josh Homann

Reputation: 16327

You cannot access Realm in the initializer, but you already have the answer in your code. Make start of week lazy just like you have for visitors and it will not be initialized until its used, and by the time your init is done. This is the way most of the realm examples are done.

lazy var startOfWeek: Result<ChartCount> = {
    return realm.objects(ChartCount.self).filter("date = 'startOfWeekDate'")
}()

Alternatively you can make start of week an implicitly unwrapped optional and initialize it in viewDidLoad or just make it a regular optional

var startOfWeek: Result<ChartCount>!
...
//ViewDidLoad
realm.objects(ChartCount.self).filter("date = 'startOfWeekDate'")

Upvotes: 2

Related Questions