2016-11-25 10 views
0

最初はフランスから来たので、私の英語はすみません。コアデータで値を更新できません

第2に、私は開発が新しく、データを追加してコアデータを表示した後にコードを開発しました。それはworks.ok

しかし私は更新が欲しいのですが、私はなぜ私は私の価値を更新できないのか分からない問題があります。 「致命的なエラー:オプションの値をアンラッピングしている間に予期せぬエラーが発生しました」

私は1週間から多くの解決策を試しましたが、問題は見つかりませんでした。誰かが私を助けてくれてありがとう!少しでも助け:)これは私のコード(SWIFT 2.3)である

import CoreData 
import UIKit 

class DetailViewController: UIViewController { 

@IBOutlet var Label: UILabel! 
@IBOutlet var Detail: UITextView! 
@IBOutlet weak var Date: UILabel! 
@IBOutlet weak var Id: UILabel! 

var dataNom = "" 
var dataDetail = "" 
var dataDate = "" 
var dataId = "" 

override func viewDidLoad() { 
    super.viewDidLoad() 

    Label.text = dataNom 
    Detail.text = dataDetail 
    Date.text = dataDate 
    Id.text = dataId 

    // Do any additional setup after loading the view 

} 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { 

    if segue.identifier == "ModifierDetail" { 

     if let destination = segue.destinationViewController as? ModifierViewController { 

      destination.modifierNom = dataNom 
      destination.modifierId = dataId 
      destination.modifierDetail = dataDetail 
      destination.modifierDate = dataDate 

     } 

    } 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

/* 
// MARK: - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    // Get the new view controller using segue.destinationViewController. 
    // Pass the selected object to the new view controller. 
} 
*/ 

} 

:セルのショーの詳細は

import UIKit 
import CoreData 

class ProduitTableViewController: UITableViewController { 

@IBOutlet var table: UITableView! 

var produits = [NSManagedObject]() 

func refreshStories(refreshControl: UIRefreshControl) { 

     produits.removeAll() 

     fetchData() 
     self.table.reloadData() 
     refreshControl.endRefreshing() 

} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.fetchData() 
    self.table.addSubview(self.refreshControl!) 

    self.refreshControl?.addTarget(self, action: #selector(ProduitTableViewController.refreshStories(_:)), forControlEvents: UIControlEvents.ValueChanged) 

} 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 

} 

func fetchData() { 

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 

    let managedContext = appDelegate.managedObjectContext 

    //2 
    let fetchRequest = NSFetchRequest(entityName: "Produits") 
    let sort = NSSortDescriptor(key:"dateAjout", ascending:true) 
    fetchRequest.sortDescriptors = [sort] 

    //3 
    do { 
     let results = try managedContext.executeFetchRequest(fetchRequest) 
     produits = results as! [NSManagedObject] 

    } catch let error as NSError { 
     print("Donnees non recu \(error), \(error.userInfo)") 
    } 

} 

// MARK: - Table view data source 

override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    // #warning Incomplete implementation, return the number of sections 
    return 1 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // #warning Incomplete implementation, return the number of rows 
    return self.produits.count 
} 

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") 

    let produit = produits[indexPath.row] 

    cell!.textLabel!.text = produit.valueForKey("nom") as? String 

    /* 
    let id = produit.valueForKey("id") as? String 
    let date = produit.valueForKey("date") as? NSDate 
    let localNotification = UILocalNotification() 
    localNotification.userInfo = ["id" : id!] 
    localNotification.soundName = UILocalNotificationDefaultSoundName 
    localNotification.alertBody = "expiré" 
    localNotification.fireDate = date 
    UIApplication.sharedApplication().scheduleLocalNotification(localNotification) 
    UIApplication.sharedApplication().applicationIconBadgeNumber += 1 
    */ 

    return cell! 
} 

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { 

    let supprimer = UITableViewRowAction(style: .Normal, title: "Suppr.") { action, index in 

     let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
     let moc = appDelegate.managedObjectContext 

     // 3 
     moc.deleteObject(self.produits[indexPath.row]) 
     appDelegate.saveContext() 

     // 4 
     self.produits.removeAtIndex(indexPath.row) 
     tableView.reloadData() 

    } 
    supprimer.backgroundColor = UIColor.redColor() 

    let update = UITableViewRowAction(style: .Normal, title: "Modifier") { action, index in 

    } 
    update.backgroundColor = UIColor.blueColor() 

    return [supprimer] 
} 

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { 
    // the cells you would like the actions to appear needs to be editable 
    return true 
} 

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 

} 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { 

    if segue.identifier == "showDetail" { 

     if let destination = segue.destinationViewController as? DetailViewController { 

      let row = table.indexPathForSelectedRow?.row 
      let produit = produits[row!] 

      let nom = produit.valueForKey("nom") as? String 
      let id = produit.valueForKey("id") as? String 
      let detail = produit.valueForKey("detail") as? String 
      let date = produit.valueForKey("date") as? NSDate 

      let time = date 
      let formatter = NSDateFormatter() 
      formatter.dateFormat = "dd-MM-YY HH:mm" 
      let formatteddate = formatter.stringFromDate(time!) 

      destination.dataNom = nom! 
      destination.dataId = id! 
      destination.dataDetail = detail! 
      destination.dataDate = formatteddate 

     } 

    } 

} 

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    if table.cellForRowAtIndexPath(indexPath) != nil { 

     self.performSegueWithIdentifier("showDetail", sender: self) 

    } 

} 

} 

