How to define recurrence events model in Core Data - ios

I am trying to make a Calendar app. I want to persist the events into Core Data. But the situation is like this, if I want to a recurring event like "every day at 6 AM wake me up". How to define this event model in Core Data? And should I calculate the events from now on to like next year, and save all these events back into Core Data, or I just save one event to Core Data but have a recurrence rule set it to like "every day at 6 AM". Is there any tutorial online like this I can learn about?

That depends on how big the application is (how many features does it have).
If it doesn't have much features, then your second idea is the way to go - Just have a flag in your core-data entity of "Recurring" to set it's a recurring event. Load all events from your core-data model and then filter the
recurring events from the normal ones. Now, set up local/remote
notifications based on your logic.
Otherwise, You can create it more abstract with an abstract entity "Event" and some entities that inherit from it like: "Normal Event", "Recurring Event" - Each fulfilling its own logic. That way, when you load the entities from your core-data model, you just fetch every "Event" entity (which will be both normal and recurring) and apply any logic you need.
You can explore some of the projects here to see some calendar application references.

Related

What is your data model for recurrent event?

For instance something like Google Calendar, where we can:
Add simple event
Add recurring event
every week
every monday/tuesday
etc.
Delete an instance of a recurring event
Change all following recurrent event
etc.
I have an events with the primary event "Event#1" for instance and its instances "Event#2" and "Event#3" that have an event_id foreign key to the primary event, e.g. 1
What do you think? Should I use the iCal spec somehow?
Two key things:
Split the event from its schedule.
Split the recurring schedule definition from its individual schedule.
By splitting the event from its schedule, instances of a recurring event can share the same event information like its description and location, while others can use an edited version.
events:
id
name
description
location
...
By splitting the recurring schedule from its individual schedule makes querying for events much simpler.
recurring_event_schedules:
id
event_id
schedule: jsonb
start_at: timestamp with time zone
This is the recurring schedule for an event.
Recurring schedules get complicated. You could have multiple tables for each type of recurring period (annual, biannual, daily, monthly, weekly, etc...) or punt and use jsonb to store the spec. The spec might be { "period": "weekly", "days": [1,2,3,4,5] } for every weekday. Reference the iCal spec and good calendaring software for what sorts of repeat events you'd want and other attributes.
jsonb is not a panacea, but this table is only for reference to generate and update events. It is not used for runtime querying. For that there's a second table.
Then generate individual scheduled events from this, out to a configurable limit.
event_schedules:
id
event_id
recurrent_event_schedule_id
schedule: tztsrange
This table is simple. What event, when, and what recurring schedule it was generated from.
Since you're using Postgres, rather than separate start/end fields, use a timestamp range. These are supported by special operators to determine if a time is inside a range, or if ranges overlap, and so on.
Rails will accept Range types, but it does not directly support the operators. For example, EventSchedule.where("duration #> ?::date", Date.new(2014, 2, 12)) finds all events happening on 2014-02-12.
If you want to edit an individual scheduled event, copy its Event, edit it, and link the EventSchedule to that new Event.
If you want to change the recurring event schedule, select the event_schedules by recurrent_event_schedule_id.
If you want to change the event for all scheduled events, edit the Event linked to the RecurringEventSchedule.
In this way you can define complex recurring events and query the simple concrete events.

Core Data Schema Design

I'm trying to write an iOS application that tracks how much weight your lifting at the gym but I'm struggling to create my Core Data schema. At the moment i have an Exercise Entity that stores info about a specific exercise (e.g. Bicep Curl) and i have a workout Entity that just has a name & image. The workout entity has a many to many relationship with the exercise entity. what i need to incorporate is 'session' functionality - the ability for a user to complete a workout and store the weights he/she lifted in a particular workout. E.g. i want to say that i completed my 'Leg Day' workout and lifted these weights for each exercise. So my Core Data looks like this at the moment.
schema
How would i go about storing the session data? I feel that the session must have a one to one relationship with a workout but that doesn't let me add results for each exercise in the workout... I also think i might need a dictionary to store the weights for each exercise.
Any help would be greatly appreciated as i have never really learnt about databases before.
Thanks
EDIT: Ive changed my schema to look like this
schema2
So, regarding your schema2, in database design it is typically bad practice to have relationships that form a "circle". Also, if an entity only has a single attribute, it could be reduced to an attribute of its parent.
I would probably approach your design a bit differently.
You should split your exercise entity into Exercise and Exercise_History or something similar. Then you would remove any relationship between Session and Workout and have a one to many between Session and Exercise_History.
Also, if Lift only has a single attribute, it probably shouldn't be its own entity.
If you approach it like that, you should get the desired relationships and functionality.

