// code to add core data. have 2000 contacts to add. but adding 2000 data takes 45 secs.
func addData(contacts: [CNContact]) {
for data in contacts {
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(data.identifier, forKey: "contactIdentifier")
newUser.setValue(data.familyName, forKey: "finalName")
newUser.setValue(data.givenName, forKey: "givenName")
newUser.setValue(data.phoneNumbers.first?.value.value(forKey: "stringValue") as? String ?? "", forKey: "phoneNumber")
do {
try context.save()
} catch {
UIUtility.showErrorAlert("", message: Constants.errorMessage)
}
}
}
First move this line to before the loop since you only need to do it once
let context = appDelegate.persistentContainer.viewContext
Then replace the next two lines with
let newUser = NSEntityDescription.insertNewObject(forEntityName entityName, into: context)
So the start of the function should look like this
let context = appDelegate.persistentContainer.viewContext
for data in contacts {
let newUser = NSEntityDescription.insertNewObject(forEntityName entityName, into: context)
//...
Creating context and entity once (a bit more efficient) and saving the context once (much more efficient) is certainly faster.
func addData(contacts: [CNContact]) {
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)!
for data in contacts {
let newUser = NSManagedObject(entity: entity, insertInto: context)
newUser.setValue(data.identifier, forKey: "contactIdentifier")
newUser.setValue(data.familyName, forKey: "finalName")
newUser.setValue(data.givenName, forKey: "givenName")
newUser.setValue(data.phoneNumbers.first?.value.value(forKey: "stringValue") as? String ?? "", forKey: "phoneNumber")
}
do {
try context.save()
} catch {
UIUtility.showErrorAlert("", message: Constants.errorMessage)
}
}
Related
How to save data in offline using coredata, and if network comes(online) send the saved data to the API?
This is the code to save data:
func savePSaveInfo(cId: String, pId:String, createdBy:String, agep:String, languageId:String, emailId:String, mobileNumber:String,backendUpdate: Bool)
{
let nameObj = NSEntityDescription.insertNewObject(forEntityName: "SaveInfo", into: context!) as! SaveInfo
nameObj.cId = cId
nameObj.pId = pId
nameObj.createdBy = createdBy
nameObj.agep = agep
nameObj.languageId = languageId
nameObj.emailId = emailId
nameObj.mobileNumber = mobileNumber
nameObj.backendUpdate = backendUpdate
do{
try context!.save()
}catch{
print("not saved")
}
}
For inserting value in core data, I am sharing a example , you can set according to you data.
Step 1 :- Set the entity like this
Step 2:-
//MARK:- FOR CREATING NEW DATA
func createData(){
//As we know that container is set up in the AppDelegates so we need to refer that container.
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
//We need to create a context from this container
let managedContext = appDelegate.persistentContainer.viewContext
//Now let’s create an entity and new user records.
let userEntity = NSEntityDescription.entity(forEntityName: "User", in: managedContext)!
//final, we need to add some data to our newly created record for each keys using
let user = NSManagedObject(entity: userEntity, insertInto: managedContext)
user.setValue(txtFldUsername.text!, forKeyPath: "username")
user.setValue(txtFldEmail.text!, forKey: "email")
user.setValue(txtFldPassword.text!, forKey: "password")
retrieveData()
//Now we have set all the values. The next step is to save them inside the Core Data
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
Stop 3:- For fetching data
//MARK:- FOR RETRIEVING OR FETCHING THE DATA
func retrieveData() {
//As we know that container is set up in the AppDelegates so we need to refer that container.
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
//We need to create a context from this container
let managedContext = appDelegate.persistentContainer.viewContext
//Prepare the request of type NSFetchRequest for the entity
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "User")
do {
let result = try managedContext.fetch(fetchRequest)
arrUserDetails.removeAll()
for data in result as! [NSManagedObject] {
print(data.value(forKey: "username") as! String)
arrUserDetails.append(userData(username: (data.value(forKey: "username") as! String), email: (data.value(forKey: "email") as! String), password: (data.value(forKey: "password") as! String)))
}
tblView.reloadData()
} catch {
print("Failed")
}
}
Still there is any issue , let me know about the query
I am trying to save 2 different string entities to core data. Then display with a tableview my function below saves the data. Right now the code is being displayed on different tableview cells. Meaning entity a is being displayed on cell 1 and entity b is being displayed on cell 2. They are not being printed into the same cell.
var itemName2 : [NSManagedObject] = []
var itemName : [NSManagedObject] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemName.count
}
func enterData() {
let appDeldeaget = UIApplication.shared.delegate as! AppDelegate
let context = appDeldeaget.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Data", in: context)
let theTitle = NSManagedObject(entity: entity!, insertInto: context)
theTitle.setValue(hits.text, forKey: "hits")
let theTitle2 = NSManagedObject(entity: entity!, insertInto: context)
theTitle2.setValue(atBats.text, forKey: "atBATS")
do {
try context.save()
itemName.append(theTitle)
itemName.append(theTitle2)
} catch {
print("d")
}
self.theScores.reloadData()
hits.text = ""
hits.resignFirstResponder()
}
try this,
func enterData() {
let appDeldeaget = UIApplication.shared.delegate as! AppDelegate
let context = appDeldeaget.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Data", in: context)
let theTitle = NSManagedObject(entity: entity!, insertInto: context)
theTitle.setValue(hits.text, forKey: "hits")
//removed theTitle2 and set the second value in theTitle itself
theTitle.setValue(atBats.text, forKey: "atBATS")
do {
try context.save()
itemName.append(theTitle)
//add theTitle only
} catch {
print("d")
}
self.theScores.reloadData()
hits.text = ""
hits.resignFirstResponder()
}
I have faced this issue many times, but finally asking how to solve this in Swift and iOS. I have the same code block that runs against 2 different kind of objects, but I can't figure out, how to apply the code to either of the 2 object types with it being strongly typed. In other languages (like PHP) I would just put a generic var myVar = nil at the top of block and then set that to one or the other of those objects, then hang the code off of it, but swift won't let me do that.
How do you handle this programming situation in Swift/iOS?
static func entitySetup(jsonObject: JSON, object: MyCoreDataEntityObject?) {
if let existingObj = object { // existingObj = a MyCoreDataEntityObject
existingObj.setValue(jsonObject["firstName"].stringValue, forKey: "firstName")
existingObj.setValue(jsonObject["lastName"].stringValue, forKey: "lastName")
existingObj.setValue(jsonObject["address"].stringValue, forKey: "address")
existingObj.setValue(jsonObject["phone"].stringValue, forKey: "phone")
} else { // newObj = NSManagedObject
let entity = NSEntityDescription.entity(forEntityName: "MyCoreDataEntityObject", in: self.context)
let newObj = NSManagedObject(entity: entity!, insertInto: self.context)
newObj.setValue(jsonObject["firstName"].stringValue, forKey: "firstName")
newObj.setValue(jsonObject["lastName"].stringValue, forKey: "lastName")
newObj.setValue(jsonObject["address"].stringValue, forKey: "address")
newObj.setValue(jsonObject["phone"].stringValue, forKey: "phone")
}
do {
try self.context.save()
} catch let error as NSError {
print("ERROR: Could not save \(error), \(error.userInfo)")
completionHandler(false)
}
}
Since both objects are NSManagedObject, you can do this:
let mangedObject: NSManagedObject
if let existingObj = object {
managedObject = existingObj
} else {
let entity = NSEntityDescription.entity(forEntityName: "MyCoreDataEntityObject", in: self.context)
managedObject = NSManagedObject(entity: entity!, insertInto: self.context)
}
managedObject.setValue(jsonObject["firstName"].stringValue, forKey: "firstName")
managedObject.setValue(jsonObject["lastName"].stringValue, forKey: "lastName")
managedObject.setValue(jsonObject["address"].stringValue, forKey: "address")
managedObject.setValue(jsonObject["phone"].stringValue, forKey: "phone")
do {
try self.context.save()
} catch let error as NSError {
print("ERROR: Could not save \(error), \(error.userInfo)")
completionHandler(false)
}
And as suggested, the four lines calling setValue can be simplified as:
for key in ["firstName", "lastName", "address", "phone"] {
managedObject.setValue(jsonObject[key].stringValue, forKey: key)
}
Try this
static func entitySetup(jsonObject: JSON, object: MyCoreDataEntityObject?) {
let newObject = object ?? NSManagedObject(entity: NSEntityDescription.entity(forEntityName: "MyCoreDataEntityObject", in: self.context)!, insertInto: self.context)
for key in ["firstName", "lastName", "address", "phone"] {
newObject.setValue(jsonObject[key].stringValue, forKey: key)
}
do {
try self.context.save()
} catch let error as NSError {
print("ERROR: Could not save \(error), \(error.userInfo)")
completionHandler(false)
}
}
When I try to save a relationship to core data it throws the above error in the title. I'm basically creating a messaging app and data model is attached. This is doing the same thing when trying to save to other relationships too. Can I save all of my data models at once or should I save one at a time and then go back and add the relationships after the model has been saved with its regular attributes. **Data Model Visual
static func save(sender: UserCD, message: String) -> Conversation? {
let convo: Conversation? = nil
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return convo
}
if #available(iOS 10.0, *) {
let context = appDelegate.persistentContainer.viewContext
let now = Date()
let messageEntity = NSEntityDescription.entity(forEntityName: "Message", in: context)
let newMessage = NSManagedObject(entity: messageEntity!, insertInto: context) as! Message
let conversationEntity = NSEntityDescription.entity(forEntityName: "Conversation", in: context)
let newConvo = NSManagedObject(entity: conversationEntity!, insertInto: context) as! Conversation
newMessage.setValue(UUID().uuidString, forKey: "messageId")
newMessage.setValue(message, forKey: "text")
newMessage.setValue(now, forKey: "timestamp")
newMessage.setValue(sender, forKey: "sender")
newConvo.setValue(UUID().uuidString, forKey: "conversationId")
newConvo.setValue(now, forKey: "startDate")
newConvo.setValue(now, forKey: "lastMessageDate")
newConvo.addMessage(message: newMessage)
sender.addMessage(message: newMessage)
sender.addConversation(conversation: newConvo)
do {
try newMessage.managedObjectContext?.save()
try sender.managedObjectContext?.save()
try newConvo.managedObjectContext?.save()
return newConvo
} catch {
let saveError = error as NSError
print("Failed to save conversastion: \(saveError.debugDescription)")
}
}
return convo
}
It fails on line "newConvo.addMessage(message: newMessage)"
#NSManaged public var messages: Message?
func addMessage(message: Message) {
let messages = self.mutableSetValue(forKey: "messages")
messages.add(message)
}
The error message
The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet
is pretty clear:
You declared messages as to-one relationship Message.
The sender of the method addMessage must be a to-many relationship Set<Message>
I want to save my data to core data when a button is clicked here is my action button code now let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let entity = NSEntityDescription.entityForName("Cart", inManagedObjectContext: context)
let cart = Cart(entity: entity!, insertIntoManagedObjectContext: context) but the only problem now is that i dont how to save here is my code to parse json
Alamofire.request(.GET, url!, headers: headers).responseJSON { (response) in
let result = response.result
if response.result.isSuccess{
let jsonObj = JSON(result.value!)
if let x = jsonObj["Items"].array {
x.forEach
{
if let uw = ($0["name"]).string{
print(uw)
let qw = ($0["image"]).string
if let rw = ($0["price"]).int{
if let hu = ($0["id"]).int{
print(hu)
let foo = Rest(name: uw, imageUrl: qw!, price: "₦\(rw)")
self.rest.append(foo)
}
}
}
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
actInd.stopAnimating()
}
}
}
So i have an array called rest which is where i want get data for the tableview. I want to save information of each cell tapped into coredata here is a screenshot of the app
So when the sure button is tapped it saves the item to coredata
here is my code incase you neecode
Try this, adapted to your code.
In the portion that you have (...let app=...) replace it by this:
let app2 = UIApplication.sharedApplication().delegate as! UIApplicationDelegate
if let context2 = app2.managedObjectContext {
let cart2 = NSEntityDescription.insertNewObjectForEntityForName("Cart", inManagedObjectContext: context2) as! Cart
cart2.name = self.res.name
cart2.price = self.res.price
cart2.url = self.res.imageUrl
cart2.id = ""
// Perform a save operation
do {
try context2?.save()
} catch {
let saveError = error as NSError
print(saveError)
}
}
Let me know if this works.
Cheers
Just an example here when you want to save your data in coredata. You have to create entity/model and all the setup for core data elements. For details please study https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial
func saveName(name: String) {
//1
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext:managedContext)
let person = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
//3
person.setValue(name, forKey: "name")
//4
do {
try managedContext.save()
//5
people.append(person)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}