Skip to content

Instantly share code, notes, and snippets.

@brennanMKE
Last active June 5, 2023 15:19
Show Gist options
  • Save brennanMKE/482452bb9ac5f578907f413902753eec to your computer and use it in GitHub Desktop.
Save brennanMKE/482452bb9ac5f578907f413902753eec to your computer and use it in GitHub Desktop.
Swift Enums for HTTP Status Codes

Non-contiguous Enum Values

This is a feature of Swift Enumerations I did not know about. Clever.

Often values like status codes are tiered like HTTP status codes which are grouped together within a range and incremented by one for most values in that group. Reducing code which must be typed is a good practice with Swift and eliminating the need to set every value in an enum definition would be a great way to eliminate details which can be derived by convention.

For this example the HTTP Status Codes are used. Tiers are grouped at increments of 100 and most values within one of the previous before the next level. If the value is not specified it would simply be one more than the previous value.

A common practice with enum types is to start with defining the first value with 0 and incrementing each value by one for the rest of the values.

enum HTTPStatusCodes: Int {
// 100 Informational
case Continue = 100
case SwitchingProtocols
case Processing
// 200 Success
case OK = 200
case Created
case Accepted
case NonAuthoritativeInformation
case NoContent
case ResetContent
case PartialContent
case MultiStatus
case AlreadyReported
case IMUsed = 226
// 300 Redirection
case MultipleChoices = 300
case MovedPermanently
case Found
case SeeOther
case NotModified
case UseProxy
case SwitchProxy
case TemporaryRedirect
case PermanentRedirect
// 400 Client Error
case BadRequest = 400
case Unauthorized
case PaymentRequired
case Forbidden
case NotFound
case MethodNotAllowed
case NotAcceptable
case ProxyAuthenticationRequired
case RequestTimeout
case Conflict
case Gone
case LengthRequired
case PreconditionFailed
case PayloadTooLarge
case URITooLong
case UnsupportedMediaType
case RangeNotSatisfiable
case ExpectationFailed
case ImATeapot
case MisdirectedRequest = 421
case UnprocessableEntity
case Locked
case FailedDependency
case UpgradeRequired = 426
case PreconditionRequired = 428
case TooManyRequests
case RequestHeaderFieldsTooLarge = 431
case UnavailableForLegalReasons = 451
// 500 Server Error
case InternalServerError = 500
case NotImplemented
case BadGateway
case ServiceUnavailable
case GatewayTimeout
case HTTPVersionNotSupported
case VariantAlsoNegotiates
case InsufficientStorage
case LoopDetected
case NotExtended = 510
case NetworkAuthenticationRequired
}
// Objective-C works too
typedef NS_ENUM(NSUInteger, SituationStatus) {
SituationStatusNormal = 100,
SituationStatusAlright,
SituationStatusDecent,
SituationStatusGood = 200,
SituationStatusGreat,
SituationStatusAwesome,
SituationStatusNoGood = 300,
SituationStatusBad,
SituationStatusTerrible
};
@EMart86
Copy link

EMart86 commented Apr 5, 2018

Hi, thanks for the StatusCodes.
This is a Swift4 valid version of your code:

enum HTTPStatusCode: Int {
    // 100 Informational
    case `continue` = 100
    case switchingProtocols
    case processing
    // 200 Success
    case ok = 200
    case created
    case accepted
    case nonAuthoritativeInformation
    case noContent
    case resetContent
    case partialContent
    case multiStatus
    case alreadyReported
    case iMUsed = 226
    // 300 Redirection
    case multipleChoices = 300
    case movedPermanently
    case found
    case seeOther
    case notModified
    case useProxy
    case switchProxy
    case temporaryRedirect
    case permanentRedirect
    // 400 Client Error
    case badRequest = 400
    case unauthorized
    case paymentRequired
    case forbidden
    case notFound
    case methodNotAllowed
    case notAcceptable
    case proxyAuthenticationRequired
    case requestTimeout
    case conflict
    case gone
    case lengthRequired
    case preconditionFailed
    case payloadTooLarge
    case uriTooLong
    case unsupportedMediaType
    case rangeNotSatisfiable
    case expectationFailed
    case imATeapot
    case misdirectedRequest = 421
    case unprocessableEntity
    case locked
    case failedDependency
    case upgradeRequired = 426
    case preconditionRequired = 428
    case tooManyRequests
    case requestHeaderFieldsTooLarge = 431
    case unavailableForLegalReasons = 451
    // 500 Server Error
    case internalServerError = 500
    case notImplemented
    case badGateway
    case serviceUnavailable
    case gatewayTimeout
    case httpVersionNotSupported
    case variantAlsoNegotiates
    case insufficientStorage
    case loopDetected
    case notExtended = 510
    case networkAuthenticationRequired
}

@brennanMKE
Copy link
Author

Thanks @EMart86!

@AndreaRov
Copy link

Thanks!

@makeitTim
Copy link

Great reference. Anybody have thoughts on the best way to wrap/combine this with Error for the new Swift 5 Result<T, Error> type?

@hockeyman0
Copy link

@makeitTim, I would probably prefer having a HTTPURLResponseError, with a required value for HTTPURLResponse itself. Since this enum is mapped to raw values, you don't need to extend HTTPURLResponse.statusCode to create an easy switch construct using the enum names instead of using the int values themself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment