Plik stałych globalnych w języku Swift

W moich projektach Objective-C często używam pliku globalnych stałych do przechowywania takich rzeczy jak nazwy powiadomień i klucze dla NSUserDefaults. Wygląda to mniej więcej tak:

@interface GlobalConstants : NSObject

extern NSString *someNotification;

@end

@implementation GlobalConstants

NSString *someNotification = @"aaaaNotification";

@end

Jak zrobić dokładnie to samo w Swift?

Author: Martijn Pieters, 2014-10-08

15 answers

Structs as namespace

IMO najlepszym sposobem radzenia sobie z tego typu stałymi jest stworzenie struktury.

struct Constants {
    static let someNotification = "TEST"
}

Następnie, na przykład, nazwij to tak w swoim kodzie:

print(Constants.someNotification)

Zagnieżdżanie

Jeśli chcesz lepszej organizacji radzę użyć segmentowane podstruktury

struct K {
    struct NotificationKey {
        static let Welcome = "kWelcomeNotif"
    }

    struct Path {
        static let Documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
        static let Tmp = NSTemporaryDirectory()
    }
}

Wtedy możesz użyć np. K.Path.Tmp

Przykład świata rzeczywistego

To tylko rozwiązanie techniczne, faktyczna implementacja w moim kodzie wygląda bardziej like:

struct GraphicColors {

    static let grayDark = UIColor(0.2)
    static let grayUltraDark = UIColor(0.1)

    static let brown  = UIColor(rgb: 126, 99, 89)
    // etc.
}

I


enum Env: String {
    case debug
    case testFlight
    case appStore
}

struct App {
    struct Folders {
        static let documents: NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
        static let temporary: NSString = NSTemporaryDirectory() as NSString
    }
    static let version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
    static let build: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String

    // This is private because the use of 'appConfiguration' is preferred.
    private static let isTestFlight = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"

    // This can be used to add debug statements.
    static var isDebug: Bool {
        #if DEBUG
        return true
        #else
        return false
        #endif
    }

    static var env: Env {
        if isDebug {
            return .debug
        } else if isTestFlight {
            return .testFlight
        } else {
            return .appStore
        }
    }
}
 782
Author: Francescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-13 09:34:23

Spóźnię się na przyjęcie.

bez względu na to, jak zarządzam plikiem stałych, aby miał on większy sens dla programistów podczas pisania kodu w języku swift.

DLA URL:

//URLConstants.swift

  struct APPURL {

    private struct Domains {
        static let Dev = "http://test-dev.cloudapp.net"
        static let UAT = "http://test-UAT.com"
        static let Local = "192.145.1.1"
        static let QA = "testAddress.qa.com"
    }

    private  struct Routes {
        static let Api = "/api/mobile"
    }

    private  static let Domain = Domains.Dev
    private  static let Route = Routes.Api
    private  static let BaseURL = Domain + Route

    static var FacebookLogin: String {
        return BaseURL  + "/auth/facebook"
    }
}

Dla CUSTOMFONTS:

//FontsConstants.swift
struct FontNames {

    static let LatoName = "Lato"
    struct Lato {
        static let LatoBold = "Lato-Bold"
        static let LatoMedium = "Lato-Medium"
        static let LatoRegular = "Lato-Regular"
        static let LatoExtraBold = "Lato-ExtraBold"
    }
}

DLA WSZYSTKICH KLAWISZY UŻYWANYCH W APLIKACJI

//KeyConstants.swift
    struct Key {

        static let DeviceType = "iOS"
        struct Beacon{
            static let ONEXUUID = "xxxx-xxxx-xxxx-xxxx"
        }

        struct UserDefaults {
            static let k_App_Running_FirstTime = "userRunningAppFirstTime"
        }

        struct Headers {
            static let Authorization = "Authorization"
            static let ContentType = "Content-Type"
        }
        struct Google{
            static let placesKey = "some key here"//for photos
            static let serverKey = "some key here"
        }

        struct ErrorMessage{
            static let listNotFound = "ERROR_LIST_NOT_FOUND"
            static let validationError = "ERROR_VALIDATION"
        }
    }

DLA STAŁYCH KOLORÓW:

//ColorConstants.swift
struct AppColor {

    private struct Alphas {
        static let Opaque = CGFloat(1)
        static let SemiOpaque = CGFloat(0.8)
        static let SemiTransparent = CGFloat(0.5)
        static let Transparent = CGFloat(0.3)
    }

    static let appPrimaryColor =  UIColor.white.withAlphaComponent(Alphas.SemiOpaque)
    static let appSecondaryColor =  UIColor.blue.withAlphaComponent(Alphas.Opaque)