:テーブルビューでのショーのため

最後に更新/詳細を変更する:

import UIKit 
import CoreData 

class ModifierViewController: UIViewController { 

@IBOutlet weak var Nom: UITextField! 
@IBOutlet weak var Detail: UITextView! 
@IBOutlet weak var Date: UITextField! 

var Produits: NSManagedObject! 
var managedContext: NSManagedObjectContext! 

var modifierNom = "" 
var modifierDetail = "" 
var modifierDate = "" 
var modifierId = "" 

override func viewDidLoad() { 
    super.viewDidLoad() 

    Nom.text = modifierNom 
    Detail.text = modifierDetail 
    Date.text = modifierDate 

    // Do any additional setup after loading the view. 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

@IBAction func Annuler(sender: UIBarButtonItem) { 

    navigationController?.popViewControllerAnimated(true) 

} 


@IBAction func Modifier(sender: UIButton) { 


    let fetchRequest = NSFetchRequest(entityName:"Produits") 
    fetchRequest.predicate = NSPredicate(format: "nom = %@", modifierNom) 

    do { 

     let list = try managedContext.executeFetchRequest(fetchRequest) as! [Produit] 
     if list.count == 0 // Check notificationId available then not save 
     { 

      let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Produits", inManagedObjectContext: managedContext) 
      newManagedObject.setValue(modifierNom, forKey: "nom") 

     } 
     // success ... 
    } catch let error as NSError { 
     // failure 
     print("Fetch failed: \(error.localizedDescription)") 
    } 

} 
/* 
// MARK: - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    // Get the new view controller using segue.destinationViewController. 
    // Pass the selected object to the new view controller. 
} 
*/ 

} 

私は、この他のファイルを作成している:あなたがコメントで述べたように

import Foundation 
import CoreData 


@objc(Produit) 
class Produit: NSManagedObject { 
@NSManaged var nom:String! 
} 
+0

私は今、その長いと申し訳ありません –

+0

あなたは、どの行でコードがクラッシュするのですか? – FelixSFD

+0

[任意の値をアンラッピングしている間に "致命的なエラーが予期せず見つからない"とはどういう意味ですか?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil- while-unwrap-an-optional-valu) – FelixSFD

答えて

0

を、この行がクラッシュが発生します。

let list = try managedContext.executeFetchRequest(fetchRequest) as! [Produit] 

あなたが知らないのでラインは、安全ではないことを、あれば[Prodiut]へのキャストは常に成功します。

一般的に、1000%がわからない場合は、強制的に(as!)または強制解除しないでください(!)。

は、あなたが guardを使用することができ、安全にキャストするには:

guard let list = try managedContext.executeFetchRequest(fetchRequest) as! [Produit] else { 
    //do some error handling here and then return 
    return 
} 

をその後、あなたは安全にlistを使用することができます。

オプションが何であるか、クラッシュなしで安全にそれらを処理する方法を理解することは、本当に重要です。

+1

通常、既知のエンティティを特定のサブクラスにフェッチすると、フェッチはそのクラスの非オプション配列を100%返します。またはエラーをスローします。私はそれが 'Produit'と' Produits'の不一致だと思う。 – vadian

+0

@vadian thanks。それを知らなかった。コアデータではあまり働いていません。 – FelixSFD

+0

本当にありがとう、私はこれを試してみます。 –

関連する問題