1

I have the next scenario :

I have created a Swift package that I am using in a main application. In this Swift Package I want to use some colors because it's an UI package. My struct Colors is already defined in my main application and I don't want to define it again in the package so I am trying to send my struct Colors to the package.

Also my struct Colors have another struct General in it like:

struct Colors {
     struct General {
          static let mainColor = "5F8E3F".toColor
     }
}

This is how I call it in my package:

func setupContent(withMainStruct mainStruct: Colors) {
    print(mainStruct.General.mainColor)
}

This is how I send it from main application:

let mainStruct = ColorStruct()
cell.setupContent(withMainStruct: mainStruct)

My main problem is:

Static member 'General' cannot be used on instance of type 'Colors'

Is there any way to do this?

All I want is to use the values of the struct, I don't need to update any of it.

poPaTheGuru
  • 1,009
  • 1
  • 13
  • 35
  • 2
    Why not simply use `Colors.General.mainColor` why even bother to create an instance of Colors in first place? Error is pretty clear, you can not access static properties from an instance, so avoid it, access it directly through `Colors.General.mainColor` I am not really sure of your use case but looking at the way the structures are nested and has a static let seems you could take a better approach :| – Sandeep Bhandari Nov 09 '21 at 06:27
  • I've edited the post with how i send it and how i call it because i want the struct to be used in my `package` and the value to be sent from the `main application` – poPaTheGuru Nov 09 '21 at 07:06
  • If you need to send it as a value, it needs to be a value all the way, that is Colors must have a property of type General. That said it feels like there should be a better solution to this, more in the line with the first comment. – Joakim Danielson Nov 09 '21 at 07:32

1 Answers1

2

Sounds like you want to define a protocol in your Package which is fulfilled by a struct in your App. So you can just provide these predefined values to the package.

So something like this.

In the App:

struct AppColors: Colors {
    let general: GeneralColors = General()

    struct General: GeneralColors {
        let mainColor = UIColor.blue
     }
}

configLib(colors: AppColors())

In the Package

protocol Colors {
    var general: GeneralColors { get }
}

protocol GeneralColors {
    var mainColor: UIColor { get }
}

func configLib(colors: Colors) {
    print(colors.general.mainColor)
}
Drobs
  • 760
  • 8
  • 12
  • func configLib(colors: Colors) { print(colors.general.mainColor) OK, thank you, all good till now, but I want this colors object to be viabile anywhere in my package. How and where should I declare an instance for colors object? But keep in mind that I want the object to be unwrapped without ! or ? or default value. I want to be declared like the parameter from this function but visible globally in the project – poPaTheGuru Nov 09 '21 at 19:08
  • 1
    I don't think that this is possible. At least default values would be needed if you don't want an optional. But for my packages I usually do define a force unwrapped global Variable in the package for my DI Object. For you it would be like `public var color: Colors!` and already fill it in the AppDelegate `MyPackage.color = AppColors()`. Since you make sure to initialize it at the start of the App, the force unwrapping will not be an issue. And even if you forget to do it, you will definitely see the crash during development time, while testing the component. So no runtime issues expected. – Drobs Nov 11 '21 at 09:18
  • Thank you for your answers and time! – poPaTheGuru Nov 11 '21 at 19:43