Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feature/AppStorage development is done #69

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

David-Acc
Copy link

@David-Acc David-Acc commented Mar 11, 2021

Finish AppStorage development

@David-Acc David-Acc requested a review from kevinwl02 as a code owner March 11, 2021 09:13
Button("Set Value") {
self.initalBool = !self.initalBool
}
}.padding()*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of commented code. This can get confusing so it's better to remove if not needed.

class AppStorageValueHolder<Value>{
public var storage: UserDefaults = UserDefaults.standard
public var key = AppStorageDefaultKey.defaultKey
var getDataFromStorage:(()->Value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and many other properties are missing proper spacing. Example:
getDataFromStorage:(
should be
getDataFromStorage: (

()->Value
should be
() -> Value

self.setDataInStorage(newValue)
}
}
init(value: Value , key:String,store: UserDefaults? = nil) where Value == Bool{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and other functions have irregular spacing. Please check them.

}

}
@propertyWrapper public struct AppStorage<Value> : DynamicProperty {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DynamicProperty is used for auto populated wrappers. For AppStorage this is not needed.


}
@propertyWrapper public struct AppStorage<Value> : DynamicProperty {
func update(context: Context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems redundant so you can remove it with above comment.

var _wrappedValue: AppStorageValueHolder<Value>
public var wrappedValue: Value{
get{
EnvironmentHolder.currentBodyViewBinderStack.last?.registerStateNotification(origin: _wrappedValue)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The origin of this state notification is simply an instance of the value holder inside this property wrapper. This means that only changes to this property wrapper will propagate view updates. If 2 or more @AppStorage property wrappers that point to the same property exist, the change in one of them won't notify the other.

In order to fix this, the origin of the notification needs to be a common object that is associated with the key, instead of just an instance created here. You can do this by creating a multiton, aka a static dictionary that holds identifier classes for each key.

After doing this, please add unit tests for this wrapper including the case I described above.

}
}
self.setDataInStorage = { (value) in
if value == Optional<Int>.none {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the value is nil, you should set nil inside user defaults, the same goes for all the other setter closures in all of the initializers

}
let tempStorage = self.storage
self.getDataFromStorage = { () ->Value in
if let _ = tempStorage.value(forKey: key){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do
tempStorage.value(forKey: key) != nil instead

self.setDataInStorage = { (value) in
tempStorage.set(value, forKey: key)
}
guard let _ = self.storage.value(forKey: key) else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is a bit strange to use a guard at the end of the function. It may be better to use
if storage.value(forKey:key) == nil

tempStorage.set(value, forKey: key)
}
guard let _ = self.storage.value(forKey: key) else {
self.value = value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value here should be a default value for this property wrapper, not for the user defaults itself. It's better to store this default value somewhere else, and keep the user defaults value the way it was (nil).

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants