2

My codes are like:

import Foundation
import CoreData
import UIKit

class BARCODEDIMENSION: NSManagedObject {
  @NSManaged var barcode: String
  @NSManaged var catid: Int32
  @NSManaged var favorite: Bool
  @NSManaged var name: String
  @NSManaged var subcatid: Int32

  class func getProducts(moc: NSManagedObjectContext) {

    var url: NSURL! = NSURL(string: "link")
    var request = NSURLRequest(URL: url)
    var response: NSURLResponse ?
      var error: NSError ?
        var data: NSData ? = NSURLConnection.sendSynchronousRequest(request, returningResponse: & response, error: & error)


    if let data: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: & response, error: & error) {

      var parsingError: NSError ?
        if
      let rateDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: & parsingError) as ? NSArray {

        for i in 0.. < rateDictionary.count {
          let row: NSDictionary = rateDictionary[i] as!NSDictionary;

          var name: String = row["name"] as!String
          var catid: Int32 = Int32(row["catid"] !.integerValue)
          var subcatid: Int32 = Int32(row["subcatid"] !.integerValue)
          var barcode: String = row["barcode"] as!String
          var favorite: Bool = false

          insertBarcodeDimension(moc, barcode: barcode, catid: catid, favorite: favorite, name: name, subcatid: subcatid)

        }
      }
    }
  }

  class func insertBarcodeDimension(moc: NSManagedObjectContext, barcode: String, catid: Int32, favorite: Bool, name: String, subcatid: Int32) - > BARCODEDIMENSION {

    let newItem = NSEntityDescription.insertNewObjectForEntityForName("BARCODEDIMENSION", inManagedObjectContext: moc) as!BARCODEDIMENSION


    newItem.barcode = barcode
    newItem.name = name
    newItem.catid = catid
    newItem.subcatid = subcatid
    newItem.favorite = favorite

    var error: NSError ?
      if (moc.save( & error)) {
        println(error ? .localizedDescription)
      }

    return newItem
  }


}

In the code above as you can see when i call getProducts(moc) function. It is adding one by one. I'm successfully adding Items to core data by this way. But there is a problem on speed. Its too slow to add for example 20000 items one by one. I wonder if there is another way to add directly the array into the core data which is already taken on rateDictionary.

  • 1
    The Core Data Programming Guide has an entire chapter about "Efficiently Importing Data". That could be a good place to start ... – Martin R May 09 '15 at 14:33
  • 1
    I already readed that but I didn't understand. Sorry because I started new to write codes on swift. If you have an example It would be better. – Kemal Müderrisoğlu May 09 '15 at 14:53
  • 1
    You are better off learning how to at least read Objective-C. All of the frameworks are still written in Objective-C and if you cannot read them you are going to have a very hard time. Expend the energy now. – Marcus S. Zarra May 09 '15 at 15:15
  • All the words that you are telling is true but now I should do it urgently this is why I asked here. Also Objective-C or Swift is not my job. I'm just trying something. After this small project, I'm not thinking to look at it again. As I said it is urgent so if you help me thanks to you. – Kemal Müderrisoğlu May 10 '15 at 15:05
  • This website is for people looking for help with their problems. It is not a website for people to write your code for you. If you can't be bothered to put the energy in to learn it then why should we bother trying to help you? – Fogmeister May 10 '15 at 20:09
  • [Swift example for inserting an arbitrarily large data array into Core Data](http://stackoverflow.com/a/32034101/3681880) – Suragch Aug 16 '15 at 11:02

1 Answers1

3

The code is currently saving the context for each and every new BarCodeDimension. You should batch up the updates. To do so remove this code from the insertBarcodeDimension function:

var error: NSError ?
  if (moc.save( & error)) {
    println(error ? .localizedDescription)
  }

and put it instead in the for loop of getProducts, after the insertBarcodeDimension... call, in an if statement to ensure it happens only every X times through the loop.

if i % 100 == 0 {
    var error: NSError ?
    if (moc.save( & error)) {
        println(error ? .localizedDescription)
    }
}

Here I've used a value for X of 100, but adjust this figure through trial and error to trade off speed against memory footprint. That will probably speed things significantly.

The other suggestion in the document referred to in comments is to set the undoManager to nil. If you are confident that your moc does not need an undo manager, then amend the code which initialises your moc to include:

moc.undoManager = nil

Or if it's more expedient, put it in at the start of the getProducts function.

pbasdf
  • 21,386
  • 4
  • 43
  • 75
  • @pbasdf, I appreciate you taking the time to answer this question. The high rep users just say "go look it up yourself" or "learn Objective-C first" or "don't ask me to do it for you". We need more specific Swift answers like this one. – Suragch Aug 16 '15 at 06:02