如何向 Alamofire 请求添加参数

Posted

技术标签:

【中文标题】如何向 Alamofire 请求添加参数【英文标题】:How to add parameter to Almofire request 【发布时间】:2015-10-09 12:22:11 【问题描述】:

免责声明:我是 ios 编程新手,所以这个问题可能看起来很简单。这不是一个技巧问题!

我有一个使用 Almofire 发送 HTTP 请求的 Swift 项目。我想为每个发出的请求在查询字符串中添加一个参数。

所以,我想在每个请求中添加mykey=myval

例如:http://example.com/index -> http://example.com/index?mykey=myval 例如:http://example.com/index?key=val -> http://example.com/index?key=val&mykey=myval

我发现所有请求似乎都通过了

public func request(URLRequest: URLRequestConvertible) -> Request 
    return Manager.sharedInstance.request(URLRequest.URLRequest)

在一个名为 Almofire.swift 的文件中

也通过

public func request(URLRequest: URLRequestConvertible) -> Request 
    var dataTask: NSURLSessionDataTask?
    dispatch_sync(queue) 
        dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest)
    

    let request = Request(session: session, task: dataTask!)
    delegate[request.delegate.task] = request.delegate

    if startRequestsImmediately 
        request.resume()
    

    return request

在一个名为 Manager.swift 的文件中,所以我假设我需要在这里添加一些代码。由于我缺乏 Swift 知识,我花了几个小时进行实验,但没有任何乐趣——只有例外。

有谁知道如何为所有请求添加参数?

【问题讨论】:

【参考方案1】:

您无需更改 Alamofire 代码中的任何内容。相反,您可以使用URLRequestConvertible 协议将您的 URL 和参数封装在一个枚举中:

enum Router: URLRequestConvertible 
    static let baseURLString = "https://example.com" // define your base URL here
    static var defaultParams = ["myKey": "myValue"] // set the default params here

    // define a case for every request you need
    case Index
    case Endpoint1(param: String)
    case Endpoint2(param1: String, param2: String)

    var URLRequest: NSMutableURLRequest 
        let result: (path: String, parameters: [String: AnyObject]) = 
            // set the path and params for each request
            switch self 
            case .Index:
                return ("/index", Router.defaultParams)
            case .Endpoint1(let param):
                var params = Router.defaultParams
                params.updateValue(param, forKey: "key")
                return ("/endpoint", params)
            case .Endpoint2(let param1, let param2):
                var params = Router.defaultParams
                params.updateValue(param1, forKey: "key1")
                params.updateValue(param2, forKey: "key2")
                return ("/endpoint2", params)
            
        ()

        // create the URL and the request
        let URL = NSURL(string: Router.baseURLString)!
        let URLRequest = NSURLRequest(URL: URL.URLByAppendingPathComponent(result.path))
        let encoding = Alamofire.ParameterEncoding.URL

        return encoding.encode(URLRequest, parameters: result.parameters).0
    

那么您可以就以下事项调用您的请求:

// sends a request to 'https://example.com/index?myKey=myValue'
Alamofire.request(Router.Index).response  (request, urlResponse, data, error) -> Void in
    // handle response


// sends a request to 'https://example.com/endpoint?key=value&myKey=myValue'
Alamofire.request(Router.Endpoint1(param: "value")).response  (request, urlResponse, data, error) -> Void in
    // handle response


// sends a request to 'https://example.com/endpoint2?key1=value1&key2=value2&myKey=myValue'
Alamofire.request(Router.Endpoint2(param1: "value1", param2: "value2")).response  (request, urlResponse, data, error) -> Void in
    // handle response

【讨论】:

谢谢。我了解如果文件被覆盖,我将丢失我的更改。我可以在 Almofire 上创建一个具有相同方法签名的包装器并将我的更改放在那里。但是我仍然需要知道如何在请求创建后添加到请求中。 请查看我的更新答案以解决您的问题。【参考方案2】:

简单请求 ->

func someFunction()

    Alamofire.request(.GET, "apiName", parameters:["Key":"Value"])
        .response  request, response, data, error in
            if error == nil 
                print(request)
                print(response)
            
            else 
                //Display Error Message
                print(error)
            

    

【讨论】:

【参考方案3】:

这是为每个 urlRequest 添加默认参数的另一种解决方案。您必须创建符合 RequestInterceptor 协议的类,并定义“adapt”方法:

class UserRequestInterceptor: RequestInterceptor 
        static var defaultParameters = ["mykey": "myval"]
        
        public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) 
            var urlRequest = urlRequest
            
            let encoding = URLEncodedFormParameterEncoder.default
            if let request = try? encoding.encode(UserRequestInterceptor.defaultParameters, into: urlRequest) 
                urlRequest = request
            
            
            completion(.success(urlRequest))
        
    

当您决定创建一个 URL 请求时,您必须添加“拦截器”参数:

func userFunction()
    
        AF.request("http://example.com/index", method: .get,
                   interceptor: UserRequestInterceptor()) // this line will be add all default params to every request
            .response  response in
                // ...
            )
    

或者您可以创建新的 Alamofire 会话并使用 UserRequestInterceptor 对其进行初始化:

class UserClass    
    let afSession = Session(interceptor: GlobusPro.SDK.GlobusProRequestInterceptor())
   ...
    func userFunction()
    
        afSession.request("http://example.com/index", method: .get) 
            .response  response in
                // ...
            )
    

【讨论】:

以上是关于如何向 Alamofire 请求添加参数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire 同时传递 queryStrings 和 JSON Body

如何在 Alamofire Swift 的 POST 请求中添加标头参数(-H、-u、-X、-d)

SwiftyDropbox 与 Alamofire 问题

在 Alamofire 的请求适配器中添加 GET 参数

在 swift 3 中下载文件时,alamo fire 中的进度视图不会更新

在 post 方法中发送标头