在Swift中通过Web服务传递参数

13 浏览
0 Comments

在Swift中通过Web服务传递参数

我正在学习Swift,但我不知道如何使用Swift将参数发送到服务器。

在Objective-C中,我们可以使用"%@"作为占位符来实现这一点。

但在Swift中应该怎么做呢?假设我有一个需要电子邮件和密码的登录网络服务。

现在我想知道的是,我该如何将logintextfieldpasswordtextfield文本发送到服务器,例如:

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

0
0 Comments

问题的原因是在调用Web服务时,没有正确传递参数。解决方法是创建一个包含所需参数的字典,并将其转换为JSON数据,然后将其作为请求的HTTPBody。

在上述代码中,我们可以看到在登录按钮点击事件中调用了一个名为`loginClicked`的函数。该函数首先创建了一个`NSMutableURLRequest`对象,并指定了Web服务的URL。然后,它创建了一个`NSURLSession`对象,并将HTTP方法设置为"POST"。接下来,它创建了一个包含所需参数的字典,并使用`NSJSONSerialization`将其转换为JSON数据。这个JSON数据被设置为请求的HTTPBody。最后,它设置了请求的"Content-Type"和"Accept"头,并创建了一个`NSURLSessionDataTask`对象来发送请求。

在`loginClicked`函数的最后,我们可以看到在请求完成后的回调中,我们从返回的数据中解析出了JSON。如果解析过程中有错误,我们打印错误描述。否则,我们将从JSON中获取"success"字段的值并打印出来。

此外,在上述代码中,我们还可以看到一个名为`criteriaDic`的函数,它返回一个包含参数的字典。在这个函数中,我们可以看到参数的键和值,例如"format":"json","MobileType":"IOS"等。

总结起来,问题的原因是在调用Web服务时没有正确传递参数。解决方法是创建一个字典来存储参数,并将其转换为JSON数据,然后将其作为请求的HTTPBody。

0
0 Comments

在创建包含用户输入的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()

我包含了很多在你的示例中没有包含的参数,仅仅是为了说明此例程如何处理各种参数类型。

顺便提一下,上述代码使用了我的datafromHttpParameters函数:

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版本,请参见此答案的之前版本

是的,你帮了我大忙..!! 它对我有效..:)

0
0 Comments

问题的出现的原因是在Web服务中传递参数时,将参数直接添加到URL中不够安全。解决方法是将参数放在请求的body中进行传递。

在上述内容中,可以看到通过在服务中传递所需的参数来完成这个问题。在代码中,变量urlPath是包含Web服务的URL,locationCoord是运行时传递给Web服务的位置参数的值。其中,参数key、sensor、radius和types是固定的。

显然,将用户ID或密码直接添加到URL中是不安全的。这些信息通常应该放在请求的body中。通常建议将安全信息放在POST请求的body中,而不是URL本身。从代码中可以看出,作者已经将HTTP请求参数放在了请求的body中。

在接下来的对话中,有关如何将参数放在请求的body中进行传递的问题得到了解答。通过给出了一些示例代码来说明如何正确地将参数传递给请求的body。

0