当前位置: 首页 > 知识库问答 >
问题:

Swift中WebService中的Pass参数

汪博达
2023-03-14

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

现在我想知道如何将LogintExtFieldPasswordTextField文本发送到服务器,

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

共有1个答案

费秦迟
2023-03-14

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

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

注意,您确实需要检查loginpassword是否为nil。无论如何,百分比转义是按以下方式完成的:

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)
    }

}

有关此扩展的另一个呈现,请参见此答案。

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()
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函数将它们连接起来,并用&分隔,但是想法是一样的。

可以自定义该函数来处理您可能传递给它的任何数据类型(例如,我通常没有cllocationcoordinate2D,但您的示例中包含了一个,所以我想展示它的样子)。但关键是,如果您提供的字段包含用户输入,请确保对其进行百分比转义。

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

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的翻译,请参阅此答案的先前翻译。

 类似资料:
  • 问题内容: 我正在尝试创建一个字符串扩展来做类似的事情 看起来像这样 它给我以下编译错误 类型CVaListPointer不符合协议CVargType 有人知道如何解决此编译错误吗? 问题答案: 这应该非常简单,只需更改您的参数,如下所示: 初始化(格式:语言环境:参数:)

  • 问题内容: 我试图从DetailViewController类调用在ViewController类中声明的函数。 尝试调试“通话中的额外参数”时,会弹出错误消息。 在ViewController类中: 在详细信息ViewController类 这很简单,但我感到困惑。 问题答案: 在某些情况下,即使参数调用的类型与函数声明的类型不匹配,即使调用看起来正确,也会给出“调用中的附加参数”。从您的问题来

  • 问题内容: 我正在寻找一种通过引用传递方法的方法。我知道Java不会将方法作为参数传递,但是,我想找到一种替代方法。 有人告诉我接口是将方法作为参数传递的替代方法,但我不了解接口如何通过引用充当方法。如果我理解正确,那么接口就是一组未定义的抽象方法。我不想发送每次都需要定义的接口,因为几种不同的方法可以使用相同的参数调用同一方法。 我要完成的工作与此类似: 调用如: 问题答案: 编辑:从Java

  • 问题内容: 当读取a的初始化程序时,我看到一些参数默认为value 。什么是关键词代表什么? 问题答案: 这不是有效的Swift代码,它是即时生成的。 在这里意味着有一些默认值,但发电机不能想像它适合你才能看到它。从技术上来说,默认值是一个内联函数,因此不能轻易将其转换为简单的声明。 您可以看到类似的声明 其中默认为(在Swift 1.x中)和默认为(在Swift 1.x中)。 在的情况下,默认值

  • 本文向大家介绍总结python中pass的作用,包括了总结python中pass的作用的使用技巧和注意事项,需要的朋友参考一下 python中pass的作用?pass代表一个空的语句块 Python中pass的作用: 示例1,定义一个类,类中没有任何内容 保存,运行之后,该文件将报错,因为结构不完整 写入pass之后,可以让程序的结构完整 pass 保证了程序结构的完整性,程序运行不再报错 pas

  • 问题内容: 当前正在学习Java 8 lambda表达式和方法参考。 我想将不带参数且没有返回值的方法作为参数传递给另一个方法。这就是我的做法: 我知道有一组预定义功能接口的,如,但我没有找到一个不带任何参数,而不是产生结果。 问题答案: 真的没关系;也会做。