Swift 3 iOS 10, versucht Array mit benutzerdefinierten Objekten in NSKeyedArchiver zu speichern, grundsätzlich versucht, die Tabellenansicht zu speichern, nachdem der Benutzer die Schaltflächen verwendet, um zwischen Abschnitten zu wechseln. Ich habe mehrere Post versucht, um das Problem zu lösen, aber kein Glück, jetzt versuche ich es selbst NSCoding und NSKeyedArchiver zu tun.Swift: Fehler in NSKeyedArchiver
Fehler:
Cannot convert value of type '[Blog]' to expected argument type 'NSCoder'
Fehler ist in Code in Blog.swift, Code, der NSCoding und mein Blog Objekte
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")
}
}
In MainController.swift Griffe - Wo ist mein Tableview ist
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?
}
}
Folgen Knopf
// 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")
}
}
Daten vom Server empfangen
// 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)")
}
Auch ist 'Pfad' definiert und verwendet nicht wahr? Vielen Dank!
Sie Dekodieren eines Objekts '[Blog]' aber dann vorbei, das Objekt in die 'init (coder' Methode, die' NSCoder' erwartet. Das ist eine klassische Typabweichung. Btw: Deine 'reveetData()' Methode ist ziemlich hässlich. Benutze 'NSMutableArray' und' .mutableContainers' nicht result? Lassen Sie den 'options' -Parameter aus und werfen Sie das Ergebnis auf' [[String: Any]] ''. Ersetzen Sie dann die Schleife durch 'for item in jsonArray' und die Zeilen im body beispielsweise durch' let bID = item ["id"] als! String'. Das ist viel sauberer und effizienter. – vadian
Wie behebe ich den Typ Mismatch, Ersetzen der BlogList mit NSCoder, gibt es den gleichen Fehler, wenn das, was Sie meinten. Für retrieveData() danke, dass ich den Code sauber machen wollte, plane ich nur, eine Tabelle mit diesen Informationen zu füllen. Wie sollte ich den Code aktualisieren? – BroSimple
Die 'encoder/decoder'-Methoden dienen zum Codieren/Decodieren jeder Eigenschaft der Klasse, nicht für die Klasse selbst. – vadian