-6

How I can use UserDefaults in Swift3 to complete this task:

I want to have a variable coins = 0 with a label that displayed "Coins: 0", then have a button and which tapped update coins by 1.

I need this to be saved as a UserDefault so that you can close the view/app and have the amount of coins stay loaded/be able to add more to them.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Jacob Peterson
  • 343
  • 1
  • 4
  • 12
  • This question has a lot of parts. What exactly do you need help with? There are countless examples of using `UserDefaults`. Did you at least look at the reference documentation? – rmaddy Apr 25 '17 at 02:46

3 Answers3

1

A good idea when working with UserDefaults is to wrap it in a protocol and using enums as keys. Here is an enum case for your coinsCount together with some other examples.

enum Key: String {
    case coinsCount
    case userId
    case recentSearches

    static var all: [Key] = [.coinsCount, .userId, .recentSearches]
}

protocol PersistenceManagerProtocol {

    //MARK: - Delete
    func deleteAll()
    func deleteValue(for key: Key)

    //MARK: - Inspection
    func hasValue(for key: Key) -> Bool

    //MARK: - Save
    func save(_ value: Any, for key: Key)

    //MARK: - Load
    func load<Value>(with key: Key) -> Value?
    func loadArray<Value>(with key: Key) -> [Value]
}


final class PersistenceManager {
    fileprivate let userDefaults: UserDefaults

    init(userDefaults: UserDefaults) {
        self.userDefaults = userDefaults
    }
}

extension PersistenceManager: PersistenceManagerProtocol {

    //MARK: - Delete
    func deleteValue(for key: Key) {
        userDefaults.setValue(nil, forKey: key.rawValue)
    }

    func deleteAll() {
        for key in Key.all {
            deleteValue(for: key)
        }
    }

    //MARK: - Inspection
    func hasValue(for key: Key) -> Bool {
        return userDefaults.value(forKey: key.rawValue) != nil
    }

    //MARK: - Save
    func save(_ value: Any, for key: Key) {
        saveValue(value, for: key)
    }

    //MARK: - Load
    func load<Value>(with key: Key) -> Value? {
        guard let value = userDefaults.value(forKey: key.rawValue) as? Value else { return nil }
        return value
    }

    func loadArray<Value>(with key: Key) -> [Value] {
        guard let array: [Value] = load(with: key) else { return [] }
        return array
    }
}

//USAGE
let persistenceManager: PersistenceManagerProtocol = PersistenceManager(.standard) // using dependency injection, can mock data

persistenceManager.save(237, for: .coinsCount)
let coinsCount: Int = persistenceManager.load(with: .coinsCount)

persistenceManager.save("foobar", for: .userId)
let userId: String = persistenceManager.load(with: .userId)

persistenceManager.save(["foo", "bar"], .recentSearches)
let recentSearches: [String] = persistenceManager.loadArray(with: .recentSearches)
Sajjon
  • 8,938
  • 5
  • 60
  • 94
-1
var coins = 0
  let saveData = UserDefaults.standard
  saveData.set(coins, forKey: "string you want to use to refer to this save data")
Chris Hutchison
  • 601
  • 6
  • 20
-2

I also had trouble using NSUserDefaults, I am no expert in Swift yet, but I can tell you what I understand of it and how it works for me:

UserDefaults works in 2 steps:

1st step: you set the data you want to save and when: For example if you want to save something while pressing a button:

buttonPressed{

Userdefaults.standard.set(list, forKey: "anyKeyYouWantHere") --> however the "list" variable looks
like at the moment you press the button it will be saved just like that

}

2nd step

If for example I want to load the list back when the view loads, in ViewDidLoad I just give the variable "list" back the value it had just before I closed the app;

As so:

list = UserDefaults.standard.string(forKey: "theSameKeyFromStep1")

Hope this makes sense to you! Good luck!