    struct TextColors {
        static let Error = AppColor.appSecondaryColor
        static let Success = UIColor(red: 0.1303, green: 0.9915, blue: 0.0233, alpha: Alphas.Opaque) 
    }

    struct TabBarColors{
        static let Selected = UIColor.white
        static let NotSelected = UIColor.black
    }

    struct OverlayColor {
        static let SemiTransparentBlack = UIColor.black.withAlphaComponent(Alphas.Transparent)
        static let SemiOpaque = UIColor.black.withAlphaComponent(Alphas.SemiOpaque)
        static let demoOverlay = UIColor.black.withAlphaComponent(0.6)
    }
}

Możesz zawinąć te wszystkie pliki w wspólną grupę o nazwie stałe W projekcie Xcode.

Oraz więcej obejrzyj ten film

 112
Author: Anish Parajuli 웃,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-26 03:13:43

Chociaż preferuję sposób @ Francescu (używając struktury ze statycznymi właściwościami), możesz również zdefiniować globalne stałe i zmienne:

let someNotification = "TEST"

Zauważ jednak, że inaczej niż lokalne zmienne / stałe i właściwości klas / struktur, globale są domyślnie leniwe, co oznacza, że są inicjalizowane, gdy są dostępne po raz pierwszy.

Sugerowane czytanie: zmienne globalne i lokalne , a także zmienne globalne w języku Swift nie są zmiennymi

 28
Author: Antonio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-08 08:35:52

Stała.swift

import Foundation

let kBaseURL = NSURL(string: "http://www.example.com/")

ViewController.swift

var manager = AFHTTPRequestOperationManager(baseURL: kBaseURL)
 23
Author: Kirit Vaghela,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-11 17:26:49

Rozważ wyliczenia. Można je logicznie podzielić na oddzielne przypadki użycia.

enum UserDefaultsKeys: String {
    case SomeNotification = "aaaaNotification"
    case DeviceToken = "deviceToken"
}

enum PhotoMetaKeys: String {
    case Orientation = "orientation_hv"
    case Size = "size"
    case DateTaken = "date_taken"
}

Jedna unikalna korzyść ma miejsce, gdy mamy sytuację wzajemnie wykluczających się opcji, takich jak:

for (key, value) in photoConfigurationFile {
    guard let key = PhotoMetaKeys(rawvalue: key) else {
        continue // invalid key, ignore it
    }
    switch (key) {
    case.Orientation: {
        photo.orientation = value
    }
    case.Size: {
        photo.size = value
    }
    }
}

W tym przykładzie, otrzymasz błąd kompilacji, ponieważ nie zająłeś się przypadkiem PhotoMetaKeys.DateTaken.

 20
Author: William Entriken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-30 13:27:57

Lub po prostu w GlobalConstants.swift:

import Foundation

let someNotification = "aaaaNotification"
 14
Author: ChikabuZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-08 08:35:36

Jak inni wspominali, wszystko, co zadeklarowano poza klasą, jest globalne.

Można również tworzyć singletony:

class TestClass {
    static let sharedInstance = TestClass()
    // Anything else goes here
    var number = 0
}

Kiedy chcesz użyć czegoś z tej klasy, piszesz np.:

TestClass.sharedInstance.number = 1

Jeśli teraz napiszesz println(TestClass.sharedInstance.number) z dowolnego miejsca w Twoim projekcie, wydrukujesz 1 do dziennika. Działa to na wszelkiego rodzaju obiekty.

Tl; dr: za każdym razem, gdy chcesz, aby wszystko w klasie było globalne, dodaj static let sharedInstance = YourClassName() do klasy i adresuj wszystkie wartości klasy z przedrostkiem YourClassName.sharedInstance

 8
Author: Jacob R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-11 09:13:30

Co zrobiłem w moim projekcie Swift
1: Utwórz nowy plik Swift
2: Utwórz w nim strukturę i stałą statyczną.
3: do używania wystarczy użyć YourStructName.baseURL

Uwaga: Po utworzeniu inicjalizacja zajmuje niewiele czasu, więc będzie widoczna w innych kontrolerach viewcontrollerów po 2-5 sekundach.

import Foundation

    struct YourStructName {
    static let MerchantID = "XXX"
    static let MerchantUsername = "XXXXX"
    static let ImageBaseURL = "XXXXXXX"
    static let baseURL = "XXXXXXX"
    }
 5
Author: Vinay Krishna Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-16 10:31:51

Aby mieć stałe globalne w moich aplikacjach, to robię w osobnym pliku Swift :

import Foundation

struct Config {
    static let baseURL = "https://api.com"

    static APIKeys {
        static let token = "token"
        static let user = "user"
    }

