作者热门文章
- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个我正在尝试连接的 API,服务器是 Windows 身份验证。
我正在尝试通过委托(delegate)方法将 URLSession 与 URLCredential 结合使用
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void){
var disposition: URLSession.AuthChallengeDisposition = URLSession.AuthChallengeDisposition.performDefaultHandling
var credential:URLCredential?
print(challenge.protectionSpace.authenticationMethod)
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
if (credential != nil) {
disposition = URLSession.AuthChallengeDisposition.useCredential
}
else
{
disposition = URLSession.AuthChallengeDisposition.performDefaultHandling
}
}
else
{
disposition = URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge
}
completionHandler(disposition, credential);
}
此代码在执行一些打印后运行两次,因为有两种身份验证方法:
NSURLAuthenticationMethodServerTrust 和 NSURLAuthenticationMethodNTLM 当它通过 NSURLAuthenticationMethodServerTrust 运行时一切都很好,但是当它运行 NSURLAuthenticationMethodNTLM 时,我在这一行收到错误:
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
这样说:
fatal error: unexpectedly found nil while unwrapping an Optional value
但只有当我从
更改此条件时if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
到
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM {
我做错了什么?
这是我用来尝试连接到该 API 的方法
func loginUser(_ username: String, password: String, completion: @escaping (_ result: Bool) -> Void)
{
//Create request URL as String
let requestString = String(format:"%@", webservice) as String
//Covert URL request string to URL
guard let url = URL(string: requestString) else {
print("Error: cannot create URL")
return
}
//Convert URL to URLRequest
let urlRequest = URLRequest(url: url)
print(urlRequest)
//Add the username and password to URLCredential
credentials = URLCredential(user:username, password:password, persistence: .forSession)
print(credentials)
//Setup the URLSessionConfiguration
let config = URLSessionConfiguration.default
//Setup the URLSession
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
//Prepare the task to get data.
let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
DispatchQueue.main.async(execute: {
print(error!)
if(error == nil)
{
completion(true)
}
else
{
completion(false)
}
})
})
//Run the task to get data.
task.resume()
}
最佳答案
在Apple documentation for URLProtectionSpace.serverTrust
,它说:
nil if the authentication method of the protection space is not server trust.
因此,您正在尝试解包 nil
的可选值,这当然会导致崩溃。
在您的情况下,您可能只需将整个函数替换为(未测试):
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void){
var disposition: URLSession.AuthChallengeDisposition = URLSession.AuthChallengeDisposition.performDefaultHandling
print(challenge.protectionSpace.authenticationMethod)
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = URLSession.AuthChallengeDisposition.performDefaultHandling
}
else
{
disposition = URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge
}
completionHandler(disposition, credential);
}
关于ios - URLSession 不适用于 URLCredential,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40999371/
我是一名优秀的程序员,十分优秀!