Faruk Faruk - 9 days ago 6
Swift Question

Returning Whether Dictionary or Array from function?

I have an global function that returns parameters, headers and url for http requests. Though headers and url will always be the same type, parameters won't. It depends on request.

[[String:String]]
or
[String: Any]
. I tried to make the func generic, but i didn't work because I have to make processes and they are not always conform with these types. There is switch a in my function and in the some of the cases i should use arrayType and at the other ones i should use dictionaryType for the
parameter
and then return it. So here is the question; how can I define the
parameter
? Or what can I do?

Any suggestion will make me so appreciated.

I tried to write an struct that will make me able to decide to type of parameter like this;

struct parameterType<KeyType: Hashable, ValueType>{
typealias arrayType = [[String:String]]
typealias dictionaryType = [String: Any]
}


But I couldn't figure out how can I use it.

These is the function;

private func returnStaticDataForPostRequest<parameterType>(requestType: postRequestType, additionalParameters: [AnyObject]?) -> (url:NSURL, header:[String: String], parameter: [String: AnyObject]){}


Parameter in the function's return state sometimes should be
[String: AnyObject]
not
[String: Any]


Again any help would make me so happy.

Answer

Do you know about Endpoints? It's abstract layer for configuration of network request parameters like URL, parameters, method and others. You can write base protocol with default implementation, for example:

protocol Endpoint {

    var baseURL: String { get }
    var path: String { get }
    var headers: [RequestHeaders] { get }
    var parameters: Parameters { get }
    var requiresAuthorizationHeaders: Bool { get }
}

extension Endpoint {

    var baseURL: String {
        return "http://google.com"
    }

    var headers: [RequestHeaders] {
        switch self {
        default: return []
        }
    }

    var requiresAuthorizationHeaders: Bool {
        return true
    }

    var parameterEncoding: ParameterEncoding {
        return URLEncoding.default
    }
}

Then you need to create endpoint for every request in your application and override property if needed. For your requests you need to write method like that:

private func request(endpoint: RequestEndpoint) -> DataRequest {
    let headers = self.headers(for: endpoint)
    return Alamofire.request(URLForEndpoint(endpoint),
                             method: endpoint.method,
                             parameters: endpoint.parameters,
                             encoding: endpoint.parameterEncoding,
                             headers: headers)
}

You can read more about this approach in Moya framework repo, it uses same technique for requests.