Reputation: 1465
I made a simple struct that handles the management of the UI background (the user can choose to use a gradient or image). Inside this struct is a computed property called preference
which gets and sets the user's preference to UserDefaults.
When I try to set the preference
property using the following code:
Background().preference = .gradient
I get an error: "Cannot assign to property: function call returns immutable value"
I have to use this instead:
var background = Background()
background.preference = .gradient
I would prefer not having to assign an instance of Background
to a variable before finally setting the property.
I've found that changing Background
from a struct
to a class
allows me to set the property using Background().preference = .gradient
directly.
Can anyone give me some insight as to why this occurs? Is using class
better than using struct
for this situation or does it not matter?
struct Background {
enum Choice {
case gradient
case image
}
var preference: Choice {
get {
if let type = UserDefaults.standard.value(forKey: "background_type"), type as! String == "background" {
return .image
}
return .gradient
}
set(value){
if value == .image {
UserDefaults.standard.setValue("background", forKey: "background_type")
}else{
UserDefaults.standard.setValue("gradient", forKey: "background_type")
}
}
}
Upvotes: 1
Views: 86
Reputation:
You're not really getting any value from making an instance of a struct / class to just wrap UserDefaults. It's a very common problem and there are lots of clever solutions out there on google if you search around. For a really simple example you could just extend UserDefaults
//: Playground - noun: a place where people can play
import Cocoa
enum BackgroundChoice {
case gradient
case image
}
extension UserDefaults {
var backgroundChoice: BackgroundChoice {
get {
if let type = string(forKey: "background_type"), type == "image" {
return .image
}
return .gradient
}
set(value){
if value == .image {
setValue("background", forKey: "background_type")
}else{
setValue("gradient", forKey: "background_type")
}
}
}
}
UserDefaults.standard.backgroundChoice = .image
I know this doesn't answer your exact question, but I think you'll find there are better solutions to this problem if you dig around.
Upvotes: 1