Swift中的全局常量文件

在我的Objective-C项目中,我经常使用全局常量文件来存储NSUserDefaults的通知名称和键等内容。它看起来是这样的:

@interface GlobalConstants : NSObject


extern NSString *someNotification;


@end


@implementation GlobalConstants


NSString *someNotification = @"aaaaNotification";


@end

我如何在Swift中做完全相同的事情?

184857 次浏览

结构作为命名空间

在我看来,处理这类常量的最好方法是创建一个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作为实例

现实世界的例子

这只是一个技术解决方案,在我的代码中的实际实现看起来更像:

struct GraphicColors {


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


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

而且


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

或者只在GlobalConstants.swift中:

import Foundation


let someNotification = "aaaaNotification"

虽然我更喜欢@Francescu的方式(使用带有静态属性的结构体),但你也可以定义全局常量和变量:

let someNotification = "TEST"

但是请注意,与局部变量/常量和类/结构属性不同,全局变量是隐式惰性的,这意味着它们在第一次访问时被初始化。

建议阅读:全局变量和局部变量,还有Swift中的全局变量不是变量

Constant.swift

import Foundation


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

ViewController.swift

var manager = AFHTTPRequestOperationManager(baseURL: kBaseURL)

正如其他人所提到的,在类之外声明的任何东西都是全局的。

你也可以创建单例对象:

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

当你想要使用这个类中的一些东西时,你可以这样写:

TestClass.sharedInstance.number = 1

如果你现在从项目的任何地方写入println(TestClass.sharedInstance.number),你将把1打印到日志中。这适用于所有类型的对象。

tl;博士:任何时候你想让类中的所有内容都是全局的,向类中添加static let sharedInstance = YourClassName(),并用前缀YourClassName.sharedInstance来寻址类的所有值

考虑枚举。这些可以在逻辑上分解为单独的用例。

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的情况。

我来晚会晚了一点。

不管这里是我如何管理常量文件,以便它对开发人员更有意义,而写代码在swift。

网址:

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

应用程序中使用的所有键

//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项目中,你可以将这些文件包装在一个名为常量的公共组中。

更多内容请看这个视频

颜色

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

对于其他-一切都与接受的答案相同。

我在我的Swift项目中所做的事情
1:新建Swift文件
2:在其中创建一个结构和静态常量 3:对于Using,只需使用YourStructName.baseURL

注意:在创建初始化后,初始化需要很少的时间,所以它将在2-5秒后显示在其他视图控制器中。

import Foundation


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

对于通知,你可以使用扩展,像这样:

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

并像NotificationCenter.default.post(name: .testNotification, object: nil)一样使用它

根据斯威夫特文档,全局变量是在文件作用域中声明的。

全局变量是定义在任何函数、方法、闭包或类型上下文之外的变量

只需创建一个swift文件(例如:constats .swift)并在那里声明你的常量:

// Constants.swift


let SOME_NOTIF = "aaaaNotification"

从项目中的任何地方调用它,而不需要提及struct,enum或类名。

// MyViewController.swift


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

我认为这对于代码可读性来说更好。

Swift 4版本

如果您想为NotificationCenter创建一个名称:

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

订阅通知:

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

发送通知:

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

如果你只是想要一个有变量的类:

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

或者:

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

为了在我的应用程序中有全局常量,我在一个单独的斯威夫特文件中这样做:

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

它很容易使用,并且可以像这样调用任何地方:

print(Config.Notifications.awareUser)

也可以使用无大小写枚举。

优点-它们不能被实例化。

enum API {
enum Endpoint {
static let url1 = "url1"
static let url2 = "url2"
}
enum BaseURL {
static let dev = "dev"
static let prod = "prod"
}
}

向苹果学习是最好的方法。

例如,苹果的键盘通知:

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


}

现在我向苹果学习:

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

此外,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


}

现在我向苹果学习:

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"


}

用法:

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

向苹果学习是每个人都可以做的方法,可以很容易地提高你的代码质量。