2

I am writing an app using Swift 4. This apps first gets the current device time and puts it in a label (currentTimeLabel) in the format HH:mm.

It also gets a time in a different timezone from a firebase database as a String and puts this in two labels (currentSharedTimeLabel and timeReceivedFromServerLabel), also in the format HH:mm. The data retrieved from the server also includes the seconds. Clearly, this second time is not changing – but I want it to behave like the user would expect a time to behave, i.e. I want to add to the server time one second every second.

To achieve this, I first change the shared time from a string to a formatted time using this code:

let isoDate = timeReceivedFromServerLabel.text
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
let mathDate = dateFormatter.date(from: isoDate!)

I then want to run a function, which adds a second every second to mathDate and puts the result in the currentSharedTimeLabel. Can you give me an idea on how to achieve this?

At the moment, and it is totally not working out, I am doing:

for i in 0..<1314000 {
    let j = i + 1
    print(i, j)

    let newCalcTime = mathDate?.addingTimeInterval(TimeInterval(j))
    currentSharedTimeLabel.text = ("\(newCalcTime)")
    print("\(String(describing: newCalcTime))")

I am a bit lost intellectually on this one and I would appreciate any help.

(I hope I have made my issue clear and don't upset you with lacking or superficial information).

Edit 2: Code of Database observer (after update of Cocoapods)

// SUBMIT BUTTON
    let submitAction = UIAlertAction(title: "Submit", style: .default, handler: { (action) -> Void in
        let textField = alert.textFields![0]
        self.enterSharingcodeTextfield.text = textField.text

        // SEARCHES FOR SHARING CODE IN DATABASE (ONLINE)
        let parentRef = Database.database().reference().child("userInfoWritten")

        parentRef.queryOrdered(byChild: "sharingcode").queryEqual(toValue: textField.text).observeSingleEvent(of: .value, with: { snapshot in

            print(snapshot)

            // PROCESSES VALUES RECEIVED FROM SERVER
            if ( snapshot.value is NSNull ) {

                // DATA WAS NOT FOUND
                // SHOW MESSAGE LABEL
                self.invalidSharingcodeLabel.alpha = 1

            } else {

                // DATA WAS FOUND
                for user_child in (snapshot.children) {
  • Why are you formatting it with `HH:mm:ss`? Didn't you say that it is in the format of `HH:mm`? Do you want to display the seconds or not? If you don't, then adding a minute every minute is fine, right? – Sweeper Sep 17 '17 at 12:32
  • @Sweeper It comes from the server as a string in the format “07:30:22”, so with seconds. I did this to be able to perform the “add-1-second-every-second”-calculation properly. In the label where the final, calculated, time is shown to the user, it should preferably just show HH:mm. –  Sep 17 '17 at 12:36

1 Answers1

1

I think it sounds like a great use case for a Timer.

Say you have your current time converted in seconds stored in a currentTimeInSeconds variable.

You can update its value every time the view controller appears, and then update its value locally using a timer, until the user leaves the view controller, which would give the impression to the user that it works like an "actual" clock.

So you have your timer defined at the top within the scope of your class :

var timer = Timer()

You could initialize the timer in your viewDidAppear like so:

timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)

which would call your updateTimer() method every second :

func updateTimer() {
    currentTimeInSeconds += 1
}

The only thing that you need to do then is to convert the currentTimeInSeconds to a time in hh:mm:ss and you should be good to go !

Alternatively you could also use the Date's addTimeInterval() method to increment directly your Date by one second within your updateTimer() method, depending on when (if) you want to convert the NSNumber you get from Firebase Database to a Date or not.

Also don't forget to invalidate the timer when the user leaves the view controller (viewDidDisappear) :

timer.invalidate()
  • I am afraid I am overseeing something. I initiated the timer but in the `updateTimer() function`, it tells me that _"Binary operator '+=' cannot be applied to operands of type 'Date?' and 'Int'"_. –  Sep 17 '17 at 13:26
  • This is because you cannot add an int (aka 1) to your date. If you want to increment 1 second to your date directly, then you would need to do : mathDate?.addTimeInterval(1.0) and it would be just fine :) –  Sep 17 '17 at 13:41
  • Otherwise if you get your current time as an NSNumber from Firebase, then you would instead use yourTimeInSeconds.intValue += 1 which would work as well. –  Sep 17 '17 at 13:42
  • Thank you! However, now in the console only `2000-01-01 19:27:29 +0000` appears over and over again (every second a new line). The second was only added once, the time received from the firebase Database was 19:27:28. :( –  Sep 17 '17 at 20:29
  • I see! Could you please show me the code where you add the database observer ? –  Sep 17 '17 at 22:23
  • Sure – I added it to the question! Thanks a mil already for your help! –  Sep 17 '17 at 22:29
  • Hmm it seems like you forgot to add a part of your method ! Also, I can see that you're using "FIRDatabase". With the new syntax of Firebase it should be "Database" instead, don't you get an error when trying to build the project ? –  Sep 17 '17 at 22:40
  • No, no error… it retrieves data correctly and populates everything to labels. In the beginning, I am declaring also declaring `var refUserInfo:FIRDatabaseReference!` –  Sep 17 '17 at 22:41
  • Do you use Firebase with Cocoapods ? While the problem may no be directly related, you may want to update your pods as well :) –  Sep 17 '17 at 22:48
  • For your problem, I will create a test project to check –  Sep 17 '17 at 22:49
  • I can't thank you enough for your generous help, Alex! :) _Edit:_ yes, I indeed used Cocoapods and I updated them right now. I will tell you if/what that changed. –  Sep 17 '17 at 22:50
  • I just created a project for you to see how you could achieve what you want :) Just let me know if you have any questions ! In order to test the project you will need to add your own GoogleService-Info.plist file though ! https://www.dropbox.com/s/kdgswmb4swj76u6/StackOverflowTestProject.zip?dl=0 –  Sep 17 '17 at 23:45