简体   繁体   中英

Saving text from a UITextView using core data Swift

Completely new to iOS Development and Swift so I hope you'll bear with me. I'm creating a simple note app based off the apple Notes app.

I am also completely new to core data. What I'm trying to do is save the text from the UITextView. Strangely enough this works but only after I remove this piece of code,

if let detail: Note = self.detailItem {

                if let textView = self.textView {
                    textView.text = detail.noteText
                }

create a new note, then reintroduce the code...

func configureView() {
        // Update the user interface for the detail item.
        if let detail: Note = self.detailItem {
            if let label = self.detailDescriptionLabel {
                label.text = detail.timeStamp.description
            }

        if let detail: Note = self.detailItem {

            if let textView = self.textView {
                textView.text = detail.noteText
            }

        }
    }

For a note that has already been created, this code is able to save the text in the textView. If I try to create a new note and then open it, the code above will crash the app.

This error comes up: Thread 1: EXC_BAD_ACCESS(code=1, address=0x0)

I think I have made a silly mistake like not initializing my model "Note.swift" class.

I'm using the boilerplate code for a master detail app with core data. I also have two "insertNewObject" functions. One is in the MasterViewController and the other is in the DetailViewController.

DetailViewController.swift

 func insertNewObject(sender: AnyObject) {
        let context = self.fetchedResultsController.managedObjectContext
        let entity = self.fetchedResultsController.fetchRequest.entity!
        let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context) as! NSManagedObject

Here's the full code including the fetchedResultsController.

  func insertNewObject(sender: AnyObject) {
        let context = self.fetchedResultsController.managedObjectContext
        let entity = self.fetchedResultsController.fetchRequest.entity!
        let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context) as! NSManagedObject

        // If appropriate, configure the new managed object.
        // Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.
        newManagedObject.setValue(self.textView.text, forKey: "noteText")
        newManagedObject.setValue("I changed", forKey: "noteTitle")

        // Save the context.
        var error: NSError? = nil
        if !context.save(&error) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }
    }

    // MARK: - Fetched results controller

    var fetchedResultsController: NSFetchedResultsController {
        if _fetchedResultsController != nil {
            return _fetchedResultsController!
        }

        let fetchRequest = NSFetchRequest()
        // Edit the entity name as appropriate.
        let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: self.managedObjectContext!)
        fetchRequest.entity = entity

        // Set the batch size to a suitable number.
        fetchRequest.fetchBatchSize = 20

        // Edit the sort key as appropriate.
        let sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
        let sortDescriptors = [sortDescriptor]

        fetchRequest.sortDescriptors = [sortDescriptor]

        // Edit the section name key path and cache name if appropriate.
        // nil for section name key path means "no sections".
        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
        aFetchedResultsController.delegate = self
        _fetchedResultsController = aFetchedResultsController

        var error: NSError? = nil
        if !_fetchedResultsController!.performFetch(&error) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }

        return _fetchedResultsController!
    }    

    var _fetchedResultsController: NSFetchedResultsController? = nil

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

    override func viewWillDisappear(animated: Bool) {
        detailItem!.noteText = self.textView.text
        detailItem!.noteTitle = "I changed"

        var error: NSError? = nil
        if !self.managedObjectContext!.save(&error) {
            abort()
        }
    }

I was able to figure it out. The issue was that I didn't set a value for "noteText" when I first called func insertNewObject(sender: AnyObject) . This resulted in a nil being set to textView.text and therefore crashing the app. Thanks for your help @BaseZen!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM