ActivityIndicator (spinner), получающий ошибку Неожиданно найденный ноль при развертывании необязательного значения - PullRequest
0 голосов
/ 30 марта 2019

В моем общем классе я пишу код спиннера, он работает нормально, но иногда он получает ошибку.

Error: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Мой код в общем классе:

import UIKit

class SharedClass: NSObject {

static let sharedInstance = SharedClass()

var transparentView:UIView!
var spinner = UIActivityIndicatorView()


//Show activity indicator
func activityIndicator(view:UIView) {

    DispatchQueue.main.async {
        let window = UIApplication.shared.keyWindow! //Error : Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
        self.transparentView = UIView()
        self.transparentView.frame = CGRect(x: 0, y: 0, width: window.frame.width, height: window.frame.height)
        self.transparentView.backgroundColor = UIColor.black.withAlphaComponent(0.4)
        window.addSubview(self.transparentView)

        if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
            self.spinner = UIActivityIndicatorView(style: .whiteLarge)
            self.spinner.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
        } else {
            self.spinner = UIActivityIndicatorView(style: .white)
            self.spinner.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
        }
        self.spinner.center = view.center
        self.transparentView.addSubview(self.spinner)
        self.spinner.startAnimating()

        DispatchQueue.main.asyncAfter(deadline: .now() + 600.0) {//Stop spinner after 10 Sec's
            self.stopActivityIndicator()
            //self.transparentView.removeFromSuperview()
        }
    }
}

//Stop activity indicator
func stopActivityIndicator() {
    DispatchQueue.main.async {
        self.spinner.stopAnimating()
        self.spinner.removeFromSuperview()
        self.transparentView.removeFromSuperview()
    }
}

//Present alert on top of all windows
func alertWindow(title: String, message: String) {
    //Calling
    //SharedClass.sharedInstance.alertWindow(title:"", message:"")
    DispatchQueue.main.async(execute: {
        let alertWindow = UIWindow(frame: UIScreen.main.bounds)
        alertWindow.rootViewController = UIViewController()
        alertWindow.windowLevel = UIWindow.Level.alert + 1

        let alert2 = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let defaultAction2 = UIAlertAction(title: "OK", style: .default, handler: { action in
        })
        alert2.addAction(defaultAction2)

        alertWindow.makeKeyAndVisible()

        alertWindow.rootViewController?.present(alert2, animated: true, completion: nil)
    })
}


 private override init() {

}

}

Я звоню вот так

SharedClass.sharedInstance.activityIndicator (view: self.view) // Воспроизвести счетчик

SharedClass.sharedInstance.stopActivityIndicator () // Остановить счетчик

Это мой логин Btn код

@IBAction func onClickLoginBtn(_ sender: UIButton) {

    let networkReachability = Reachability.forInternetConnection()
    let networkStatus:Int = (networkReachability?.currentReachabilityStatus())!.rawValue
    print(networkStatus)
    if networkStatus == NotReachable.rawValue {
        let msg = SharedClass.sharedInstance.noNetMsg
        SharedClass.sharedInstance.alertWindow(title: "", message: msg)
    } else {

        SharedClass.sharedInstance.activityIndicator(view: self.view)//Play spinner
        let parameters = "imei=\(deviceID)&devid=\(deviceID)&ver=\(ver)"
        print("Parameters : \(parameters)")
        var request = URLRequest(url: URL(string: url)!)

        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"

        print("URL : \(request)")

        request.httpBody = parameters.data(using: .utf8)

        let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error
            SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner
            print("error=\(String(describing: error))")
            SharedClass.sharedInstance.alertWindow(title: "", message: "\(String(describing: error!.localizedDescription))")
            return
            }

            SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 500 {
                SharedClass.sharedInstance.alertWindow(title: "", message: "Server Error")
            } else if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(String(describing: response))")
            }

            do {
                let response = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject]
                print(response!)


                if status == "SUCCESS" {


                } else {
                    let message = res[0]["message"] as! String
                    //Call alert function
                    SharedClass.sharedInstance.alertWindow(title: "", message: message)
                }

            } catch let error as NSError {
                print(error)
                print(error.localizedDescription)
            }
        }

        task.resume()

    }

}

Здесь, когда я нажимаю кнопку входа в систему btn в первый раз, она работает нормально. Но когда я получаю ответ Время ожидания запроса истекло .

Error

Ошибка домена = NSURLErrorDomain Code = -1001 «Время ожидания истекло». UserInfo = {NSUnderlyingError = 0x7f9eab767d60 {Домен ошибки = kCFErrorDomainCFNetwork Code = -1001 "(null)" UserInfo = {_ kCFStreamErrorCodeKey = -2102, _kCFStreamErrorDomainKey = 4}}

Предупреждение будет отображаться. В этом случае, когда я нажимаю кнопку входа в систему btn второй раз, теперь приложение падает с ошибкой: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

1) Мой формат кода правильный или нет (означает вызов функции и почтовый индекс JSON)

2) Как решить эту ошибку.

1 Ответ

1 голос
/ 30 марта 2019

Вы можете убедиться, что у вас есть окно ключей, как будто вы не получаете окно, в котором вы собираетесь показывать загрузчик активности.

Сделайте это следующим образом

guard let window = UIApplication.shared.keyWindow else {
  return
}

это как раз то, что предлагал paulw11

...