简体   繁体   中英

How to set Array of enums in UserDefaults swift

I have custom type of enum array and I want to store it in UserDefaults using swift4.

enum DataType : Int
{
   case cloud = 1, files = 2, googleDrive = 3, mega = 4, others = 5
}
//
let arrayOfData : [DataType] = [.cloud, .files, .mega]

I want to store this array in UserDefaults.

Make DataType conform to Codable . It's pretty easy, just add Codable

enum DataType : Int, Codable
{
    case cloud = 1, files, googleDrive, mega, others // the consecutive raw values are inferred
}

let arrayOfData : [DataType] = [.cloud, .files, .mega]

Now encode the array as JSON data and save it

let data = try! JSONEncoder().encode(arrayOfData)
UserDefaults.standard.set(data, forKey: "dataType")

And read it back accordingly

do {
    if let data = UserDefaults.standard.data(forKey: "dataType") {
        let array = try JSONDecoder().decode([DataType].self, from: data)
    }
} catch { print(error)}

You can store your array in UserDefaults like below:

UserDefaults.standard.set(arrayOfData, forKey: "YourKeyName")

Hope this helps.

Store the rawValues of DataType . Then, when retrieving the array from UserDefaults , map the values to DataType

enum DataType: Int {
    case cloud = 1
    case files = 2
    case googleDrive = 3
    case mega = 4
    case others = 5
}

let arrayOfData: [DataType] = [.cloud, .files, .mega]
let arrayKey = "enumArray"

UserDefaults.standard.set(arrayOfData.map { $0.rawValue }, forKey: "enumArray")

let rawArray = UserDefaults.standard.value(forKey: arrayKey) as! [Int]

let dataTypeArray = rawArray.compactMap { DataType(rawValue: $0) }

You can save every type that confirms to Codable just like in the other answers.

enum DataType : Int, Codable
{
    case cloud = 1, files, googleDrive, mega, others // the consecutive raw values are inferred
}

In order to save an array of Codable Elements you can use an extension like this:

extension Array: RawRepresentable where Element: Codable {
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8) else {
            return nil
        }
        do {
            let result = try JSONDecoder().decode([Element].self, from: data)
            print("Init from result: \(result)")
            self = result
        } catch {
            print("Error: \(error)")
            return nil
        }
    }

    public var rawValue: String {
        guard let data = try? JSONEncoder().encode(self),
              let result = String(data: data, encoding: .utf8)
        else {
            return "[]"
        }
        print("Returning \(result)")
        return result
    }
}

Now you can do something like this:

let arrayOfData : [DataType] = [.cloud, .files, .mega]

UserDefaults.standard(set: arrayOfData, forKey:"myArrayOfCodableEnums")

or:

@AppStorage("ArrayOfCodableEnums") var myArrayOfCodableEnums = [DataType]()

convert your DataType to rawValue first.

enum DataType : Int
{
    case cloud = 1, files = 2, googleDrive = 3, mega = 4, others = 5
}
//
let arrayOfData:[DataType] = [.cloud, .files, .mega]
let rawArrayOfData = arrayOfData.map { $0.rawValue }

UserDefaults.standard.setValue(rawArrayOfData, forKey: "hello")

guard let data = UserDefaults.standard.value(forKey: "hello") as? [DataType.RawValue] else {
    return
}
let saved = data.map{ DataType(rawValue: $0)!}
print(saved)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM