0

I am trying to create a timer that counts down so I can implement it to a app I am creating, here is a demo project: https://www.dropbox.com/scl/fo/h6uggyqzpwhxji76dv4ck/h?rlkey=5an6cwpshyft1f9q0y8p8gvk0&dl=0

The error I am facing is that when I change the struct name to something other then ContentView() I get this error:

Error when I rename struct

Error when I rename struct

But if the struct is ContentView() I get no error:

No error when struct name ContentView

No error when struct name ContentView

What can I do so I can name the struct something other then ContentView() and not get any errors (Like if I want to name the struct Timer() what should I do)?

Thanks in advance,

I tried to use a different timer method but could not find/understand any as I am new to swift.

iDeveloper
  • 2,339
  • 2
  • 24
  • 38
jfgjhfgj
  • 13
  • 2
  • 3
    *…something other then ContentView()*. It's the other way round, you can name it anything else but `Timer` because `Timer` is a reserved word – the name already exists – in the `Combine` framework. For example name it `TimerView`. – vadian Aug 20 '23 at 15:03
  • Similar concept https://stackoverflow.com/questions/71698728/textfield-viewmodifier-not-conforming-to-viewmodifier/72363048#72363048 – lorem ipsum Aug 20 '23 at 16:25
  • Please provide enough code so others can better understand or reproduce the problem. – Community Aug 20 '23 at 23:29

1 Answers1

0

What you experience is a "symbol look up" issue.

The symbol "Timer" is already defined in module Foundation.

Now, in fact one can define a language artefact in a module with a symbol which is already used in another module, without conflicts.

There's only one catch: in oder to find the definition of a certain symbol, the compiler needs to "look it up". This can sometimes be ambiguous, in which case you get a compiler error. In your case, the statement

let timer = Timer.publish(every: 1, on: .main, in: .common) .autoconnect()

within a struct "Timer" lets the compiler find the symbol "Timer" from the struct, but not the symbol "Timer" from module "Foundation". So, the compiler gets "confused" and emits an error.

Now, it's entirely possible to use the name "Timer" in your module – you just need to give the compiler a hint where to start the search. So, this can be achieved by giving the compiler (fully) qualified name for the symbol "Timer" in module "Foundation", i.e., you need to prefix the symbol with the module name:

let timer = Foundation.Timer.publish(every: 1, on: .main, in: .common) .autoconnect()

You can extend this concept to local symbols as well, and create a "name space" for your symbols. For the sake of demonstration, below a brief example:

import Foundation

enum TimerFeature {}

extension TimerFeature {

    struct Timer {
        let every: TimeInterval

        let timer = Foundation.Timer  // needs qualified name!
        .publish(
            every: every, 
            on: .main, 
            in: .common
         )
        .autoconnect()
    }

}

Then, you can use your Timer with a fully qualified name to disambiguate the symbol look up for symbol "Timer":

import Foundation

// your Timer:
let myTimer = TimerFeature.Timer(every: 1)  

// Foundation Timer:
let foundationTimer = Timer.publish(
    every: 1, 
    on: .main, 
    in: .common
).autoconnect()   

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67