簡體   English   中英

在沒有互聯網的情況下,保持JSONSerialization不會崩潰我的應用程序的最佳方法?

[英]Best way to keep JSONSerialization from crashing my app when there is no internet?

好的,所以我找到了幾個非常相似的問題的不同答案,但大多數建議使用if語句或try / catch塊,我的代碼都有。 我正在調用我的Web服務,該服務返回JSON,我使用JSONSerialization將其拉出來進行解析。 由於標題表明我的應用程序在沒有互聯網時崩潰和燒傷,我希望有人能告訴我處理這個問題的最佳方法。 我將把我的方法放在下面:

func getCategories() {
    activityIndicator?.startAnimating()
    tableView.isUserInteractionEnabled = false
    categoryArray = []
    let configuration = URLSessionConfiguration.default
    configuration.requestCachePolicy = NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData
    let getQuizTitlesURL = URL(string: "https://myservice.com/my/directory/selectcategories.php")
    URLSession.shared.dataTask(with: getQuizTitlesURL! as URL, completionHandler: {(data, response, error) in

        do{
            if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSArray {

                var name:String
                var categoryId:Int
                var quizCount:Int

                for index in 0...parsedData.count-1 {
                    let aObject = parsedData[index] as! [String : AnyObject]
                    name = (aObject["Name"] as? String)!
                    quizCount = Int(aObject["Count"] as! String)!
                    categoryId = (Int((aObject["ID"] as? String)!)!)
                    let category:Category = Category(name: name, quizCount: quizCount, categoryId: categoryId)
                    self.categoryArray.append(category)
                }
            }

            if let HTTPResponse = response as? HTTPURLResponse {
                print(HTTPResponse)
                let statusCode = HTTPResponse.statusCode
                if statusCode == 200 {
                    print("Success")
                }
            }
        }catch let error as NSError {
            print(error)
        }
        DispatchQueue.main.async {
            self.tableView.reloadData()
            self.activityIndicator?.stopAnimating()
            self.tableView.isUserInteractionEnabled = true
        }
    }).resume()
}

我個人使用Reachability ,我在撥打電話之前檢查連接是否可用

var reachability = Reachability()! // I declare this in the appDelegate as global variable

func getCategories() {
  if reachability.isReachable {

    // your code 

  } else {
  let alertViewController  = UIAlertController(title: "No Connection" , message: "There is something wrong with your internet Connection. Please check and try again", preferredStyle: .alert)
  let okAction = UIAlertAction(title: okTitle, style: .default) { (uialertAction) in
        alertViewController.dismiss(animated: true, completion: nil)
    }
    alertViewController.addAction(okAction)

  self.present(alertViewController, animated: true, completion: nil)
  }
}

不要使用力量展開。

guard let data = data else { 
    // no data
    return
}
do {
    if let parsedData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSArray {
. . .

另外,正如@joaofs所說,請在請求之前檢查網絡可用性。 即使你檢查這一點,在請求 - 響應期間一切皆有可能。 就像請求后網絡斷開一樣。

如果沒有可用的網絡,我不會嘗試進行API調用檢查此庫

另一方面,在嘗試序列化有效負載之前,應確保獲得指示響應成功的HTTP狀態代碼。

創建一個新的swift文件(Cocoa類)並將其命名為Reachability.swift。 在此文件中添加以下代碼:

import UIKit
import SystemConfiguration

protocol Utilities {
}

extension NSObject:Utilities{


enum ReachabilityStatus {
    case notReachable
    case reachableViaWWAN
    case reachableViaWiFi
}

var currentReachabilityStatus: ReachabilityStatus {

    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
    zeroAddress.sin_family = sa_family_t(AF_INET)

    guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            SCNetworkReachabilityCreateWithAddress(nil,$0)
        }
    }) else {
        return .notReachable
    }

    var flags: SCNetworkReachabilityFlags = []
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
        return .notReachable
    }

    if flags.contains(.reachable) == false {
        // The target host is not reachable.
        return .notReachable
    }
    else if flags.contains(.isWWAN) == true {
        // WWAN connections are OK if the calling application is using the CFNetwork APIs.
        return .reachableViaWWAN
    }
    else if flags.contains(.connectionRequired) == false {
        // If the target host is reachable and no connection is required then we'll assume that you're on Wi-Fi...
        return .reachableViaWiFi
    }
    else if (flags.contains(.connectionOnDemand) == true || flags.contains(.connectionOnTraffic) == true) && flags.contains(.interventionRequired) == false {
        // The connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs and no [user] intervention is needed
        return .reachableViaWiFi
    }
    else {
        return .notReachable
    }
}

}

現在實現這個,你想要實現你的Web服務和這樣的東西。

func checkReachability(){
    if (currentReachabilityStatus == .reachableViaWiFi) ||  (currentReachabilityStatus == .reachableViaWWAN) {

        // if wifi-connection or mobile-network-connection

        // YOUR_CODE

    } else {

        print("There is no internet connection")

        // make an alert to go to settings and enable mobile data/wifi.

        let alertController = UIAlertController (title: "Connectivity error!", message: "Go to Settings -> Enable Wi-Fi/Mobile Data", preferredStyle: .alert)

        let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
            guard let settingsUrl = URL(string: "App-Prefs:root") else {
                return
            }

            if UIApplication.shared.canOpenURL(settingsUrl) {
                UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                    print("Settings opened: \(success)") // Prints true
                })
            }
        }

        alertController.addAction(settingsAction)
        present(alertController, animated: true, completion: nil)

    }
}

好的,不要謝謝我。 祝好運!!!! :d

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM