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

@interface GlobalConstants : NSObject

extern NSString *someNotification;

@end

@implementation GlobalConstants

NSString *someNotification = @"aaaaNotification";

@end

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


当前回答

根据swift docs,全局变量是在文件作用域中声明的。

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

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

// Constants.swift

let SOME_NOTIF = "aaaaNotification"

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

// MyViewController.swift

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

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

其他回答

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

例如,苹果的键盘通知:

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)

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

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

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

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

Constant.swift

import Foundation

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

ViewController.swift

var manager = AFHTTPRequestOperationManager(baseURL: kBaseURL)

我在Swift项目中所做的 1:新建Swift File 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"
    }

结构作为命名空间

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

and


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