我是swift的新手,所以我的代码可能会有很多错误,但我试图实现的是向带有参数的本地主机服务器发送GET个请求.更重要的是,考虑到我的函数有两个参数baseURL:string,params:NSDictionary,我试图实现它.我不知道如何将这两者结合到实际请求中?以下是我迄今为止所做的try

    func sendRequest(url:String,params:NSDictionary){
       let urls: NSURL! = NSURL(string:url)
       var request = NSMutableURLRequest(URL:urls)
       request.HTTPMethod = "GET"
       var data:NSData! =  NSKeyedArchiver.archivedDataWithRootObject(params)
       request.HTTPBody = data
       println(request)
       var session = NSURLSession.sharedSession()
       var task = session.dataTaskWithRequest(request, completionHandler:loadedData)
       task.resume()

    }

}

func loadedData(data:NSData!,response:NSURLResponse!,err:NSError!){
    if(err != nil){
        println(err?.description)
    }else{
        var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
        println(jsonResult)

    }

}

推荐答案

在构建GET个请求时,请求没有正文,而是所有内容都放在URL上.要构建URL(并对其进行适当的百分比转义),还可以使用URLComponents.

var url = URLComponents(string: "https://www.google.com/search/")!

url.queryItems = [
    URLQueryItem(name: "q", value: "War & Peace")
]

唯一的诀窍是大多数web服务都需要+个字符的转义(因为它们会将其解释为application/x-www-form-urlencoded specification指定的空格字符).但URLComponents%的人无法逃脱.苹果认为+是查询中的有效字符,因此不应转义.从技术上讲,它们是正确的,在URI的查询中允许这样做,但它在application/x-www-form-urlencoded个请求中有特殊的意义,并且不应该在未经转移的情况下传递.

苹果承认,我们必须对这+个字符进行百分制转义,但建议我们手动操作:

var url = URLComponents(string: "https://www.wolframalpha.com/input/")!

url.queryItems = [
    URLQueryItem(name: "i", value: "1+2")
]

url.percentEncodedQuery = url.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")

这是一个不优雅的变通办法,但它是有效的,如果你的查询可能包括+个字符,并且你的服务器将它们解释为空格,苹果就会建议你这样做.

因此,将其与你的sendRequest个常规动作结合起来,你最终会得到如下结果:

func sendRequest(_ url: String, parameters: [String: String], completion: @escaping ([String: Any]?, Error?) -> Void) {
    var components = URLComponents(string: url)!
    components.queryItems = parameters.map { (key, value) in 
        URLQueryItem(name: key, value: value) 
    }
    components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
    let request = URLRequest(url: components.url!)
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard
            let data = data,                              // is there data
            let response = response as? HTTPURLResponse,  // is there HTTP response
            200 ..< 300 ~= response.statusCode,           // is statusCode 2XX
            error == nil                                  // was there no error
        else {
            completion(nil, error)
            return
        }
        
        let responseObject = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any]
        completion(responseObject, nil)
    }
    task.resume()
}

你会这样称呼它:

sendRequest("someurl", parameters: ["foo": "bar"]) { responseObject, error in
    guard let responseObject = responseObject, error == nil else {
        print(error ?? "Unknown error")
        return
    }

    // use `responseObject` here
}

就我个人而言,我现在会使用JSONDecoder,并返回自定义struct而不是字典,但这在这里并不重要.希望这说明了如何将参数百分比编码到GET请求的URL中的基本思想.


有关SWIFT 2和手动转义百分比格式副本,请参见previous revision of this answer.

Ios相关问答推荐

在Swift5中,将某些属性值从一个类复制到另一个类实例

自定义油漆圆角三角形

如何将Safari调试器附加到Turbo-iOS原生应用中的模拟器

如何根据SWIFT中的按钮点击更新文本值

如何在iOS 17 SwiftUI中获取用户名

在将Cocoapods更新到1.13.0之后,它抛出错误

封装 Swift 导入

比较 `某个协议` 实例时出现编译错误

SwiftUI中的Tap手势无法识别视图上的偏移变化

iOS 16 中的状态栏 colored颜色

以正确的方式在 Text() 中使用 colored颜色

XCode 14 Beta 中 NavigationStack 的正文渲染问题

如何使用 Swift 文档注释

滑动列表项以获取更多选项(Flutter)

如何在导航栏右侧添加多个 UIBarButtonItem?

在 iOS 7 上更改标签栏色调 colored颜色

呈现和关闭模态视图控制器

iTunes Connect 中的无限制 Web 访问是什么意思

在 NSUserDefaults 中存储值是否有任何限制?

UITableView 中的圆形 UIImageView 没有性能影响?