如何正确检查应用程序连接?
How do I check app connectivity correctly?
我正在尝试创建一个函数来在应用程序加载时检查连接。如果检测到互联网连接,应用程序应下载 JSON 数据并将数组保存在 UserDefaults 中,然后继续执行 UITableView 方法。但是,如果未找到互联网连接,应用程序应恢复 USerDefault 上的数组以填充另一个数组,然后继续使用 UItableView 方法。
我面临的问题是,当编译器通过 UserDefault 行来保存数组时,应用程序会立即崩溃。我做错了什么?
编译器错误:
) for key backupSaved'
*** First throw call stack: (0x18257ad8c 0x1817345ec 0x18257ac6c 0x1825b1d08 0x1824e730c 0x1824e5a60 0x1825b2080 0x182515cec
0x1825b2080 0x1825b2304 0x182518d6c 0x182518588 0x182518c54
0x1825bc218 0x1825bf8a0 0x182edaaf4 0x102a794c0 0x102a7452c
0x102e8d314 0x102e45b7c 0x103da11dc 0x103da119c 0x103da5d2c
0x182523070 0x182520bc8 0x182440da8 0x184425020 0x18c45d758
0x102a756b0 0x181ed1fc0) libc++abi.dylib: terminating with uncaught
exception of type NSException (lldb)
[固定]ViewController:
import UIKit
import Kingfisher
import Alamofire
var arrCerveja = [Cerveja]()
var arrBackup = [Cerveja]()
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
//TableView DataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if Connectivity.isConnectedToInternet {
return arrCerveja.count
} else {
return arrBackup.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! TableViewCell
if Connectivity.isConnectedToInternet {
let model = arrCerveja[indexPath.row]
cell.labelName.text = model.name
cell.labelDetail.text = "Teor alcoólico: \(model.abv)"
let resource = ImageResource(downloadURL: URL(string: "\(model.image_url)")!, cacheKey: model.image_url)
cell.imageViewCell.kf.setImage(with: resource, placeholder: UIImage(named: "icons8-hourglass-48"), options: nil, progressBlock: nil, completionHandler: nil)
return cell
} else {
let model = arrBackup[indexPath.row]
cell.labelName.text = model.name
cell.labelDetail.text = "Teor alcoólico: \(model.abv)"
let resource = ImageResource(downloadURL: URL(string: "\(model.image_url)")!, cacheKey: model.image_url)
cell.imageViewCell.kf.setImage(with: resource, placeholder: UIImage(named: "icons8-hourglass-48"), options: nil, progressBlock: nil, completionHandler: nil)
return cell
}
}
//TableView Delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if Connectivity.isConnectedToInternet {
performSegue(withIdentifier: "segueId", sender:arrCerveja[indexPath.row])
} else {
performSegue(withIdentifier: "segueId", sender:arrBackup[indexPath.row])
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueId" {
let des = segue.destination as? TableViewDetalhes
//.item possui uma propriedade instanciada na TelaDetalheProdutos
des?.item = (sender as? Cerveja)
//Segue para CollectionView Categorias
}
}
struct Connectivity {
static let sharedInstance = NetworkReachabilityManager()!
static var isConnectedToInternet:Bool {
return self.sharedInstance.isReachable
}
}
override func viewDidAppear(_ animated: Bool) {
if Connectivity.isConnectedToInternet {
print("Connected")
getApiData { (cerveja) in
arrCerveja = cerveja
//Backup
do{
let data = try JSONEncoder().encode(arrCerveja)
UserDefaults.standard.set(data, forKey: "backupSaved")
//
self.tableView.reloadData()
}catch{print(error)
}
}
} else {
print("No Internet")
do{
if let savedData = UserDefaults.standard.value(forKey: "backupSaved") as? Data {
arrBackup = try JSONDecoder().decode([Cerveja].self, from: savedData)
self.tableView.reloadData()
}
}catch{
print(error)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
//SetupNavBarCustom
navigationController?.navigationBar.setupNavigationBar()
}
}
型号:
struct Cerveja:Decodable{
let name:String
let image_url:String
let description:String
let tagline:String
let abv:Double
let ibu:Double?
}
数组在保存之前应该被编码为数据,因为它是自定义对象的数组
do {
....... write
let data = try JSONEncoder().encode(arr)
UserDefaults.standard.set(data, forKey: "backupSaved")
// save as data
....... read
if let savedData = UserDefaults.standard.value(forKey: "backupSaved") as? Data {
let savedArr = try JSONDecoder().decode([Cerveja].self, from: savedData)
// use the array here
}
}
catch {
print(error)
}
//
从现在开始编码和解码
struct Cerveja:Codable {--}
//
此外,我不赞成在 userDefaults 中保存,考虑 CoreData
我正在尝试创建一个函数来在应用程序加载时检查连接。如果检测到互联网连接,应用程序应下载 JSON 数据并将数组保存在 UserDefaults 中,然后继续执行 UITableView 方法。但是,如果未找到互联网连接,应用程序应恢复 USerDefault 上的数组以填充另一个数组,然后继续使用 UItableView 方法。
我面临的问题是,当编译器通过 UserDefault 行来保存数组时,应用程序会立即崩溃。我做错了什么?
编译器错误:
) for key backupSaved' *** First throw call stack: (0x18257ad8c 0x1817345ec 0x18257ac6c 0x1825b1d08 0x1824e730c 0x1824e5a60 0x1825b2080 0x182515cec 0x1825b2080 0x1825b2304 0x182518d6c 0x182518588 0x182518c54 0x1825bc218 0x1825bf8a0 0x182edaaf4 0x102a794c0 0x102a7452c 0x102e8d314 0x102e45b7c 0x103da11dc 0x103da119c 0x103da5d2c 0x182523070 0x182520bc8 0x182440da8 0x184425020 0x18c45d758 0x102a756b0 0x181ed1fc0) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
[固定]ViewController:
import UIKit
import Kingfisher
import Alamofire
var arrCerveja = [Cerveja]()
var arrBackup = [Cerveja]()
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
//TableView DataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if Connectivity.isConnectedToInternet {
return arrCerveja.count
} else {
return arrBackup.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! TableViewCell
if Connectivity.isConnectedToInternet {
let model = arrCerveja[indexPath.row]
cell.labelName.text = model.name
cell.labelDetail.text = "Teor alcoólico: \(model.abv)"
let resource = ImageResource(downloadURL: URL(string: "\(model.image_url)")!, cacheKey: model.image_url)
cell.imageViewCell.kf.setImage(with: resource, placeholder: UIImage(named: "icons8-hourglass-48"), options: nil, progressBlock: nil, completionHandler: nil)
return cell
} else {
let model = arrBackup[indexPath.row]
cell.labelName.text = model.name
cell.labelDetail.text = "Teor alcoólico: \(model.abv)"
let resource = ImageResource(downloadURL: URL(string: "\(model.image_url)")!, cacheKey: model.image_url)
cell.imageViewCell.kf.setImage(with: resource, placeholder: UIImage(named: "icons8-hourglass-48"), options: nil, progressBlock: nil, completionHandler: nil)
return cell
}
}
//TableView Delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if Connectivity.isConnectedToInternet {
performSegue(withIdentifier: "segueId", sender:arrCerveja[indexPath.row])
} else {
performSegue(withIdentifier: "segueId", sender:arrBackup[indexPath.row])
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueId" {
let des = segue.destination as? TableViewDetalhes
//.item possui uma propriedade instanciada na TelaDetalheProdutos
des?.item = (sender as? Cerveja)
//Segue para CollectionView Categorias
}
}
struct Connectivity {
static let sharedInstance = NetworkReachabilityManager()!
static var isConnectedToInternet:Bool {
return self.sharedInstance.isReachable
}
}
override func viewDidAppear(_ animated: Bool) {
if Connectivity.isConnectedToInternet {
print("Connected")
getApiData { (cerveja) in
arrCerveja = cerveja
//Backup
do{
let data = try JSONEncoder().encode(arrCerveja)
UserDefaults.standard.set(data, forKey: "backupSaved")
//
self.tableView.reloadData()
}catch{print(error)
}
}
} else {
print("No Internet")
do{
if let savedData = UserDefaults.standard.value(forKey: "backupSaved") as? Data {
arrBackup = try JSONDecoder().decode([Cerveja].self, from: savedData)
self.tableView.reloadData()
}
}catch{
print(error)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
//SetupNavBarCustom
navigationController?.navigationBar.setupNavigationBar()
}
}
型号:
struct Cerveja:Decodable{
let name:String
let image_url:String
let description:String
let tagline:String
let abv:Double
let ibu:Double?
}
数组在保存之前应该被编码为数据,因为它是自定义对象的数组
do {
....... write
let data = try JSONEncoder().encode(arr)
UserDefaults.standard.set(data, forKey: "backupSaved")
// save as data
....... read
if let savedData = UserDefaults.standard.value(forKey: "backupSaved") as? Data {
let savedArr = try JSONDecoder().decode([Cerveja].self, from: savedData)
// use the array here
}
}
catch {
print(error)
}
//
从现在开始编码和解码
struct Cerveja:Codable {--}
//
此外,我不赞成在 userDefaults 中保存,考虑 CoreData