Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save array of tuples in UserDefaults

I am using a tuple of arrays in one of my files and want to start saving it in UserDefaults. Here is how I am storing my current data:

typealias savemytuple = (Name: String, NameID: String, BookID: String, Picture: NSData)
var savefun = [savemytuple]()

I have researched and found I may need to do something with the following for saving:

NSKeyedArchiver.archivedDataWithRootObject

And this for retrieving:

NSKeyedUnarchiver.unarchiveObjectWithData

Not sure if this way will work as my tuple has multiple data types. Any idea on how to do this?

like image 968
mbro12 Avatar asked Feb 08 '18 03:02

mbro12


People also ask

Can I store array in UserDefaults Swift?

You can only store arrays of strings, numbers, Date objects, and Data objects in the user's defaults database.

How do you save Uicolor in UserDefaults?

The easiest way would be using NSUserDefaults . In this case you are storing the string "Coding Explorer" and you can reference by the key "userNameKey" .

Can I save an object in UserDefaults?

UserDefaults can simply save custom object which conforms to Codable protocol. JSONEncoder and JSONDecoder play important roles for handling the data transformation. Nested object must also conform to Codable protocol in order to encode and decode successfully.

How much can I store in UserDefaults?

There is no specific number attached to “a small amount”, but everything you store in UserDefaults will automatically be loaded when your app launches – if you store a lot in there your app launch will slow down. To give you at least an idea, you should aim to store no more than 512KB in there.


1 Answers

The values in UserDefaults must be property lists, so you need to convert each tuple to a property list. A Data is a property list, and there are several ways to convert things to Data.

One way is to stop using a tuple and use a struct instead. If all of the struct's stored properties conform to Codable, then you can ask Swift to generate everything needed to make the struct itself conform to Codable just by declaring the conformance. Both String and Data conform to Codable.

Once the struct is Codable, you can convert one of them, or even an array of them, into a property list via JSONEncoder or PropertyListEncoder:

import Foundation

struct Bookie: Codable {
    var name: String
    var nameId: String
    var bookId: String
    var picture: Data
}

let bookies = [
    Bookie(name: "mbro12", nameId: "id1", bookId: "b1", picture: Data()),
    Bookie(name: "mayoff", nameId: "id2", bookId: "b2", picture: Data())
]
let bookiesData = try! PropertyListEncoder().encode(bookies)
UserDefaults.standard.set(bookiesData, forKey: "bookies")

let fetchedData = UserDefaults.standard.data(forKey: "bookies")!
let fetchedBookies = try! PropertyListDecoder().decode([Bookie].self, from: fetchedData)
print(fetchedBookies)
like image 192
rob mayoff Avatar answered Sep 30 '22 04:09

rob mayoff