我有一个这样的枚举:
enum Environment {
case Production
case Staging
case Dev
}
我想在NSUserDefaults中保存一个像这样的实例:
func saveEnvironment(environment : Environment){
NSUserDefaults.standardUserDefaults().setObject(environment, forKey: kSavedEnvironmentDefaultsKey)
}
据我所知,Swift枚举不是NSObject,这使得难以保存,但我不确定将其转换为可存储的最佳方法是什么。
答案 0 :(得分:70)
使用rawValue作为枚举是使用可存储在NSUserDefaults中的类型的一种方法,定义枚举以使用rawValue。原始值可以是字符串,字符或任何整数或浮点数类型:
enum Environment: String {
case Production = "Prod"
case Staging = "Stg"
case Dev = "Dev"
}
您还可以使用rawValue(可能来自NSUserDefaults)直接创建枚举实例,例如:
let env = Environment(rawValue: "Dev")
您可以像这样从枚举对象中提取rawValue(String),然后根据需要将其存储在NSUserDefaults中:
if let myEnv = env {
println(myEnv.rawValue)
}
func saveEnvironment(environment : Environment){
NSUserDefaults.standardUserDefaults().setObject(environment.rawValue, forKey: kSavedEnvironmentDefaultsKey)
}
答案 1 :(得分:15)
如果您想保存/读取UserDefaults中的数据并分离一些逻辑,您可以按照以下方式进行操作(Swift 3):
enum Environment: String {
case Production
case Staging
case Dev
}
class UserDefaultsManager {
static let shared = UserDefaultsManager()
var environment: Environment? {
get {
guard let environment = UserDefaults.standard.value(forKey: kSavedEnvironmentDefaultsKey) as? String else {
return nil
}
return Environment(rawValue: environment)
}
set(environment) {
UserDefaults.standard.set(environment?.rawValue, forKey: kSavedEnvironmentDefaultsKey)
}
}
}
因此,在UserDefaults中保存数据将是这样的:
UserDefaultsManager.shared.environment = Environment.Production
读取数据,以这种方式保存在UserDefaults中:
if let environment = UserDefaultsManager.shared.environment {
//you can do some magic with this variable
} else {
print("environment data not saved in UserDefaults")
}
答案 2 :(得分:3)
<p id="time"> </p>
协议符合<Text style={styles.text}>{this.state.time.toTimeString().substring(0, 5)}</Text>
协议的范围Codable
枚举,将值编码和解码为Environment
。
Codable
Data
的包装器:
enum Environment: String, Codable {
case Production
case Staging
case Dev
}
UserDefaults
答案 3 :(得分:0)
我正在使用这种类型的舞台。你可以试试这个会对你有帮助。
enum Environment: String {
case Production = "Production URL"
case Testing = "Testing URl"
case Development = "Development URL"
}
//your button actions
// MARK: set Development api
@IBAction func didTapDevelopmentAction(_ sender: Any) {
let env = Environment.Development.rawValue
print(env)
UserDefaults.standard.set(env, forKey:Key.UserDefaults.stagingURL)
}
// MARK: set Production api
@IBAction func didTapProductionAction(_ sender: Any) {
let env = Environment.Production.rawValue
print(env)
UserDefaults.standard.set(env, forKey:Key.UserDefaults.stagingURL)
}
// MARK: set Testing api
@IBAction func didTapTestingAction(_ sender: Any) {
let env = Environment.Testing.rawValue
print(env)
UserDefaults.standard.set(env, forKey:Key.UserDefaults.stagingURL)
}
//Based on selection act
print("\(UserDefaults.standard.object(forKey: "stagingURL") ?? "")")
答案 4 :(得分:0)
Swift 5.1 您可以为此创建属性包装器
@propertyWrapper final class UserDefaultsLanguageValue {
var defaultValue: LanguageType
var key: UserDefaultsKey
init(key: UserDefaultsKey, defaultValue: LanguageType) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: LanguageType {
get { LanguageType(rawValue: UserDefaults.standard.object(forKey: key.rawValue) as? String ?? defaultValue.rawValue) ?? .en }
set { UserDefaults.standard.set(newValue.rawValue, forKey: key.rawValue) }
}
}
enum UserDefaultsKey: String {
case language
}
enum LanguageType: String {
case en
case ar
}
并像这样使用它
@UserDefaultsLanguageValue(key: .language, defaultValue: LanguageType.en) var language
答案 5 :(得分:0)
这是另一种可供选择的方法,可以轻松地与基于NSUserDefaults可以存储的类型(如String,Int等)的枚举一起使用。
@propertyWrapper
struct StoredProperty<T: RawRepresentable> {
let key: String
let defaultValue: T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
guard let rawValue = UserDefaults.standard.object(forKey: key) as? T.RawValue, let value = T(rawValue: rawValue) else {
return defaultValue
}
return value
}
set {
UserDefaults.standard.set(newValue.rawValue, forKey: key)
}
}
}
用法示例:
enum Environment: String {
case Production
case Staging
case Dev
}
@StoredProperty("Environment", defaultValue: .Dev)
var storedProperty: Environment
答案 6 :(得分:0)
Swift 5.1您可以使用Codable创建值来传入和传出UserDefaults来创建通用属性包装器
extension UserDefaults {
// let value: Value already set somewhere
// UserDefaults.standard.set(newValue, forKey: "foo")
//
func set<T>(_ value: T, forKey: String) where T: Encodable {
if let encoded = try? JSONEncoder().encode(value) {
setValue(encoded, forKey: forKey)
}
}
// let value: Value? = UserDefaults.standard.get(forKey: "foo")
//
func get<T>(forKey: String) -> T? where T: Decodable {
guard let data = value(forKey: forKey) as? Data,
let decodedData = try? JSONDecoder().decode(T.self, from: data)
else { return nil }
return decodedData
}
}
@propertyWrapper
public struct UserDefaultsBacked<Value>: Equatable where Value: Equatable, Value: Codable {
let key: String
let defaultValue: Value
var storage: UserDefaults = .standard
public init(key: String, defaultValue: Value) {
self.key = key
self.defaultValue = defaultValue
}
// if the value is nil return defaultValue
// if the value empty return defaultValue
// otherwise return the value
//
public var wrappedValue: Value {
get {
let value: Value? = storage.get(forKey: key)
if let stringValue = value as? String, stringValue.isEmpty {
// for string values we want to equate nil with empty string as well
return defaultValue
}
return value ?? defaultValue
}
set {
storage.set(newValue, forKey: key)
storage.synchronize()
}
}
}
// use it
struct AppState: Equatable {
enum TabItem: String, Codable {
case home
case book
case trips
case account
}
var isAppReady = false
@UserDefaultsBacked(key: "selectedTab", defaultValue: TabItem.home)
var selectedTab
// default value will be TabItem.home
@UserDefaultsBacked(key: "selectedIndex", defaultValue: 33)
var selectedIndex
// default value will be 33
}