ios - ActivityIndicator(微调器)出现错误在展开可选值时意外发现 nil
问题描述
在我的共享课程中,我编写了微调器代码,它工作正常,但有时会出错。
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 时,它工作正常。但是当我得到响应请求超时时。
错误
错误域=NSURLErrorDomain 代码=-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)如何解决这个错误。
解决方案
您可以确保获得 keyWindow,就好像您没有获得 window 一样,您将在哪里显示您的活动加载器。
按照以下方式进行
guard let window = UIApplication.shared.keyWindow else {
return
}
这正是 paulw11 的建议
推荐阅读
- reactjs - 我可以将 repo 中的单个组件作为 npm 包发布吗
- javascript - 如何获取反应材料ui组件中的字段值
- reactjs - 在 Material UI 中使用 Skeleton 时如何修复错误“alpha”未从“@material-ui/core/styles”导出
- python - 如何使用 NumPy 有效地计算行的成对比率?
- ios - 您如何在可区分的数据源(带有组合布局的集合视图)中使用多个数据模型?
- sql - How to check the current row with next row and update the current row not using while loop and cursor
- java - 我的代码仅从产品页面中选择第一项的值
- rest - 批处理的 OData $value 支持
- c# - 如何在c#中使用Dataset xsd文件获取数据
- php - Laravel 模型观察者更新和删除事件不会触发?