致命错误:在使用URLSession展开Optional值时意外发现nil

时间:2016-10-03 15:07:46

标签: swift swift3

我有这个方法在Swift 2.2中工作,但自从我将代码转换为Swift 3后它就不再有效了,这个方法的作用是将用户名和密码登录到带有Windows身份验证的URL,如果信用是更正为true,如果不正确,则返回false。

以下是方法:

func loginUser(_ username: String, password: String, completion: @escaping (_ result: Bool) -> Void)
    {
        //Setup the NSURLSessionConfiguration

        let configuration = URLSessionConfiguration.default

        //Setup the NSURLSession

        let session = Foundation.URLSession(configuration: configuration, delegate: self, delegateQueue: nil)

        //Add the username and password to NSURLCredential

        credential = URLCredential(user:username, password:password, persistence: .forSession)

        //Create request URL as String

        let requestString = NSString(format:"%@", webservice) as String

        //Convert URL string to NSURL

        let url: URL! = URL(string: requestString)

        //Prepare the task to get data.

        let task = session.dataTask(with: url, completionHandler: {
            data, response, error in

            DispatchQueue.main.async(execute: {

                if(error == nil)
                {

                    //If there is no error calling the API, return true

                    completion(true)
                }
                else
                {

                    //If there is an error calling the API, return false

                    completion(false)
                }

            })

        })

        //Run the task to get data.

        task.resume()

    }

我收到此错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

这就发生在这里:

let task = session.dataTask(with: url, completionHandler: {
            data, response, error in

            DispatchQueue.main.async(execute: {

                if(error == nil)
                {

                    //If there is no error calling the API, return true

                    completion(true)
                }
                else
                {

                    //If there is an error calling the API, return false

                    completion(false)
                }

            })

        })

我做错了什么?

在致命错误之前出现在我的调试导航器中:

function signature specialization <preserving fragile attribute, Arg[1] = [Closure Propagated : reabstraction thunk helper from @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> () to @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> (@out ()), Argument Types : [@callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> ()]> of generic specialization <preserving fragile attribute, ()> of Swift.StaticString.withUTF8Buffer <A> ((Swift.UnsafeBufferPointer<Swift.UInt8>) -> A) -> A

我相信我的问题在这里:

/**
     Requests credentials from the delegate in response to a session-level authentication request from the remote server.
     */

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        if challenge.previousFailureCount > 0
        {
            completionHandler(Foundation.URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
        }
        else
        {
            completionHandler(Foundation.URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:challenge.protectionSpace.serverTrust!))
        }

    }

    /**
     Requests credentials from the delegate in response to an authentication request from the remote server.
     */

    func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        completionHandler(Foundation.URLSession.AuthChallengeDisposition.useCredential,credential)

    }

它不喜欢这些方法。

2 个答案:

答案 0 :(得分:0)

这个答案适用于那些有这个问题的人,但方式不同 以下是我所面临和解决的问题: 我有一个搜索字段来查看tableview中的一些结果 它会因数字或擦除字而崩溃,并尽可能快速地进行数字化。 我设置了一个异常断点,但没有显示崩溃的位置。所以重新踏上了这一步,并从此开始:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "iTableViewCell", for: indexPath) as! MyClassTableViewCell
    cell.setCellFood(with: self.elementsArray[indexPath.row]) // <-- HERE
    return cell
}

但是,为了在数字化时到达那里,它从这里开始:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    self.elementsArray.removeAll() // <-- Last thing debbuging i found stop here

    DispatchQueue.main.asyncAfter(deadline: .now()) {
        if textField == self.txtSearch && (textField.text?.characters.count)! > 3 {
            let predicate = NSPredicate(format: "status = 'A' AND name CONTAINS [cd] %@", textField.text!)
            let filtered = MyObjectRealm().get(withFilter: "", predicate: nil, nsPredicate: predicate)
            filtered.forEach({ (food) in
                self.elementsArray.append(food)
                self.reloadAllDataCustom()
            })
        }else{
            self.elementsArray = MyObjectRealm().get(withFilter: "status = 'A'")
            self.reloadAllDataCustom()
        }
    }

    return true
}

所以,当它删除所有元素时,它会崩溃! 问题是DispatchQueue.main.asyncAfter(deadline: .now())
它有一个.now() + 0.2的dalay然后,它没有时间再次重新加载元素,导致崩溃!
现在它是实时擦除和填充,永不再崩溃,因为它在填充单元格时永远不会返回nil。

希望能帮助某人进行拆分并找到错误!

答案 1 :(得分:-1)

更改网址声明
let url: URL! = URL(string: requestString)

为:

let url: URL = URL(string: requestString)!

仅此一点就可以解决它;或者它会显示您的requestString不好。