CoreData object modeling with multiple timeframes for weather data

I do have some JSON file http://jsonblob.com/530664b3e4b0237f7f82bdfa I am pulling from forecast.io.
I am little confused how I should be creating my CoreData entities and relationships.
In below setup, I made my Location entity as the parent entity and created a separate entity for Currently, Minutely, Hourly, Daily. However I have decided it's best to hold all the information regarding the weather data in one entity, so I created a Data table for that purpose and tied it to Daily and Currently in the image below.
Before going further, I paused and would like to get a second opinion on it. Is this a valid way of going forward with this?
EDIT: Based on Wain's response I changed my model to this
Currently Minutely and Hourly add little value as they don't have any attributes or relationships. It's also generally easier to add a type attribute rather than having a number of sub entities because you can easily filter the type using a predicate while doing a fetch. If you're going to add more in the future then there could be a case for keeping sub entities.
Once the entities are trimmed down then you only have a Location and Data with a relationship. You should make that relationship bi-directional so that Core Data can manage the data store contents better. (this applies to all relationships, even if you keep the sub entities you already have).
Other than that, fine :-)

Model design for a calendar

I'm building an application that is based on a calendar and (with basic functionality expected from a calendar).
As the calendar will have such a fundamental part of the application I don't want to rely on any gem but build the calendar myself.
I don't know which route to go: to have a day-model representing each day with a unique record (that events can reference by day_id) OR render the calendar "on the fly" based on a Date class (and events would then reference the date).
In short: What model design would be the most efficient to render a calendar?
You don't need to have a model at all. The following code below will do the trick.
Grab the code from https://gist.github.com/RichIsOnRails/5535564 and drop it in a helper, use like so (haml below, so adapt it to meet your own needs.) Note that i'm rendering events in this calendar, but you don't have to.
= calendar #date do |date|
.text-left=date.day
- if #events_by_date[date]
- #events_by_date[date].each do |event|
.event=event.title
I will do an article on my website in the near future that goes over this in detail. Good luck!
Unless there is something specific about the days you would like to model, you may be able to just have an events model, with each event having a date field. This approach is simpler and I think preferable. Since there are a practically infinite number of dates, one big advantage of this approach is that you won't need to manage all the logical inconsistencies of keeping a finite subset of dates in your database.
Even if you find a need for a day model, you can do this without tying the model to the database, and thus avoid having a record in your database for every possible date. This might be useful if you want a method that tells you if a day is a work day, or if you want to find a collection of days. For more on how to make a model that doesn't require a database table behind it, see this stackoverflow question: Tableless model in rails 3.1

Core Data, "sorting by transient property" workaround

Let's say I have a Core Data entity called Event, which represents recurrent (yearly) events. Each Event has a "date" property.
I need to present this events to the user sorted by "next occurrence of date". This property, of course, depends on the current date and as such should be marked as transient: there's no point in storing it in the database.
But, as you know, you can't query sorting by a transient property in Core Data.
Is there a smart way to keep this property transient and still have Core Data sort for me? I don't want to fetch and then sort myself, but I would also like to avoid storing this transient info in the database.
If you store the date in a separate entity, then you can fetch just the dates and sort them yourself however you like. You'd have a relationship from Event to EventDate, and a corresponding inverse relationship that lets you find the Event from a given EventDate.
Suggestion: Specify a sort descriptor in your fetch request so that you get the dates sorted from the beginning of the year. Then all you have to do is locate the current date in the returned array, and move everything before that point to the end of the array.
Make the EventDate->Event relationship to-many, since it might happen that more than one Event falls on the same date. Setting your model up like this gives you the nice property that you can easily answer the question "What events happen on date X?"

Resources