Kodeco Forums

Getting Started with Core Data Tutorial

Learn the basics of building the data layer of your iOS app with this getting started with Core Data tutorial.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1550-getting-started-with-core-data-tutorial

Hi Pietro
I am trying to learn swift, and I have found your wonderful tutorial. It works perfect, until I made the changes to use CoreData. In that moment, it gave me two errors in AppDelegate.swift: “Extra argument ‘error’ in call”, and “Argument passed to call that takes no arguments”
Can you help me?
Thanks in advance
Carlos

It almost sounds like you were trying to use a Swift 1 style Core Data method. One that used to take an NSErrorPointer instead of the new do-try-catch syntax shown in this tutorial. What line specifically is giving you this error?

Hello

I have one question. How to access the database table in which there are the data stored using Core data or what library should be used to view this.
Thanks

Thank you for this tutorial. I have a question about storing map annotations using CoreData. I’m trying to create an app that allows user to save their current location as an annotation, and I then want the user to be able to see all their locations from pervious times. I’m doing this to store bird sightings. I’m not quite sure how to save this data and load it each time the app loads. I then want to send this data to a server such that I can access all locations that people have stored. Thanks again.

Although not affecting the running of the app, I am getting the following error right after self.saveName(textField!.text!) in the saveAction(). I am running 10.110.4 with Xcode 7.3. If I commented out self.saveName(textField!.text!), then the error disappear.

2016-04-24 23:33:02.047 HitList[3108:231532] _BSMachError: (os/kern) invalid capability (20)
2016-04-24 23:33:02.047 HitList[3108:231532] _BSMachError: (os/kern) invalid name (15)

Any idea?

Tom

I am running the app up to the point of your tutorial just before the fetching data. The app crashes as soon as I try to save the text string.

failureReason String "There was an error creating or loading the application\'s saved data."

code is here: viewcontroller - Pastebin.com

Hi
This may be a bit off topic but would it possible to read core data entries through Unity
I have a native iOS app made in xCode.
It is looking to be ported to unity for easy of cross platform builds and updating.
If we do this will we be able to read existing customers data that they have already entered recorded using the app?

cheers

Paul

Very interesting tuto, many tanks. Starting from that “flat file” tuto, i could not find an example of a RELATED FILES application. It looks easy to build the Coredata structure of a 2 related tables, but after : what is the right SQLITE query to ask for the owners ( table owners ) of a car modùle ( table cars)
Cheers

Hi Pietro,
Having a problem passing a String variable into a Core Data fetch request predicate. If I pass a String literal in it works fine but an identical String variable taken from a pickerList fails to return data. Any help greatly appreciated.
Kind regards
Tim

Hi Pietrorea,

I built the first app using the sample without using the core data model. I can execute it and when I save no data is showing in my table view list. Here is my code:

//
// ViewController.swift
// HitList
//
// Created by James Steckel on 5/17/16.
// Copyright © 2016 ufosearch. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITableViewDataSource {
var names = String

@IBOutlet weak var tableView: UITableView!




@IBAction func addName(sender: AnyObject) {
    
    let alert = UIAlertController(title: "New Name", message: "Add a new name", preferredStyle: .Alert)
    
    let saveAction = UIAlertAction(title: "Save", style: .Default, handler: { (action:UIAlertAction) -> Void in
        
        let textField = alert.textFields?.first
        self.names.append(textField!.text!)
        self.tableView.reloadData()
        
    })
    let cancelAction = UIAlertAction(title: "Cancel", style: .Default) { (action: UIAlertAction) -> Void in
    }
    
    alert.addTextFieldWithConfigurationHandler {
        (textField: UITextField) -> Void in
    }
    
    alert.addAction(saveAction)
    alert.addAction(cancelAction)
    
    presentViewController(alert, animated: true, completion: nil)
    
    
}





override func viewDidLoad() {
    super.viewDidLoad()
    title = "\"The List\""
    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}

  func viewWillAppear() {
    title = "\"The List\""
    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}

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





func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    
    return 5
    
}



// return Int, how many rows
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return names.count
}

// what are the contents of each cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell")

    cell!.textLabel!.text = names[indexPath.row]
    
    return cell!
    
}

}

Hi, Thanks for the great tutorial. Worked perfectly. I need to store a list of items rather than string / int attributes for an entitiy.

Ex:
I have an Asset Class with some n properties, some of them are lists like (where AssetValues is another class):

class Asset{ var assetId: String = "" ... var assetValues = [AssetValues]() }
Now When my app loads for first time, i can do few things to persist the data:

  1. Store each asset as we did with the person names - facing issue to store this assetValues Array
  2. Store All Assets, as an Array of type Asset with a key name so that I can retrieve all the items using this key

