How do you use a switch statement with a nested enum?

后端 未结 4 868
你的背包
你的背包 2021-01-31 10:32

I\'ve created an enum for Instagram endpoints with nested enums similar to Moya.

enum Instagram {
    enum Media {
        case Popular
        case Shortcode(id         


        
4条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-31 11:01

    There is a couple of problems with your architecture. You should know when and why you need to use extensions and protocols and how you should structure your blocks of code.

    1. If your type needs to conform to that protocol, feel free to use it to ensure you set your own standards. I don't even see that in the github project you referred to.
    2. Extension are good way to have a primitive type and extend its functionality in other parts of the project. It doesn't make sense to me why you should extend the type right after declaration. A good use case of it is where the String type has been extended to support URL Encoded values:
    private extension String {
        var URLEscapedString: String {
            return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())!
        }
    }
    
    1. When you are using this type of switch-case block
    switch self {
        case .Zen:
            return "/zen"
        case .UserProfile(let name):
            return "/users/\(name.URLEscapedString)"
        case .UserRepositories(let name):
            return "/users/\(name.URLEscapedString)/repos"
    }
    

    The value in the case should be a member of self. that's why it can not find the type. the type is declared inside Instagram enum but it doesn't hold value in the self. it holds value inside Media. So move your media related function into the declaration of Media and access them there. That way self is referring to Media. Here's the full working code for me:

    
    private extension String {
        var URLEscapedString: String {
            return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())!
        }
    }

    public enum Instagram {

    public enum Media {
        case Search(String)
    
        var path:String {
            switch self {
    
            case Media.Search(let keyword):
                return "/media/search/\(keyword.URLEscapedString)"
            }
        }
    }
    

    }

    var me = Instagram.Media.Search("me") print(me.path)

    1. As a piece of advice, in each step of building your whole architecture just question yourself if that piece of code belongs to that type or should be accessible publicly. In this case it makes complete sense to move search to Media cause you are searching media. You can add the same pattern for something like User and have search under user that returns different value.

提交回复
热议问题