Search code examples
swiftposthttp-headersalamofire

Alamofire, HTTPheaders for post request [string:any]


I need to send a post request using alamofire to my server, one of the header to be sent is not a string value but is an Int

Reading the documentation of Alamofire look like the HTTPHeaders is only type [String: String]

Is there any way to customise the HTTPHeaders to [String:Any]?

I can't find to much understandable for me online.

thanks


Solution

  • Alamofire doesn't have such methods, but you can easily do it

    ["hey": 1].mapValues { String(describing: $0) } returns [String: String]

    If you have many places where you're using it, you can:

    1. Create extension for Dictionary
    extension Dictionary where Key == String, Value == Any {
        func toHTTPHeaders() -> HTTPHeaders {
            HTTPHeaders(mapValues { String(describing: $0) })
        }
    }
    // Usage
    AF.request(URL(fileURLWithPath: ""), headers: ["": 1].toHTTPHeaders())
    
    1. Create extension for HTTPHeaders
    extension HTTPHeaders: ExpressibleByDictionaryLiteral {
        public init(dictionaryLiteral elements: (String, Any)...) {
            self.init()
    
            elements.forEach { update(name: $0.0, value: String(describing: $0.1)) }
        }
    }
    // usage
    AF.request(URL(fileURLWithPath: ""), headers: HTTPHeaders(["": 1]))
    
    1. Create extension for Session
    extension Session {
        open func request(_ convertible: URLConvertible,
                          method: HTTPMethod = .get,
                          parameters: Parameters? = nil,
                          encoding: ParameterEncoding = URLEncoding.default,
                          headers: [String: Any],
                          interceptor: RequestInterceptor? = nil,
                          requestModifier: RequestModifier? = nil) -> DataRequest {
    
            return request(convertible, method: method, parameters: parameters, encoding: encoding, headers: headers.mapValues { String(describing: $0) }, interceptor: interceptor, requestModifier: requestModifier)
        }
    }
    
    // Usage
    AF.request(URL(fileURLWithPath: ""), headers: ["": 1])
    

    The reason there's no such option in Alamofire is type safety. When you use Any you can literary pass any value there and so probability of a mistake is much more. By requiring string library makes sure you're converting all values you need by yourself.

    I'd go for the first variant, because it's more clear when you read the code that there's something going on there