Which method is better? I think 1 is better. But how do i solve that issue of assetValue Array?

Awaiting your reply
Thanks again!

Can we please get a link to the Objective-C version of this tutorial. I appreciate it is no longer supported but it would be good to have as a frame of reference, especially considering parts 2 and 3 of this tutorial are still available in Obj-C.

It would be great to show another method for saving attributes of a managed object. Might I recommend showing how to use the Edit mode, make a change, and then have the change persist when the done button is clicked to exit edit mode. Exactly like the Contacts app on the IPhone.

1 Like

new coder here.

it bugs me to ask for help because usually it is just a typo somewhere but my eyes are blurry from staring at it.

Running into an “Unexpectedly found NIL while unwrapping an optional value” error related to the line that says " cell!.textLabel!.text = names[indexPath.row]

here is the current code. Any help from anyone would be greatly appreciated.

Colin

//
// ViewController.swift
// Speakers
//
// Created by Dad on 2016-07-17.
// Copyright © 2016 Dad. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

var names=[String]()


override func viewDidLoad() {
    super.viewDidLoad()
    title="\"The List\""
    tableView.registerClass(UITableViewCell.self,
                            forCellReuseIdentifier: "CELL")
    
    // Do any additional setup after loading the view, typically from a nib.
}


// Mark: UITableViewDataSource
func tableView(tableView:UITableView,
               numberOfRowsInSection section: Int)-> Int {
    return names.count
}

func tableView(tableView:UITableView,
               cellForRowAtIndexPath
    indexPath:NSIndexPath)-> UITableViewCell {
    
    let cell =
    tableView.dequeueReusableCellWithIdentifier("Cell")
    
    
    cell!.textLabel!.text = names[indexPath.row]
    
    return cell!
}



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

@IBAction func addName(sender: AnyObject) {
    
    //Implement the addName IBAction
    
    
    let alert = UIAlertController(title: "New Name",
                                  message: "Add a new name",
                                  preferredStyle: .Alert)
    
    let saveAction = UIAlertAction(title: "Save",
        style: .Default,
        handler: { (action:UIAlertAction) -> Void in
                                    
        let textField = alert.textFields!.first
        self.names.append(textField!.text!)
        self.tableView.reloadData()
    })
    
    let cancelAction = UIAlertAction(title: "Cancel",
        style: .Default) { (action: UIAlertAction) -> Void in
    }
    
    alert.addTextFieldWithConfigurationHandler {
        (textField: UITextField) -> Void in
    }
    
    alert.addAction(saveAction)
    alert.addAction(cancelAction)
    
    presentViewController(alert,
                          animated: true,
                          completion: nil)
}

}

Not sure if this is your problem or not, but you have “CELL” and “Cell” as your identifiers.

1 Like

Fantastic
!

I thought it was a typo but couldn’t find it.

Thanks for the help jj!!!

All is working (for now!)

Has this tutorial been updated to Swift 3.0 and persistent context? Developing in Xcode 8 iOS 10 and I get stuck at adding the saveName() function with many errors.

@spoa94

I just finished following this tutorial using Swift 3 on Xcode 8 (target iOS 10). Below is an update to the saveName() function.

// 1
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegete.persistentContainer.viewContext

// 2
let entity = NSEntityDescription.entity(forEntityName: "Person",
                                        in: managedContext)
let person = NSManagedObject(entity: entity!, insertTo: managedContext)

// 3
person.setValue(name, forKey: "name")

// 4
do {
    try managedContext.save()
    people.append(person)
} catch let error as NSError {
    print("Could not save \(error), \(error.userInfo)")
}

Most of the other conversions, I was able to do with suggestions from Xcode. The other difficulty I faced was with loading the core data upon startup in viewDidAppear. Below is what I got working after googling.

override func viewDidAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // 1
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let managedContext = appDelegate.persistentContainer.viewContext

    // 2
    let fetchRequest : NSFetchRequest<Person> = Person.fetchRequest()

    // 3
    do {
        let results = try managedContext.fetch(fetchRequest)
        people = results as [NSManagedObject]
    } catch let error as NSError {
        print("Could not fetch \(error), \(error.userInfo)")
    }
    tableView.reloadData()
}

If you receive the error Use of undeclared type: ‘Person’, select the file HitList.xcdatamodelId in the document viewer pane on the left of Xcode and select the Person entity. In the Data Model Inspector (right side of Xcode next to the icon with the question mark in a circle) under the Class section, make sure that Codegen is set to Class Definition. Save (cmd + s) and build (cmd + b).

getting error in AppDelegate class

let modelURL = NSBundle.mainBundle().URLForResource(“HitList”, withExtension: “momd”)!

in this line

the error is:

fatal error: unexpectedly found nil while unwrapping an Optional value.

please help