如何在 Swift. 中使用 .net(C# 创建 API)?我可以使用它吗?
How to use .net (C# Created API) in Swift.? can i use it.?
我在我的项目中使用了 swiftyJSON,当我使用 php created API 它在项目中工作正常但是当我在我的项目中使用 C# Created API 时它给出 null 作为响应。
我在网上搜索了一下,找到了,你可以在你的项目中使用它。
这是代码
let url: NSURL = NSURL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx?Mobile_Number=8523697888&Password=123")! // Enter URL Here
let request:NSMutableURLRequest = NSMutableURLRequest(url:url as URL)
//let bodyData = "employeeVerify & employeeID=\(empID)"// Pass parameter Form Here.
// print(bodyData)
request.httpMethod = "GET"
//request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
print(request)
let task = URLSession.shared.dataTask(with: request as URLRequest)
{
data, response, error in
if error != nil
{
print("error=\(error)")
return
}
// You can print out response object
print("response = \(response)")
do {
let json = JSON(data: data!)
print(json)
}
}
task.resume()
解决这个问题的方法是什么?我可以用吗?
在回答您的问题时,是的,您可以从 Swift 调用您的 C#、ASP.NET Web 服务。这就是 Web 服务的美妙之处,只要请求和响应的格式正确,客户端和服务器代码中使用的各自技术就完全相互独立。
话虽如此,这里有几个问题:
如果response
(URLResponse
)是nil
,那么error
就不会是nil
。查看错误是什么并采取相应措施。
例如,如果您没有更新 Info.plist
以接受不安全的请求(即没有 https://
的请求),您将收到错误消息。但是您可以将以下条目添加到您的 plist 中:
话虽如此,我怀疑网络响应可能没有失败(即 response
、URLResponse
object 本身不是 nil
),而是 JSON 解析失败,但您没有捕获 JSON 解析错误。
具有讽刺意味的是,对于一个名为 SwiftyJSON 的库来说,它捕获错误的方式非常笨拙。要捕获错误,您必须使用提供的 error
参数 调用 JSON()
初始化程序 。因此,在 SwiftyJSON 的当前版本中,您可以执行以下操作:
func performGetRequest(completionHandler: @escaping (JSON?, Error?) -> Void) {
let url = URL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx?Mobile_Number=8523697888&Password=123")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
completionHandler(nil, error)
return
}
var error: NSError?
let json = JSON(data: data, options: [], error: &error)
completionHandler(json, error)
}
task.resume()
}
然后这样称呼它:
performGetRequest() { json, error in
guard let json = json, error == nil else {
print("error = \(error)")
return
}
print("\(json)")
}
如果你这样做,你会看到报告:
error = Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.})
查看您的网络服务 data
returned 的内容,问题很明显:
[{"success":"1","Id":"5","FirstName":"admin","LastName":"admin","Email":"admin@gmail.com","Password":"123","Mobile_Number":"8523697888"}]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title></head>
<body>
<form method="post" action="./login.aspx" id="form1">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="dLzeSuX8RwkzsXsmp+fPMkjIu69T9SDFeB24ER3qTQYwmIJB0b8hk32gWHwKrHiE2deVYOcUhwor5igxXXPwUh/uQ+FoE26gCWjolkMFgpg=" />
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="45AB9188" />
<div>
</div>
</form>
</body>
</html>
如您所见,您的 Web 服务 return 不仅 JSON,而且 HTML。您只需要将您的网络服务修复为 return 和 JSON。
综上所述,还有一些基本无关的观察结果:
如我上面的示例所示,well-formed 请求通常会指定某些 header,即 Content-Type
(告诉 Web 服务您是如何构造您的request) 和 Accept
(告诉 web 服务您期望响应 body 的形式)。这些在技术上不是必需的,但是 (a) 这样做是最佳做法; (b) 根据您编写 Web 服务的方式,它可能需要它。在这种情况下并非如此,但是在编写 C# ASP.NET web API 时,它通常可以默认发送 XML 响应,除非客户端请求在 Accept
header.
另请注意,在我上面的示例中,我没有使用 NSURL
、NSURLRequest
或 NSMutableURLRequest
。我直接使用 URL
和 URLRequest
。
注意,在 URL 中发送密码不是好的做法。这并不像人们喜欢的那样安全。您希望将其放在请求的 body 中,而不是 URL。因此,您可能希望使用 POST
请求(然后将您的服务器更改为使用 https
而不是 http
):
func performPostRequest(completionHandler: @escaping (JSON?, Error?) -> Void) {
let url = URL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx")! // Enter URL Here
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "Mobile_Number=8523697888&Password=123".data(using: .utf8)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
completionHandler(nil, error)
return
}
var error: NSError?
let json = JSON(data: data, options: [], error: &error)
completionHandler(json, error)
}
task.resume()
}
同样值得注意的是,虽然我在上面没有这样做,但在准备这些请求时,您确实应该对这些字段值进行转义,以防它们包含任何保留字符。有关示例,请参阅 https://whosebug.com/a/41092318/1271826。
另外,你注释掉的httpBody
里面有空格,但是在正常的x-www-form-urlencoded
请求中,你应该没有空格。
如您所见,除了服务器代码问题外,还存在与客户端代码相关的问题。要正确完成所有这些工作 non-trivial,您可能需要考虑使用像 Alamofire 这样的库,这会使这更容易一些。
我在我的项目中使用了 swiftyJSON,当我使用 php created API 它在项目中工作正常但是当我在我的项目中使用 C# Created API 时它给出 null 作为响应。 我在网上搜索了一下,找到了,你可以在你的项目中使用它。
这是代码
let url: NSURL = NSURL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx?Mobile_Number=8523697888&Password=123")! // Enter URL Here
let request:NSMutableURLRequest = NSMutableURLRequest(url:url as URL)
//let bodyData = "employeeVerify & employeeID=\(empID)"// Pass parameter Form Here.
// print(bodyData)
request.httpMethod = "GET"
//request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
print(request)
let task = URLSession.shared.dataTask(with: request as URLRequest)
{
data, response, error in
if error != nil
{
print("error=\(error)")
return
}
// You can print out response object
print("response = \(response)")
do {
let json = JSON(data: data!)
print(json)
}
}
task.resume()
解决这个问题的方法是什么?我可以用吗?
在回答您的问题时,是的,您可以从 Swift 调用您的 C#、ASP.NET Web 服务。这就是 Web 服务的美妙之处,只要请求和响应的格式正确,客户端和服务器代码中使用的各自技术就完全相互独立。
话虽如此,这里有几个问题:
如果
response
(URLResponse
)是nil
,那么error
就不会是nil
。查看错误是什么并采取相应措施。例如,如果您没有更新
Info.plist
以接受不安全的请求(即没有https://
的请求),您将收到错误消息。但是您可以将以下条目添加到您的 plist 中:话虽如此,我怀疑网络响应可能没有失败(即
response
、URLResponse
object 本身不是nil
),而是 JSON 解析失败,但您没有捕获 JSON 解析错误。具有讽刺意味的是,对于一个名为 SwiftyJSON 的库来说,它捕获错误的方式非常笨拙。要捕获错误,您必须使用提供的
error
参数 调用JSON()
初始化程序 。因此,在 SwiftyJSON 的当前版本中,您可以执行以下操作:func performGetRequest(completionHandler: @escaping (JSON?, Error?) -> Void) { let url = URL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx?Mobile_Number=8523697888&Password=123")! var request = URLRequest(url: url) request.httpMethod = "GET" request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.setValue("application/json", forHTTPHeaderField: "Accept") let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { completionHandler(nil, error) return } var error: NSError? let json = JSON(data: data, options: [], error: &error) completionHandler(json, error) } task.resume() }
然后这样称呼它:
performGetRequest() { json, error in guard let json = json, error == nil else { print("error = \(error)") return } print("\(json)") }
如果你这样做,你会看到报告:
error = Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.})
查看您的网络服务
data
returned 的内容,问题很明显:[{"success":"1","Id":"5","FirstName":"admin","LastName":"admin","Email":"admin@gmail.com","Password":"123","Mobile_Number":"8523697888"}] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> </title></head> <body> <form method="post" action="./login.aspx" id="form1"> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="dLzeSuX8RwkzsXsmp+fPMkjIu69T9SDFeB24ER3qTQYwmIJB0b8hk32gWHwKrHiE2deVYOcUhwor5igxXXPwUh/uQ+FoE26gCWjolkMFgpg=" /> <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="45AB9188" /> <div> </div> </form> </body> </html>
如您所见,您的 Web 服务 return 不仅 JSON,而且 HTML。您只需要将您的网络服务修复为 return 和 JSON。
综上所述,还有一些基本无关的观察结果:
如我上面的示例所示,well-formed 请求通常会指定某些 header,即
Content-Type
(告诉 Web 服务您是如何构造您的request) 和Accept
(告诉 web 服务您期望响应 body 的形式)。这些在技术上不是必需的,但是 (a) 这样做是最佳做法; (b) 根据您编写 Web 服务的方式,它可能需要它。在这种情况下并非如此,但是在编写 C# ASP.NET web API 时,它通常可以默认发送 XML 响应,除非客户端请求在Accept
header.另请注意,在我上面的示例中,我没有使用
NSURL
、NSURLRequest
或NSMutableURLRequest
。我直接使用URL
和URLRequest
。注意,在 URL 中发送密码不是好的做法。这并不像人们喜欢的那样安全。您希望将其放在请求的 body 中,而不是 URL。因此,您可能希望使用
POST
请求(然后将您的服务器更改为使用https
而不是http
):func performPostRequest(completionHandler: @escaping (JSON?, Error?) -> Void) { let url = URL(string: "http://compareit.unitechecom.com/AndroidClass/API/login.aspx")! // Enter URL Here var request = URLRequest(url: url) request.httpMethod = "POST" request.httpBody = "Mobile_Number=8523697888&Password=123".data(using: .utf8) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.setValue("application/json", forHTTPHeaderField: "Accept") let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { completionHandler(nil, error) return } var error: NSError? let json = JSON(data: data, options: [], error: &error) completionHandler(json, error) } task.resume() }
同样值得注意的是,虽然我在上面没有这样做,但在准备这些请求时,您确实应该对这些字段值进行转义,以防它们包含任何保留字符。有关示例,请参阅 https://whosebug.com/a/41092318/1271826。
另外,你注释掉的
httpBody
里面有空格,但是在正常的x-www-form-urlencoded
请求中,你应该没有空格。
如您所见,除了服务器代码问题外,还存在与客户端代码相关的问题。要正确完成所有这些工作 non-trivial,您可能需要考虑使用像 Alamofire 这样的库,这会使这更容易一些。