Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

String enums not saving #30

Open
adeeldb opened this issue Mar 16, 2018 · 10 comments
Open

String enums not saving #30

adeeldb opened this issue Mar 16, 2018 · 10 comments

Comments

@adeeldb
Copy link

adeeldb commented Mar 16, 2018

Models are as follows:

enum Gender : String {
    case male, female, undefined
}

@objcMembers
class User: Base {
    dynamic var gender: Gender = .undefined

    override func encode(_ key: String, value: Any?) -> Any? {
        if key == "gender" {
            return self.gender.rawValue
        }

        return nil
    }
    
    override func decode(_ key: String, value: Any?) -> Bool {
        if key == "gender" {
            if let value = value as? String, let gender = Gender(rawValue: value) {
                self.gender = gender
            }
            
            return true
        }
        
        return false
    }
}
@1amageek
Copy link
Owner

?

@adeeldb
Copy link
Author

adeeldb commented Mar 16, 2018

When the user object is updated, the gender property does not persist.

@1amageek
Copy link
Owner

@1amageek
Copy link
Owner

@adeeldb Did you solve?

@adeeldb
Copy link
Author

adeeldb commented Apr 2, 2018

@1amageek the enum in the test is of type Int. Unfortunately, String enums don't work.

@1amageek
Copy link
Owner

1amageek commented Apr 2, 2018

@adeeldb Hi.
I was able to reproduce your behavior.

The reason why String does not work is in KVO.
Pring internally uses KVO. KVO does not work for enums that do not depend on @objc.

@1amageek
Copy link
Owner

1amageek commented Apr 2, 2018

https://github.com/1amageek/Pring/blob/master/Pring/Object.swift#L441

I have created a Function to update explicitly.

@adeeldb
Copy link
Author

adeeldb commented Apr 2, 2018

@1amageek My solution in my current project is as follows:

protocol PringEnum {
    var stringValue: String { get }
}

extension PringEnum where Self: RawRepresentable, Self.RawValue == String {
    var stringValue: String { return rawValue }
}

enum MyEnum : String, PringEnum  { 
    case something 
}

class MyObject : Object {
	override func encode(_ key: String, value: Any?) -> Any? {
	        let data = Mirror(reflecting: self).children.flatMap{ (label: $0.label, value: $0.value) }.reduce(into: [String: Any]()) { dictionary, item in
	            if let label = item.label {
	                dictionary[label] = item.value
	            }
	        }
	        if let data = data[key], let value: PringEnum = data as? PringEnum {
	            return value.stringValue
	        }
	        else {
	            return super.encode(key, value: value)
	        }
	    }

	override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
	        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
	        Mirror(reflecting: self).children.forEach { child in
	            guard let property = child.label.flatMap({ (label: $0, value: child.value) }) else { return }
	            
	            switch property.value {
	            case let rawRepresentable as PringEnum:
	                updateValue[property.label] = rawRepresentable.stringValue
	            default:
	                break
	            }
	        }
	}
}

@1amageek
Copy link
Owner

@adeeldb
observeValue is not valid for properties that do not inherit from NSObject.
I think updates will not work.

@adeeldb
Copy link
Author

adeeldb commented Apr 23, 2018

@1amageek the above approach seems to be working fine, given that String does inherit from NSObject.

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

No branches or pull requests

2 participants