Swift 3 iOS 10, Essayer d'enregistrer tableau avec des objets personnalisés dans NSKeyedArchiver, essayant fondamentalement d'enregistrer la vue de la table après que l'utilisateur utilise les boutons pour basculer entre les sections. J'ai essayé plusieurs post pour résoudre le problème mais pas de chance, maintenant j'essaye de le faire moi-même NSCoding et NSKeyedArchiver.Swift: erreur dans NSKeyedArchiver
Erreur:
Cannot convert value of type '[Blog]' to expected argument type 'NSCoder'
erreur est en code Blog.swift, code qui gère NSCoding et mon Blog Objets
import UIKit
class BlogsCoding: NSObject, NSCoding {
var blogList : [Blog]
init(blogList : [Blog]) {
self.blogList = blogList
}
convenience required init?(coder aDecoder: NSCoder) {
guard let blogList = aDecoder.decodeObject(forKey: "blogs") as? [Blog]
else {
return nil
}
self.init (blogList : blogList)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(blogList, forKey: "blogs")
}
}
class Blog: NSObject, NSCoding { // To conform to 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] // To conform to NSCoding
override init() {
}
// 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 conform to NSCoding
{
super.init()
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 // To conform to NSCoding
}
// To conform to NSCoding
convenience required init?(coder aDecoder: NSCoder) {
guard let blogList = aDecoder.decodeObject(forKey: "blogs") as? [Blog]
else {
return nil
}
self.init (coder : blogList) // *---* Error is here *---*
}
func encode(with aCoder: NSCoder) {
aCoder.encode(blogList, forKey: "blogs")
}
}
Dans MainController.swift - Où mon tableview est
override func viewDidLoad() {
var path : String {
let manager = FileManager.default
let url = manager.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
return url.appendingPathComponent("blogs")!.path // I have a blogs.plist for this, doing it right?
}
}
Bouton de suivi
// Follow Button
@IBAction func followButtonClick(_ sender: UIButton!) {
// After Updating Table, Save Arrays
var success = false
// mainArray is array holding custom objects from json
success = NSKeyedArchiver.archiveRootObject(mainArray, toFile: "path") // If I dont use "" I get undeclared 'path'
if success {
print("Saved Blogs")
} else {
print("Didn't Save Blogs")
}
}
Réception de données à partir du serveur
// Retrieving Data from Server
func retrieveData() {
let getDataURL = "http://blogexample.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
// New
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
let blogList: NSObject = ((jsonArray[i]) as! NSObject).value(forKey: "blogList") as! NSObject
// Add Blog Objects to Main Array
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)")
}
Aussi, est défini 'chemin' et utilisé à droite? Je vous remercie!
Vous décoder un objet '[Blog]', mais en faisant passer l'objet la méthode 'init (coder' qui attend' NSCoder'.) C'est une incompatibilité de type classique Btw: Votre méthode 'retrieveData()' est plutôt laide.Ne pas utiliser 'NSMutableArray' et' .mutableContainers'. omettez le paramètre 'options' et transtypez le résultat en' [[String: Any]] ', puis remplacez la boucle par' pour item dans jsonArray' et les lignes dans le corps par exemple 'let bID = item ["id"] comme! Chaîne C'est beaucoup plus propre et plus efficace. – vadian
Comment puis-je corriger la différence de type, en remplaçant le blogList avec NSCoder, il donne la même erreur si c'est ce que vous vouliez dire. Pour retrieveData() je vous remercie de vouloir nettoyer ce code, j'ai juste l'intention de remplir une tableview avec cette information. Comment dois-je mettre à jour le code? – BroSimple
Les méthodes 'encoder/decoder' sont pour coder/décoder chaque propriété de la classe, pas pour la classe elle-même. – vadian