2017-06-12 8 views
0

L'erreur provoque un blocage lors de l'utilisation de NSCoder pour archiver des objets personnalisés dans un tableau à partir de json.Swift NSCoder NSKeyArchiver: trouvé de manière inattendue lors du déballage

Erreur provoquant l'accident:

fatal error: unexpectedly found nil while unwrapping an Optional value

Code d'erreur: J'inclus le code complet dans retrieveData()

// NSCoding *Error causes Crash here* 
let blogList: NSObject = ((jsonArray[i]) as! NSObject).value(forKey: "blogList") as! NSObject 

MainController.swift

// Retrieving Data from Server *Clean Code* 
func retrieveData() { 

    let getDataURL = "http://blogtest.com/receiving.php" 
    let url: NSURL = NSURL(string: getDataURL)! 

    do { 
     let data: Data = try Data(contentsOf: url as URL) 
     jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray 

     // Looping through jsonArray 
     for i in 0..<jsonArray.count { 

      // Create Blog Object 
      let bID: String = (jsonArray[i] as AnyObject).object(forKey: "id") as! String 
      let bName: String = (jsonArray[i] as AnyObject).object(forKey: "blogName") as! String 
      let bStatus1: String = (jsonArray[i] as AnyObject).object(forKey: "blogStatus1") as! String 
      let bStatus2: String = (jsonArray[i] as AnyObject).object(forKey: "blogStatus2") as! String 
      let bURL: String = (jsonArray[i] as AnyObject).object(forKey: "blogURL") as! String 
      let bType: String = (jsonArray[i] as AnyObject).object(forKey: "blogType") as! String 
      let bDate: String = (jsonArray[i] as AnyObject).object(forKey: "blogDate") as! String 
      let bPop: String = (jsonArray[i] as AnyObject).object(forKey: "blogPop") as! String 

      // NSCoding *Error causes Crash here* 
      let blogList: NSObject = ((jsonArray[i]) as! NSObject).value(forKey: "blogList") as! NSObject 

      // Add Blog Objects to mainArray 
      mainArray.append(Blog(blogName: bName, andBlogStatus1: bStatus1, andBlogStatus2: bStatus2, andBlogURL: bURL, andBlogID: bID, andBlogType: bType, andBlogDate: bDate, andBlogPop: bPop, blogList: blogList as! [Blog])) 
     } 
    } 
    catch { 
     print("Error: (Retrieving Data)") 
    } 
    myTableView.reloadData() 
} 

Blog.swift - Poignées les objets personnalisés Blog

import UIKit 

class Blog: NSObject, NSCoding { 

// Strings 
var blogName: String 
var blogStatus1: String 
var blogStatus2: String 
var blogURL: String 
var blogID: String 
var blogType: String 
var blogDate: String 
var blogPop: String 
var blogList : [Blog] // NSCoding 

// Converting Strings into Objects 
init(blogName bName: String, 
    andBlogStatus1 bStatus1: String, 
    andBlogStatus2 bStatus2: String, 
    andBlogURL bURL: String, 
    andBlogID bID: String, 
    andBlogType bType: String, 
    andBlogDate bDate: String, 
    andBlogPop bPop: String, 
    blogList : [Blog]) // To NSCoding 
{ 

    self.blogName = bName 
    self.blogStatus1 = bStatus1 
    self.blogStatus2 = bStatus2 
    self.blogURL = bURL 
    self.blogID = bID 
    self.blogType = bType 
    self.blogDate = bDate 
    self.blogPop = bPop 
    self.blogList = blogList // NSCoding 
    super.init() 
} 

// NSCoding 
convenience required init?(coder aDecoder: NSCoder) { 
    self.init (coder : aDecoder) 
    self.blogName = aDecoder.decodeObject(forKey: "blogName") as! String 
    self.blogStatus1 = aDecoder.decodeObject(forKey: "blogStatus1") as! String 
    self.blogStatus2 = aDecoder.decodeObject(forKey: "blogStatus2") as! String 
    self.blogURL = aDecoder.decodeObject(forKey: "blogURL") as! String 
    self.blogID = aDecoder.decodeObject(forKey: "blogID") as! String 
    self.blogType = aDecoder.decodeObject(forKey: "blogType") as! String 
    self.blogDate = aDecoder.decodeObject(forKey: "blogDate") as! String 
    self.blogPop = aDecoder.decodeObject(forKey: "blogPop") as! String 
    self.blogList = aDecoder.decodeObject(forKey: "blogs") as! [Blog] 
} 

func encode(with aCoder: NSCoder) { 
    aCoder.encode(blogName, forKey: "blogName") 
    aCoder.encode(blogStatus1, forKey: "blogStatus1") 
    aCoder.encode(blogStatus2, forKey: "blogStatus2") 
    aCoder.encode(blogURL, forKey: "blogURL") 
    aCoder.encode(blogID, forKey: "blogID") 
    aCoder.encode(blogType, forKey: "blogType") 
    aCoder.encode(blogDate, forKey: "blogDate") 
    aCoder.encode(blogPop, forKey: "blogPop") 
    aCoder.encode(blogList, forKey: "blogs") 
} 
} 

Répondre

1

Ce crash n'a rien à voir avec NSCoder. Archivez le débogueur ou consignez la valeur de la valeur (forKey: "blogList"). Il n'existe probablement pas. Pouvez-vous donner des exemples de réponses de ce que vous obtenez dans la réponse réseau.

En outre, il est ma suggestion de ne pas utiliser forcé déballant utiliser à la place en option avec garde que la réponse du serveur ne peut pas faire confiance et cela pourrait commencer à causer l'accident à l'avenir

Vous devez changer constructeur ci-après

init?(id:String, info:[String:AnyObject]){ 
    guard let name = info["blogName"] as? String, let blogStatus1 = info["blogStatus1"] as? String ... so on .. else { 
     return nil 
    } 

    blogName = name 
    . 
    . initialize all field like these 

    // for blog list 
    var tmpBlogList = [BlogList]() 
    if let tmpBlogListInfo = info["blogList"] as? [[String:AnyObject]] 
    { 
     for info in tmpBlogListInfo 
     { 
      let childId = info["blogID"] as? String 
      if let blog = Blog(id:childId, info) { 
        tmpBlogList.append(blog) 
      } 
     } 
    } 
    blogList = tmpBlogList 
} 


//Replace mainArray.append(Blog(blogName: bName, andBlogStatus1: bStatus1, andBlogStatus2: bStatus2, andBlogURL: bURL, andBlogID: bID, andBlogType: bType, andBlogDate: bDate, andBlogPop: bPop, blogList: blogList as! [Blog])) 
if let blog = Blog(id: bID, info: blogList) { 
     mainArray.append(blog) 
} 
+0

Alors l'accident se produit parce que "blogList" est vide? Je dois désactiver NSCoder pour imprimer 'mainArray' qui est l'endroit où le réseau stocke les objets. Je ne peux pas imprimer "blogList" car il se bloque dans cette ligne. Impression de mainArray sans utiliser NSCoder. 'Ceci est mainArray [, , , , ]' (raccourci parce que ne correspondrait pas) – BroSimple

+0

Comment puis-je empêcher le crash? – BroSimple

+1

Vous pouvez imprimer print ("index: \ (i), content: \ (String (décrivant: jsonArray [i]))") avant de lire blogList. – Atif