    struct Notifications {
        static let awareUser = "aware_user"
    }
}
Jest łatwy w użyciu i można dzwonić wszędzie w ten sposób:
print(Config.Notifications.awareUser)
 4
Author: Ale Mohamad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-20 17:31:00

Do powiadomień możesz użyć rozszerzenia, coś w tym stylu:

extension Notification.Name {
    static let testNotification = "kTestNotification"
}

I używaj go jak NotificationCenter.default.post(name: .testNotification, object: nil)

 3
Author: B. Shoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 11:09:00

Można również użyć bezkluczowych enum.

Korzyść - nie można ich utworzyć.

enum API {
    enum Endpoint {
        static let url1 = "url1"
        static let url2 = "url2"
    }
    enum BaseURL {
        static let dev = "dev"
        static let prod = "prod"
    }
}
 3
Author: Pranav Pravakar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-02 05:05:17

Wersja Swift 4

Jeśli chcesz utworzyć nazwę dla NotificationCenter:

extension Notification.Name {
    static let updateDataList1 = Notification.Name("updateDataList1")
}

Subskrybuj powiadomienia:

NotificationCenter.default.addObserver(self, selector: #selector(youFunction), name: .updateDataList1, object: nil)

Wyślij powiadomienie:

NotificationCenter.default.post(name: .updateDataList1, object: nil)

Jeśli chcesz użyć klasy ze zmiennymi:

class Keys {
    static let key1 = "YOU_KEY"
    static let key2 = "YOU_KEY"
}

Lub:

struct Keys {
    static let key1 = "YOU_KEY"
    static let key2 = "YOU_KEY"
}
 2
Author: Valeriy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-19 15:40:06

Kolory

extension UIColor {
    static var greenLaPalma: UIColor {
        return UIColor(red:0.28, green:0.56, blue:0.22, alpha:1.00)
    }
}

Czcionki

enum CustomFontType: String {
    case avenirNextRegular = "AvenirNext-Regular",
    avenirDemiBold = "AvenirNext-DemiBold"
}

extension UIFont {
    static func getFont(with type: CustomFontType, size: CGFloat) -> UIFont {
        let font = UIFont(name: type.rawValue, size: size)!

        return font
    }
}

Dla innych-wszystko tak samo jak w odpowiedzi zaakceptowanej.

 1
Author: Bohdan Savych,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-15 12:31:10

Zgodnie z swift Docs zmienne globalne są deklarowane w obszarze pliku.

Zmienne globalne to zmienne, które są zdefiniowane poza dowolną funkcją, metodą, zamknięciem lub kontekstem typu

Wystarczy utworzyć plik swift (np: Constnats.swift) i zadeklarować tam swoje stałe:

// Constants.swift

let SOME_NOTIF = "aaaaNotification"

I wywołaj go z dowolnego miejsca w projekcie, bez konieczności wspominania o struct, enum lub nazwie klasy.

// MyViewController.swift

NotificationCenter.default.post(name: SOME_NOTIF, object: nil)

Myślę, że to jest dużo lepsze dla kodu czytelność.

 1
Author: Seif Meddeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 13:53:18

Ucz się od Apple jest najlepszym sposobem.

Na przykład powiadomienie klawiatury Apple:

extension UIResponder {

    public class let keyboardWillShowNotification: NSNotification.Name

    public class let keyboardDidShowNotification: NSNotification.Name

    public class let keyboardWillHideNotification: NSNotification.Name

    public class let keyboardDidHideNotification: NSNotification.Name

}

Teraz uczę się od Apple:

extension User {
    /// user did login notification
    static let userDidLogInNotification = Notification.Name(rawValue: "User.userDidLogInNotification")
}

Co więcej, NSAttributedString.Key.foregroundColor:

extension NSAttributedString {

    public struct Key : Hashable, Equatable, RawRepresentable {

        public init(_ rawValue: String)

        public init(rawValue: String)
    }
}

extension NSAttributedString.Key {

    /************************ Attributes ************************/

    @available(iOS 6.0, *)
    public static let foregroundColor: NSAttributedString.Key // UIColor, default blackColor

}

Teraz uczę się z Apple:

extension UIFont {

    struct Name {

    }

}

extension UIFont.Name {

    static let SFProText_Heavy = "SFProText-Heavy"
    static let SFProText_LightItalic = "SFProText-LightItalic"
    static let SFProText_HeavyItalic = "SFProText-HeavyItalic"

}

Użycie:

let font = UIFont.init(name: UIFont.Name.SFProText_Heavy, size: 20)

Ucz się od Apple jest sposobem, w jaki każdy może zrobić i może łatwo promować jakość kodu.

 1
Author: 无夜之星辰,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-11 09:42:22