如何正确检查应用程序连接?

时间:2018-07-21 23:42:16

标签: ios swift xcode nsuserdefaults

我正在尝试创建一个功能,以在应用加载时检查连通性。如果检测到互联网连接,则该应用程序应下载JSON数据并将该数组保存在UserDefaults中,然后继续执行UITableView方法。但是,如果找不到互联网连接,则应用程序应在USerDefault上恢复该数组以填充另一个数组,然后继续执行UItableView方法。

我面临的问题是,当编译器通过UserDefault行以能够保存数组时,应用程序立即崩溃。我在做什么错了?

编译器错误:

  

)进行密钥备份已保存'   ***第一个抛出调用堆栈:(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:未捕获终止   NSException(lldb)类型的异常

[FIXED] 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?
}

1 个答案:

答案 0 :(得分:1)

在保存之前,应将数组末尾编码为Data,因为它是自定义对象的数组

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