Файл глобальных констант в Swift

252

В моих проектах Objective-C я часто использую файл глобальных констант для хранения таких вещей, как имена уведомлений и ключи для NSUserDefaults. Это выглядит примерно так:

@interface GlobalConstants : NSObject

extern NSString *someNotification;

@end

@implementation GlobalConstants

NSString *someNotification = @"aaaaNotification";

@end

Как сделать то же самое в Swift?

  • 2
    Вы можете увидеть этот тутоирал
Теги:

10 ответов

623
Лучший ответ

IMO лучший способ справиться с этим типом констант - создать Struct.

struct Constants {
    static let someNotification = "TEST"
}

Затем, например, вызовите его так:

print(Constants.someNotification)

Изменить: если вы хотите улучшить организацию, я советую вам использовать сегментированные подструктуры

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

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

Тогда вы можете просто использовать K.Path.Tmp

  • 3
    Удивительно, это самый организованный способ ... особенно сегментированные подструктуры ..
  • 115
    Лично я выбрал файл Constant.swift с разделенными структурами, но не инкапсулированный в большую структуру Constants чтобы избежать слишком длинного вызова константы. Поэтому я называю NotificationKey.Welcome вместо Constants.NotificationKey.Welcome
Показать ещё 17 комментариев
48

Я опаздываю на вечеринку.

Независимо от того, как я управляю файлом констант, так что он имеет смысл для разработчиков при написании кода в swift.

ДЛЯ 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"
    }
}

ДЛЯ 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"
    }
}

ДЛЯ ВСЕХ КЛЮЧЕЙ, ИСПОЛЬЗУЕМЫХ В APP

//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"
        }
    }

ДЛЯ ЦВЕТНЫХ КОНСТАНТ:

//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)
    }
}

Вы можете обернуть эти все файлы в общую группу с именем Константы в проекте Xcode.

И для большего просмотра этого видео

  • 0
    спасибо, я нашел ваш метод наиболее удобным (по крайней мере для меня), молодец! 8)
  • 0
    плюс один пример кода и усилий
Показать ещё 6 комментариев
28

Хотя я предпочитаю метод @Francescu (используя структуру со статическими свойствами), вы также можете определить глобальные константы и переменные:

let someNotification = "TEST"

Обратите внимание, что, в отличие от локальных переменных/констант и свойств класса/структуры, глобальные символы неявно ленивы, а это значит, что они инициализируются при первом обращении к ним.

Рекомендуемое чтение: Глобальные и локальные переменные, а также Глобальные переменные в Swift не являются переменными

  • 0
    Это правильный способ объявить константы. Структурный подход очень хорош для удобства чтения.
  • 1
    Я не рекомендую этот подход, так как он отменяет принцип ООП.
Показать ещё 5 комментариев
21

Constant.swift

import Foundation

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

ViewController.swift

var manager = AFHTTPRequestOperationManager(baseURL: kBaseURL)
  • 0
    По какой причине использует kBaseURL вместо BASEURL? Спасибо!
  • 0
    Вероятно, он также разрабатывает приложения для Android, и это стандарт Android.
Показать ещё 1 комментарий
14

Рассмотрим перечисления. Они могут быть логически разбиты для отдельных случаев использования.

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

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

Одно уникальное преимущество происходит, когда у вас есть ситуация взаимоисключающих опций, например:

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
    }
    }
}

В этом примере вы получите ошибку компиляции, потому что вы не обработали случай PhotoMetaKeys.DateTaken.

  • 1
    Enum case не может содержать повторяющиеся значения. Так что это не подходит для всех сценариев.
  • 0
    @AainaJain На самом деле, если вычисленные свойства используются для значений вместо необработанного значения enum, легко в разных случаях перечисления вывести одно и то же значение.
14

Или просто в GlobalConstants.swift:

import Foundation

let someNotification = "aaaaNotification"
6

Как и другие, упоминается что-либо, объявленное вне класса, глобально.

Вы также можете создавать синглтоны:

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

В любое время, когда вы хотите использовать что-то из этого класса, вы, например. написать:

TestClass.sharedInstance.number = 1

Если вы теперь пишете println(TestClass.sharedInstance.number) из любого места вашего проекта, вы будете печатать 1 в журнале. Это работает для всех видов объектов.

tl; dr: Каждый раз, когда вы хотите сделать все в глобальном классе, добавьте static let sharedInstance = YourClassName() в класс и адресуйте все значения класса с префиксом YourClassName.sharedInstance

  • 0
    вопрос для вас. другие ответы включают использование struct для хранения информации, но потенциальная проблема заключается в том, что struct является типом значения, class является ссылочным типом, назначение экземпляра класса в struct приведет к грубому переходу класса в тип значения, что нежелательно, верно?
2

Цвета

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

Шрифты

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
    }
}

Для других - все так же, как в принятом ответе.

1

Для уведомлений вы можете использовать расширение, что-то вроде этого:

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

И используйте его как NotificationCenter.default.post(name: .testNotification, object: nil)

1

Что я сделал в своем проекте Swift
1: Создайте новый файл Swift
2: Создайте в ней структуру и статическую константу.
3: Для использования просто используйте YourStructName.baseURL

Примечание. После создания инициализации занимает мало времени, поэтому она будет отображаться в других диспетчерах просмотра через 2-5 секунд.

import Foundation

    struct YourStructName {
    static let MerchantID = "XXX"
    static let MerchantUsername = "XXXXX"
    static let ImageBaseURL = "XXXXXXX"
    static let baseURL = "XXXXXXX"
    }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню