iOS / Swift - Limiting access to view controllers to once per day - ios

I am fairly new to swift development but i would like to implement limiting access to specified view controllers to once per day, ideally 3am this would reset but 12am is also fine.
How could I implement this?
Thanks in advance for any help.

When you visit the view controller, save the current date to user defaults.
Next time the user clicks a button to get to the view controller, read the saved date. If there is no saved date, or the difference between the saved date and the current date is > 24 hours, allow it.
If the difference is < 12 hours, you need to check to see if the date has changed (for midnight) or if 3 am is between those 2 dates.
To see if the 2 saved Dates are on different days, use the Calendar function isDate(_:inSameDayAs:)
To see if 3 AM has passed since the last time is more complicated. Off the top of my head, I'd probably take the current Date, Date(), and use the function
date(bySettingHour:minute:second:of,matchingPolicy:repeatedTimePolicy: direction:) to create a date for 3 AM today, if it has already passed, and then see if 3AM today is between my saved date and now.

Related

How to handle time-intervals with timezone in iOS/Swift

I am new to this iOS world, trying to learn how to handle dates and time.
Imagine I have a Class Shop. The shop have time-intervals which represent the open and close time for each day of the week.
Some context data (example string from database, GMT Timezone):
Monday: "08:00:00-13:00:00, 15:00:00-18:00:00"
Tuesday:"09:00:00-13:00:00, 15:00:00-19:00:00"
Wednesday: "15:00:00-23:59:59"
Thursday: "00:00:00-08:00:00"
etc..
Monday for example would have to store 2 time-intervals.
My question is how can I store this data (array of DateIntervals? TimeIntervals? or another more suitable class?) in a Class and get the current time to check if the store is opened or not.
The native date format for iOS (and Mac OS) is the Date object. A Date object represents and instant in time, independent of time zone. You then use a DateFormatter to convert a date to a string representation in a particular time zone.
In your case, though, you need to represent timer ranges for days of the week on a variety of different dates.
You should read the Calendar class reference in the Xcode documentation. Of particular interest would be the date(bySetting:value:of:) method, which will let you start from a given date and calculate a new date by changing the value of various date components.
You have a set of time intervals for each day. So you need a way to store, for a given day of the week, one or more time intervals. Your time intervals have a start time and an end time. Each of those needs to be represented by an hour, minute, and optionally second.
With that information you can get the current date/time and split it into components. Get the weekday, hour, minute, and second. Using the weekday you can get the appropriate time intervals. Then you can iterate those intervals and see if the current hour, minute, second falls between one of the intervals.
This all assumes that for a given business, your time intervals (open times) are specified in local time for the given business.
When converting the current date/time into its components, you should ensure that you set the calendar's timezone to match the timezone of the business in question.
There is no need for any date comparisons for any of this. You want to compare hours/minutes/seconds of the current date with the hours/minutes/seconds of the open times.

Get a set of the next 7 given days

I allow teachers to set schedules for days they're working. Saved in the DB with their week days 0..6. Now what I want to achieve is to give a method a date, often todays date and retrieve the next 7 days they'll be able to work. Take note that for example if their TimeSlot only have a week_day column stored as 1 then the 7 next Mondays should be retrieved.
If it's Mondays and Wednesdays then they'll be returned until 7 days have been stored and returned.
Do anybody have experience in how I might handle this. I struggeling with how to find a good solution to iterate over dates.

How to add Data to Firebase?

