AppStorage – Save Array

For a long time I thought about how I can store arrays in AppStorage. My intention was to pass an array from the app to the widgets. In the following I will present my solution. With my solution I can store String, Int, Double and even UIColor arrays.

I create a class that I assign to the NSObject and then write two functions.

class Storage: NSObject {
    
    static func archiveStringArray(object : [String]) -> Data {
        do {
            let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
            return data
        } catch {
            fatalError("Can't encode data: \(error)")
        }

    }

    static func loadStringArray(data: Data) -> [String] {
        do {
             let allowedClasses = [NSArray.self, NSString.self]
    guard let array = try NSKeyedUnarchiver.unarchivedObject(ofClasses: allowedClasses, from:data) as? [String] else {
        return []
    }
            return array
        } catch {
            fatalError("loadWStringArray - Can't encode data: \(error)")
        }
    }
}

The first function helps us to archive the array, in this case the string array as pure data. The second function then returns the data as a (string) array.

Here is an example application — code example:

@AppStorage(„nameArray", store: UserDefaults(suiteName: "group.de.domain.MyApp"))
    var nameArray: Data = Data()

var tempArray = ["David", "Caro", "Adrian"]
            
//Save Array
nameArray = Storage.archiveStringArray(object: tempArray)

Retrieve Array:

//Retrieve Array Example (SwiftUI)

ForEach(0..<{getStrings(data: entry.nameArray)).count) { i in
     Text(getStrings(data: entry.nameArray)[i])
                                       
}

func getStrings(data: Data) -> [String] {
    return Storage.loadStringArray(data: data)
}

First we save the temporary array in AppStorage which data is assigned to and we archive it. Then we can unpack the saved data array and call it up again as an array. In this example, we are looping through all the names.

As I said, you can’t just store a string array. Here, for example, with a UIColor array:

class Storage: NSObject {
    
    static func archiveColorArray(object : [UIColor]) -> Data {
        do {
            let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
            return data
        } catch {
            fatalError("Can't encode data: \(error)")
        }

    }

    static func loadColorArray(data: Data) -> [UIColor] {
        do {
            let allowedClasses = [NSArray.self, UIColor.self]
    guard let array = try NSKeyedUnarchiver.unarchivedObject(ofClasses: allowedClasses, from:data) as? [UIColor] else {
        return []
    }
            return array
        } catch {
            fatalError("loadWStringArray - Can't encode data: \(error)")
        }
    }
}

This is just a solution to store arrays in AppStorage. Of course there are several other solutions and maybe, in the next WWDC, it will be possible to store arrays more easily.

david
david

My favorite programming language is and will always be Swift, Dart & Python. I also have a good knowledge of Objective-C (and Web Development).

Articles: 2