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

对枚举类型的实现效果不佳 #43

Closed
donyang opened this issue Nov 17, 2016 · 8 comments
Closed

对枚举类型的实现效果不佳 #43

donyang opened this issue Nov 17, 2016 · 8 comments

Comments

@donyang
Copy link

donyang commented Nov 17, 2016

我们通常会针对服务端下发的数字转化成枚举
enum ResourceType : Int {
case 新闻 = 1
case 自媒体 = 2
case 帖子 = 3
case 问答 = 4
case 话题 = 5
case Unknown = -1
}
在ObjectMapper里只要直接放上去这个,在用默认map就可以反序列化
初始化默认使用Unknown, 当服务端下发6,7等客户端无法识别的类型时还是会保存Unknown不变
HandyJSON能否实现类似效果,另外HandyJSON这个协议加到enum上会有入侵性

@xuyecan
Copy link
Contributor

xuyecan commented Nov 21, 2016

是的,由于HandyJSON使用的赋值方法比较特殊,目前确实有一些限制,影响比较大的就是枚举类型的赋值。目前枚举类型需要通过自定义解析这种方式来实现。迟点我把文档再完善下。

入侵性方面,目前确实存在问题。我继续研究看看有没有更好的处理方式。

@butcheryl
Copy link

butcheryl commented Nov 21, 2016

我看了源码,发现在自定义解析 child 的时候对 child.value 做类型判断,如果是一个不支持的类型就抛出fatalError,你的例子是通过将这种不支持的类型使用可选值包装后绕过这种判断的方式实现的,但是对于枚举或者其他非基本类型的属性我们在创建的时候希望有个默认值,而不是可选值所以这个方法是否有一些欠缺?

对于枚举这种常用的非基本类型,可否通过 displayStyle 判断,然后做特殊处理,在还没有找到解决方式的时候强制用户对于有默认值的枚举实现 mapping 方法来达到安全的目的,而又不限制枚举有默认的初始值?

@xuyecan
Copy link
Contributor

xuyecan commented Nov 22, 2016

@butcheryl

  1. 你的例子是通过将这种不支持的类型使用可选值包装后绕过这种判断的方式实现的 不是这样的,可选最后也会解包进行赋值,写成非可选也会面临一样的问题。我给的例子是通过自定义解析方式去解析枚举值。
  2. 我昨晚想到了一个比较完美的方法,今天我实现一下,在这里贴下 commit,到时候你看下是否合适~

@butcheryl
Copy link

butcheryl commented Nov 22, 2016

@xuyecan

我给的例子是通过自定义解析方式去解析枚举值。

是通过自定义解析去解析枚举值但是这个枚举属性不能是有默认值的属性如:

struct ClassA: HandyJSON {
    
    var field1: (String, String)?
    var field2: (String, String)!
    var field3 = ("", "")
    
    mutating func mapping(mapper: HelpingMapper) {
        mapper.specify(property: &field1) { str in
            return ("a", "b")
        }
        
        mapper.specify(property: &field2) { str in
            return ("a", "b")
        }
        
        mapper.specify(property: &field3) { str in
            return ("a", "b")
        }
    }
}

具体转化一下这就了解了

@xuyecan
Copy link
Contributor

xuyecan commented Nov 22, 2016

@butcheryl

我把我想法实现了,已经提交: #97288d,欢迎检查下。

然后参考 示例代码,一个枚举类型要支持反序列化,只需要实现HandyJSONEnum协议:

enum Gender: String, HandyJSONEnum {
    case Male = "Male"
    case Female = "Female"

    static func makeInitWrapper() -> InitWrapperProtocol? {
        return InitWrapper<String>(rawInit: Gender.init)
    }
}

如果觉得有侵入性,可以这样:

enum Gender: String {
    case Male = "Male"
    case Female = "Female"
}

extension HandyJSONEnum {
    static func makeInitWrapper() -> InitWrapperProtocol? {
        return InitWrapper<String>(rawInit: Gender.init)
    }
}

实现makeInitWrapper函数只依赖枚举类型本身的init函数,实现起来毫不费劲,我感觉已经很完美了:)

没什么问题的话,我今天就发1.3.0版本。

@butcheryl
Copy link

good job

@xuyecan
Copy link
Contributor

xuyecan commented Nov 22, 2016

fixed in #97288d.

@xuyecan xuyecan closed this as completed Nov 22, 2016
@HMWDavid
Copy link

Installing HandyJSON 5.0.4-beta 中没有看到呢?

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

4 participants