具有参数的Swift GET请求
我对swift非常陌生,所以我可能在代码中有很多错误,但是我想实现的是向参数localhost服务器发送一个GET
请求。 更多,所以我试图实现它给我的函数采取两个参数baseURL:string,params:NSDictionary
。 我不知道如何将这两个结合到实际的URLRequest? 这是我到目前为止所尝试的
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中, :
http://www.example.com?key1=value1&key2=value2
请注意,请求的HTTPBody
不用于GET
请求。
key
和value
string也应该是百分比转义的。 因此,在Swift 3中, sendRequest
函数可能如下所示:
func sendRequest(url: String, parameters: [String: AnyObject], completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionTask { let parameterString = parameters.stringFromHttpParameters() let requestURL = URL(string: url + "?" + parameterString)! var request = URLRequest(url: requestURL) request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request, completionHandler: completionHandler) task.resume() return task }
(注意,我注意到你使用的是你在别处定义的loadedData
闭包,没关系,尽pipe我可能更喜欢把它作为方法的一个参数,但是希望这可以说明这个想法。
我们在Swift 3中使用下列String
和Dictionary
类别:
extension String { /// Percent escapes values to be added to a URL query as specified in RFC 3986 /// /// This percent-escapes all characters besides the alphanumeric character set and "-", ".", "_", and "~". /// /// http://www.ietf.org/rfc/rfc3986.txt /// /// - returns: Returns percent-escaped string. func addingPercentEncodingForURLQueryValue() -> String? { let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 let subDelimitersToEncode = "!$&'()*+,;=" var allowed = CharacterSet.urlQueryAllowed allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode) return addingPercentEncoding(withAllowedCharacters: allowed) } } extension Dictionary { /// Build string representation of HTTP parameter dictionary of keys and objects /// /// This percent escapes in compliance with RFC 3986 /// /// http://www.ietf.org/rfc/rfc3986.txt /// /// - returns: String representation in the form of key1=value1&key2=value2 where the keys and values are percent escaped func stringFromHttpParameters() -> String { let parameterArray = map { key, value -> String in let percentEscapedKey = (key as! String).addingPercentEncodingForURLQueryValue()! let percentEscapedValue = (value as! String).addingPercentEncodingForURLQueryValue()! return "\(percentEscapedKey)=\(percentEscapedValue)" } return parameterArray.joined(separator: "&") } }
请参阅Swift 2演绎的这个答案的前一个修订 。
使用NSURLComponents来构build你的NSURL
var urlComponents = NSURLComponents(string: "https://www.google.de/maps/")! urlComponents.queryItems = [ NSURLQueryItem(name: "q", value: String(51.500833)+","+String(-0.141944)), NSURLQueryItem(name: "z", value: String(6)) ] urlComponents.URL // returns https://www.google.de/maps/?q=51.500833,-0.141944&z=6
字体: https : //www.ralfebert.de/snippets/ios/encoding-nsurl-get-parameters/
Swift 3 :
extension URL { func getQueryItemValueForKey(key: String) -> String? { guard let components = NSURLComponents(url: self, resolvingAgainstBaseURL: false) else { return nil } guard let queryItems = components.queryItems else { return nil } return queryItems.filter { $0.name.lowercased() == key.lowercased() }.first?.value } }
我用它来获取图像名称为UIImagePickerController
在func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
:
var originalFilename = "" if let url = info[UIImagePickerControllerReferenceURL] as? URL, let imageIdentifier = url.getQueryItemValueForKey(key: "id") { originalFilename = imageIdentifier + ".png" print("file name : \(originalFilename)") }
我正在使用这个,在操场上试试。 在“常量”中将“基础URL”定义为“结构”
struct Constants { struct APIDetails { static let APIScheme = "https" static let APIHost = "restcountries.eu" static let APIPath = "/rest/v1/alpha/" } } private func createURLFromParameters(parameters: [String:Any], pathparam: String?) -> URL { var components = URLComponents() components.scheme = Constants.APIDetails.APIScheme components.host = Constants.APIDetails.APIHost components.path = Constants.APIDetails.APIPath if let paramPath = pathparam { components.path = Constants.APIDetails.APIPath + "\(paramPath)" } if !parameters.isEmpty { components.queryItems = [URLQueryItem]() for (key, value) in parameters { let queryItem = URLQueryItem(name: key, value: "\(value)") components.queryItems!.append(queryItem) } } return components.url! } let url = createURLFromParameters(parameters: ["fullText" : "true"], pathparam: "IN") //Result url= https://restcountries.eu/rest/v1/alpha/IN?fullText=true
我用:
let dictionary = ["method":"login_user", "cel":mobile.text! "password":password.text!] as Dictionary<String,String> for (key, value) in dictionary { data=data+"&"+key+"="+value } request.HTTPBody = data.dataUsingEncoding(NSUTF8StringEncoding);
@Rob提供的这个扩展名适用于Swift 3.0.1
我无法编译他在Xcode 8.1(8B62)中所包含的版本,
extension Dictionary { /// Build string representation of HTTP parameter dictionary of keys and objects /// /// :returns: String representation in the form of key1=value1&key2=value2 where the keys and values are percent escaped func stringFromHttpParameters() -> String { var parametersString = "" for (key, value) in self { if let key = key as? String, let value = value as? String { parametersString = parametersString + key + "=" + value + "&" } } parametersString = parametersString.substring(to: parametersString.index(before: parametersString.endIndex)) return parametersString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)! } }
你可以扩展你的Dictionary
,只提供stringFromHttpParameter
如果这两个键和值符合CustomStringConvertable
像这样
extension Dictionary where Key : CustomStringConvertible, Value : CustomStringConvertible { func stringFromHttpParameters() -> String { var parametersString = "" for (key, value) in self { parametersString += key.description + "=" + value.description + "&" } return parametersString } }
这是更清洁,并防止意外调用stringFromHttpParameters
没有业务调用该方法的字典