My goal is to add +1 every day to a global variable in Firebase to track how many days have passed. I'm building an app that give new facts every day, and at the 19:00 UTC time marker, I want the case statement number (the day global day variable) to increment by +1.
Some have suggested that I compare two dates and get the days that have passed that way. If I were to do that, I could hard code the initial time when I first want the app to start at 19:00 some day. Then when the function reached1900UTC() is called everyday thereafter, compare it to a Firebase timestamp of that current time which should be 19:00. In theory, it should show that 1 day or more day has passed.
This is the best solution so far, thanks to #DavidSeek and #Jay, but I would still like to figure it out with concurrent writes if anyone has a solution in that front. Until then, I'm marking David's answer as the correct one.
How would I make it so it can't increase more than +1 if multiple people call this? Because my fear is that, when say, 100 people calls this function, it increases by + 1 for every person that has called it.
My app works on a global time, and this function is called every day at 19:00 UTC. So when that function is called I want the day count to increase by one.
You should use transactions to handle concurrent writes:
https://firebase.google.com/docs/database/ios/read-and-write#save_data_as_transactions
You may know this but Firebase doesn't have a way to auto-increment a counter as there's no server side logic, so having a counter increment at 19:00 UTC isn't going to be possible without interaction from a client that happens to be logged on at that time.
That being said, it's fairly straightforward to have the first user that logs in increment that counter - then any other clients logging in after that would not increment it and would have access to that day's new content.
Take a look at Zapier.com - that's a service that can fire time based triggers for your app which may do the trick.
As of this writing, Zapier and Firebase don't play nice together, however, there are a number of other trigger options that Zapier can do with your app while continuing to use Firebase for storage.
One other thought...
Instead of dealing with counters and counting days, why not just have each day's content stored within a node for each day and when each user logs on, the app get's that days content:
2016-10-10
fact: "The Earth is an Oblate Spheroid"
2016-10-11
fact: "Milli Vanilli is neither a Milli or a Vanilli. Discuss."
2016-10-12
fact: "George Washington did not have a middle name"
This would eliminate a number of issues such as counters, updates, concurrent writing to Firebase, triggers etc.
It's also dynamic and expandable and a user could easily see that day's facts or the fact for any prior day(s)
I'm trying to split your question into different sections.
1) If you want to use a global variable to count the days from, let's say, today. Then I would set a timestamp hardcoded into the App that sets the NSDate.
Then In my App, when I need to know the days that have been passed by, I would call a function counting the days from the timestamp to NSDate().
2) If you have a function in your App that counts a +1 into a Firebase, then your fear is correct. It would count +1 for every person that uses the App.
3) If you want every User to have a variable count since when they use their App, then I would handle User registration. So I have a "UserID" and then I would set a Firebase tree like that:
UserID
------->
FirstOpen
-------> Date
That way you could handle each User's first open.
Then you are able to set a timestamp AND call +1 for every user independently. Because then you set the +1 for every user into their UserID .child

Datetime and Time Zones - OpenERP 7

I'm keeping the current date in a model using a datetime field in which I am indicating default to take the current date as a value.
_defaults = {
'f_inicio' : lambda *a: datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
}
Assuming that the current date is '07/10/2013 17:24:05 ', in the view is the date '07/10/2013 12:24:05' and rectified in the database and the date is '07/10/2013 17:24:05'; gather that this subtracting five hours. The user can set the time zone 'America/Bogota', Colombia is in the region (GTM - 5:00). But do not understand how to properly show when the user since I get a totally different value that should show. Apparently this taking as 'GTM 0' the GTM Colombia. Taking the approximate date create_date field that should have given me as default is '2013-10-07 22:24:05.384'.
Anyone have any idea what may be happening, really appreciate any help on this issue that is driving me crazy.
This drived me too crazy in the past. This is a real simple issue.
The date stored in the database is UTC (GMT-0) timezone. Assume that the person is set with timezone GMT - 5:00, then while storing the value to the database, the date will be added with 5 hrs (exactly 5, not little more or little less) and thus we get the UTC time to store into the database. Now when displaying the same it will check for the users timezone and it finds that its GMT - 5:00 so the database time will be subtracted with 5 (again exactly 5, not little more or little less) and displayed the user.
This will be great for system which is used in different timezones. So the understanding is the input is taken in the user's timezone stored in UTC(GMT-0) and displayed to user's timezone (even if the user viewing is in the different timezone the time will be accurate to their timezone)
Note: if the user is not set with the timezone the browsers timezone is considered and will be used with the warning icon on the top corner
That's it. Hope this gives u better clarity!!

UIdatepicker showing weekdays

I would like to make a datepicker that shows weekdays, date and month.
I got a working datepicker showing month, date and year but I would really like it to show month, day, date
How is this possible? I know I might have to make a custom UIpicker, but how to I make this refer to dates?
You need to create your own picker with a UIPickerView. Create an NSDateFormatter. You can then access the month names and the weekday names from the date formatter. An NSCalendar can be used to obtain the maximum number of days for a month.
The real trick is updating the picker view components as the user selects a value from one of the components. For example, if the user picks a month, you want to update the number of days shown in the day component (or, like a UIDatePicker), grey out invalid days. This is complicated by the fact that you don't have a year so there is no way to properly handle February.
And what do you do when a user picks a given weekday? How should this affect the selected day? Just things to consider.

Resources