在Swift中传递WebService中的参数 [英] Pass Parameter in WebService in Swift

查看:73
本文介绍了在Swift中传递WebService中的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Swift,我不知道如何使用Swift将参数发送到服务器。
在Objective-C中,我们可以使用%@作为占位符。
但是对于Swift应该怎么办,假设我有一个需要电子邮件和密码的登录网络服务。

I am learning Swift and I don't know how to send parameters to server using Swift. In Objective-C we can do this by using "%@" as the placeholder. But what should be done in case of Swift, suppose I have a login webservice which requires email and password.

现在我想知道的是我将 logintextfield passwordtextfield 文本发送到服务器,例如,

Now I want to know is that how will i send the logintextfield and passwordtextfield text to the server, such as,

var bodyData = "email=logintextfield.text&password=passwordtextfield.text"


推荐答案

当创建包含用户输入的HTTP请求时,如果用户输入中有任何保留字符,通常应该将其转义为百分比,因此:

When creating a HTTP request that includes user input, one should generally percent escape it in case there are any reserved characters in the user's input, thus:

let login    = logintextfield.text?.addingPercentEncodingForURLQueryValue() ?? ""
let password = passwordtextfield.text?.addingPercentEncodingForURLQueryValue() ?? ""
let bodyData = "email=\(login)&password=\(password)"

注意,你真的想检查登录密码是否 nil 与否。无论如何,百分比逃逸如下:

Note, you'd really want to check to see if login and password were nil or not. Anyway, the percent-escaping is done as follows:

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 allowedCharacters = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~")

        return self.addingPercentEncoding(withAllowedCharacters: allowedCharacters)
    }

}

参见这个答案是对这个扩展的另一个演绎。

See this answer for another rendition of this extension.

如果你想看一个使用的演示如上所述,想象以下请求:

If you wanted to see a demonstration of the use of the above, imagine the following request:

let keyData = "AIzaSyCRLa4LQZWNQBcjCYcIVYA45i9i8zfClqc"
let sensorInformation = false
let types = "building"
let radius = 1000000
let locationCoordinate = CLLocationCoordinate2D(latitude:40.748716, longitude: -73.985643)
let name = "Empire State Building, New York, NY"
let floors = 102
let now = Date()

let params:[String: Any] = [
    "key" : keyData,
    "sensor" : sensorInformation,
    "typesData" : types,
    "radius" : radius,
    "location" : locationCoordinate,
    "name" : name,
    "floors" : floors,
    "when" : now,
    "pi" : M_PI]

let url = URL(string: "http://some.web.site.com/inquiry")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpBody = params.dataFromHttpParameters()

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard data != nil && error == nil else {
        print("error submitting request: \(error)")
        return
    }

    if let httpResponse = response as? HTTPURLResponse where httpResponse.statusCode != 200 {
        print("response was not 200: \(response)")
        return
    }

    // handle the data of the successful response here
}
task.resume()

I我包含了许多未包含在您的示例中的参数,但仅仅是为了说明例程对各种参数类型的处理。

I'm including lots of parameters that were not included in your example, but simply as a way of illustrating the routine's handling of a diverse array of parameter types.

顺便提一下,上面使用我的 datafromHttpParameters 函数:

Incidentally, the above uses my datafromHttpParameters function:

extension Dictionary {

    /// This creates a String representation of the supplied value.
    ///
    /// This converts NSDate objects to a RFC3339 formatted string, booleans to "true" or "false",
    /// and otherwise returns the default string representation.
    ///
    /// - parameter value: The value to be converted to a string
    ///
    /// - returns:         String representation

    private func httpStringRepresentation(_ value: Any) -> String {
        switch value {
        case let date as Date:
            return date.rfc3339String()
        case let coordinate as CLLocationCoordinate2D:
            return "\(coordinate.latitude),\(coordinate.longitude)"
        case let boolean as Bool:
            return boolean ? "true" : "false"
        default:
            return "\(value)"
        }
    }

    /// Build `Data` 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 dataFromHttpParameters() -> Data {
        let parameterArray = self.map { (key, value) -> String in
            let percentEscapedKey = (key as! String).addingPercentEncodingForURLQueryValue()!
            let percentEscapedValue = httpStringRepresentation(value).addingPercentEncodingForURLQueryValue()!
            return "\(percentEscapedKey)=\(percentEscapedValue)"
        }

        return parameterArray.joined(separator: "&").data(using: .utf8)!
    }

}

这里,因为我正在交易使用参数字符串数组,我使用 join 函数来连接它们,用& 分隔,但想法是相同。

Here, because I'm dealing with an array of parameter strings, I use the join function to concatenate them separated by &, but the idea the same.

随意自定义该函数以处理您可能传递给它的任何数据类型(例如,我通常没有 CLLocationCoordinate2D 在那里,但你的例子包括一个,所以我想展示它的样子)。但关键是如果你提供包含用户输入的任何字段,请确保百分之以逃避它。

Feel free to customize that function to handle whatever data types you may be passing into it (e.g. I don't generally have CLLocationCoordinate2D in there, but your example included one, so I wanted to show what it might look like). But the key is that if you're supplying any fields that include user input, make sure to percent-escape it.

仅供参考,这是我的 rfc3339String 上面使用的函数。 (显然,如果你不需要传输日期,你不需要这个,但为了更完整的解决方案,我将其包括在内。)

FYI, this is my rfc3339String function which is used above. (Clearly, if you don't need to transmit dates, you don't need this, but I'm including it for the sake of completeness for a more generalized solution.)

extension Date {

    /// Get RFC 3339/ISO 8601 string representation of the date.
    ///
    /// For more information, see:
    ///
    /// https://developer.apple.com/library/ios/qa/qa1480/_index.html
    ///
    /// - returns: Return RFC 3339 representation of date string

    func rfc3339String() -> String {
        let formatter = DateFormatter()

        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSX"
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.locale = Locale(identifier: "en_US_POSIX")

        return formatter.string(from: self)
    }
}

要查看Swift 2的再现,请参阅此答案的前一个演绎

To see Swift 2 rendition, see previous rendition of this answer.

这篇关于在Swift中传递WebService中的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