问题
I'm making a converter app. I want to save the conversion historic. I saw this tutorial and it works fine but when I tried to use it on my app I'm getting a SIGABRT.
Could not cast value of type '__NSCFDictionary' (0x57945c) to 'NSMutableArray' (0x5791c8)
I'm getting this at
notesArray = try NSPropertyListSerialization.propertyListWithData(data, options: NSPropertyListMutabilityOptions.MutableContainersAndLeaves, format: nil) as! NSMutableArray
EDIT:
AppDelegate:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var plistPathInDocument:String = String()
func preparePlistForUse(){
let rootPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, .UserDomainMask, true)[0]
plistPathInDocument = rootPath.stringByAppendingString("/historic.plist")
if !NSFileManager.defaultManager().fileExistsAtPath(plistPathInDocument){
let plistPathInBundle = NSBundle.mainBundle().pathForResource("historic", ofType: "plist") as String!
do {
try NSFileManager.defaultManager().copyItemAtPath(plistPathInBundle, toPath: plistPathInDocument)
}catch{
print("Error occurred while copying file to document \(error)")
}
}
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
self.preparePlistForUse()
return true
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
self.preparePlistForUse()
}
}
ViewController:
import UIKit
class ViewControllerHistorico: UITableViewController {
var notesArray:NSMutableArray!
var plistPath:String!
override func viewWillAppear(animated: Bool) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
plistPath = appDelegate.plistPathInDocument
// Extract the content of the file as NSData
let data:NSData = NSFileManager.defaultManager().contentsAtPath(plistPath)!
do{
notesArray = try NSPropertyListSerialization.propertyListWithData(data, options: NSPropertyListMutabilityOptions.MutableContainersAndLeaves, format: nil) as! NSMutableArray
}catch{
print("Error occured while reading from the plist file")
}
self.tableView.reloadData()
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell:UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("cellIdentifier")
cell.textLabel!.text = notesArray.objectAtIndex(indexPath.row) as? String
return cell
}
override func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int{
return notesArray.count
}
override func tableView(tableView: UITableView,
commitEditingStyle editingStyle: UITableViewCellEditingStyle,
forRowAtIndexPath indexPath: NSIndexPath){
// remove the row from the array
notesArray.removeObjectAtIndex(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
notesArray.writeToFile(plistPath, atomically: true)
}
}
historic.plist
回答1:
You are trying to cast a Dictionary
into a NSMutableArray
.
You could save it as a Dictionary by changing your code to:
var notesDict: NSMutableDictionary = try NSPropertyListSerialization.propertyListWithData(data, options: NSPropertyListMutabilityOptions.MutableContainersAndLeaves, format: nil) as! NSMutableDictionary
回答2:
Believe I had this same problem, and from your code it looks like we also copied from the same example. I prepared my plist file and XCode did let my call the root an array, but my data really wasn't in an array format, it was a dictionary, and that is the format in which it was saved.
When I reloaded the plist file, NSPropertyListSerialization was smart enough to see my data was really a dictionary, and so the cast to NSMutableArray failed (BOOM!). Sure enough, when I opened the saved plist file and examined it, the XML clearly showed it had been saved as a dictionary. So, think about the data you are saving and if it really is a dictionary, change the cast to NSMutableDictionary and unpack your data using that format.
来源:https://stackoverflow.com/questions/34111323/swift-sigabrt-cast-value-of-type-nscfdictionary-to-nsmutablearray