Int-Enum to String and vice a versa in Swift
Is the .none case really needed? It serves as a "fallback" in init(rawString: String)
if an unknown string is received from the network. But it is not listed in
the mapping dictionary, i.e. it can not be converted back to a string.

My suggestion is to remove that case, and use a failable initializer for the 
conversion from a string:

init?(rawString: String) {
    let loweredStr = rawString.lowercased()
    guard let type = NetworkType.networkDict[loweredStr] else {
        return nil
    }
    self = type
}


Using a custom extension for the conversion to a string is not really necessary,
the same can be achieved directly with

func rawString() -&gt; String? {
    return NetworkType.networkDict.first(where: { $1 == self }).map { $0.0 }
}


But the real question is: Why does this return an optional? It would return nil
if one of the enum cases is not covered in the dictionary. Let us assume that
you add another case five_g in the enumeration and forget to update the dictionary.
Now NetworkType.five_g.rawString() returns nil. What string do you send to the
server? 

One possible approach would be to force-unwrap the string, so that this
programming error is detected early:

func rawString() -&gt; String {
    return NetworkType.networkDict.first(where: { $1 == self }).map { $0.0 }!
}


But there is still a chance that the error remains undetected during development
and the deployed application crashes later.



A safer (and actually shorter and easier) approach is to define a string-based
enumeration, which implicitly defines the conversion to strings
and back:

enum NetworkType: String {
    case gprs
    case two_g = "2g"
    case three_g = "3g"
    case four_g = "4g"
    case lte
    case wifi
}


To make the comparison work, an ordinal number is associated with 
each case:

extension NetworkType: Comparable {
    var ordinal: Int {
        switch self {
        case .gprs: return 1
        case .two_g: return 2
        case .three_g: return 3
        case .four_g: return 4
        case .lte: return 5
        case .wifi: return 6
        }
    }

    public static func &lt; (a: NetworkType, b: NetworkType) -&gt; Bool {
        return a.ordinal &lt; b.ordinal
    }
}


Now the conversion is done using the built-in methods:

// String to NetworkType:
if let network = NetworkType(rawValue: "gprs") {
    // ..
} else {
    // unknown string from network
}

// NetworkType to String:
let rawString = NetworkType.gprs.rawValue


The conversion to a string cannot fail anymore. If another case is added, the compiler ensures that it is added to var ordinal as well.