5

I have around 10 Swift 3 applications.

They are almost similar but there are some fields that changes in each application and I would like that these values could be used in the entirely program (for example: the name of each company, the primary colour on the application, etc). These values will be constant in the whole program.

I would like to create one constants file by application so the values that will be used on each application will be different from the others so I will not have to repeat on each program each value all the time. For example, if I set a constant named company and change its value to company1, company2, etc... depending on the file I can use that company constant in all the applications. So I will not have to replace the variable manually in the whole application each time I create a new one. Just replacing the corresponding values to each application.

So, is it possible to create a constants file? Maybe adding a special class. I guess that maybe it has another specific name but I could not find it.

Thanks in advance!

Francisco Romero
  • 12,787
  • 22
  • 92
  • 167

6 Answers6

16

Yes you can create Constants file in Swift. Below are the ways.:

struct Constants {
    //App Constants
    static let APP_NAME = "YOUR_APP_NAME"
}

Usage:

print(Constants.APP_NAME)

Create a class and access via creating object:

class Constants{
     let APP_NAME = "YOUR APP NAME"
}

Usage:

let constInstance = Constants()
print(constInstance.APP_NAME)

The most efficient way is to go with struct.

Sohil R. Memon
  • 9,404
  • 1
  • 31
  • 57
  • And can I add struct in a different file? I would like to have a separated file with all the constants for a better maintenance of my code after. – Francisco Romero Nov 28 '16 at 13:19
  • Yes you can @Error404, you only need to create a new file and add it to all the targets you are going to access it from. – Marc Nov 28 '16 at 13:21
  • @Marc I guess you mean to use an import with the name of the struct file, right? – Francisco Romero Nov 28 '16 at 13:25
  • @Error404 You don't need to import anything. It's publicly available. – Sohil R. Memon Nov 28 '16 at 14:36
  • @SohilR.Memon So... what do you mean with "and add it to all the targets you are going to access it from."? Just to use the variables whatever I want? – Francisco Romero Nov 28 '16 at 15:01
  • @Error404 I mean in Xcode, on the file properties (right toolbar) check all the targets. But don't worry, xocde should do this for you automatically. You should be able to access the variables from everywhere without any fruther work. – Marc Nov 28 '16 at 15:08
  • Also, consider creating a new target - Framework. Move the things you want in different projects here and you no longer need to create anything new, instead add an "import" statement. –  Nov 28 '16 at 18:19
  • @dfd This is the next step I really need but I cannot get it. What do you mean with `create a new Framework`? – Francisco Romero Nov 29 '16 at 10:44
  • Menu option - File|New|Target|Cocoa Touch Framework. Move your code into whatever "structure" you want (classes, extensions, public/internal/private, etc.) and move your files (images, etc.) into bundles and you can share things by importing them just like you do UIKit or SpriteKit. –  Nov 29 '16 at 11:21
1

It actually depends on what you want to define:

  • In case of app's fonts, for example, declare an UIFont extension. In this way the precompiler can help you while writing code.

  • In case of any particular constant (string, integers, etc..), I would create a Constants.swift file which contains only enums. The enum in this case is better than class or struct because it cannot be wrongly initialized

    enum Constants { static let appIdentifier: String = "string" }

It can only be used in this way: Constants.appIdentifier It cannot be initialized by doing Constants() (compiler will throw an error).

See https://www.natashatherobot.com/swift-enum-no-cases/ for more info

Luca D'Alberti
  • 4,749
  • 3
  • 25
  • 45
1

The cleanest way (following the file approach) is to use a Constants.swift file and structs that segment use cases for each variable set. For instance:

class Constants {

    struct Validation {
        static let InvalidValue = "n/a"
        static let IncompleteValue = "Incomplete"
    }

    struct Labels {
        static let Username = "Username"
    }

}

And to use simply:

print(Constants.Validation.InvalidValue)

This gives you more readable variables as well as organized and focused constants file. If the file gets too large you can then choose to split it into several files using the same approach.

Julian B.
  • 3,605
  • 2
  • 29
  • 38
0

Use Structure for define Constant.

Do As follow.

struct Company {
    static let kCountry1 = "Company1"
    static let kCountry2 = "Company2"
    static let kCountry3 = "Company3"
    static let kCountry4 = "Company4"
}

Use like this.

print(Company.kCountry1)
Hitesh Surani
  • 12,733
  • 6
  • 54
  • 65
  • These should be `let` not `var`, and since they're `static`, you won't be able to access them with an instance `Company()`. So remove the first line in your usage. – Connor Neville Nov 28 '16 at 13:23
0

Constants are created with let in swift. Simply create a Constants.swift file and define your constants:

let mainColor = UIColor.green

You might want to version this separately and maybe add it to a custom framework.

shallowThought
  • 19,212
  • 9
  • 65
  • 112
0

Here is a slightly different solution not using a constants file, but a singleton class using a plist. This allows you to use one Settings file in all your applications, and then each application just needs a plist file.

If you add a plist to your project called "CustomSettings.plist" with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PrimaryColor</key>
    <string>cc3333</string>
    <key>CompanyName</key>
    <string>Company1</string>
</dict>
</plist>

Then create a new file called Settings with the following code:

public class Settings {
    static let instance = Settings()

    public let companyName: String
    public let primaryColor: UIColor

    private init() {
        let path = Bundle.main.path(forResource: "CustomSettings", ofType: "plist")!
        let settingsDict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

        companyName = settingsDict["CompanyName"] as! String
        let colorString = settingsDict["PrimaryColor"] as! String
        primaryColor = Settings.hexStringToUIColor(hex: colorString)
    }

    // Taken from: http://stackoverflow.com/questions/24263007/how-to-use-hex-colour-values-in-swift-ios
    private static func hexStringToUIColor (hex:String) -> UIColor {
        var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()

        if (cString.hasPrefix("#")) {
            cString.remove(at: cString.startIndex)
        }

        if ((cString.characters.count) != 6) {
            return UIColor.gray
        }

        var rgbValue:UInt32 = 0
        Scanner(string: cString).scanHexInt32(&rgbValue)

        return UIColor(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
            alpha: CGFloat(1.0)
        )
    }
}

Now you only need one Settings file which you could have in a framework, and then each application only needs the CustomSettings plist file with the custom contents. You could use it as follows:

print (Settings.instance.companyName)
view.backgroundColor = Settings.instance.primaryColor
totiDev
  • 5,189
  • 3
  • 30
  • 30
  • what is the most efficient way to use constants in-app using singleton or structs, my friend told me struct will cost me more memory is he right.. – Varun Kumar Mar 07 '17 at 12:01