swift - How to check CoreData exists - ios

I am trying to check if the item exits in coredata if not add it to coredata. How am I going to implement the check?
var authorList = [AuthorList]()
let articleEntity = NSEntityDescription.entityForName("AuthorList", inManagedObjectContext: self.context!)
let newAuthor = AuthorList(entity: articleEntity!, insertIntoManagedObjectContext: self.context!)
//if authorID is not in coredata then....
newAuthor.authorName = authorName!
newAuthor.authorImage = authorImage!
newAuthor.newspaperName = newspaperName!
newAuthor.newsPaperImage = newsPaperImage!
newAuthor.authorID = authorID!

In case any body looking for swift 3 solution.:
Swift 3
Xcode 8x
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Friends")
let predicate = NSPredicate(format: "friendName == %#", frd.text)
request.predicate = predicate
request.fetchLimit = 1
do{
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.managedObjectContext
let count = try context.count(for: request)
if(count == 0){
// no matching object
print("no present")
}
else{
// at least one matching object exists
print("one matching item found")
}
}
catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}

Used NSPredicate to filter articlID in coredata...
let fetchRequest = NSFetchRequest(entityName: "FavArticles")
let predicate = NSPredicate(format: "articleID == %ld", articleID!)
fetchRequest.predicate = predicate
let fetchResults = self.context!.executeFetchRequest(fetchRequest, error: nil) as? [FavArticles]
if fetchResults!.count > 0 {
println("already favd")
}

func checkIfItemExist(id: String) -> Bool {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Products")
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: "productId == %#", id)
do {
let count = try DatabaseHelper.context!.count(for: fetchRequest)
if count > 0 {
return true
} else {
return false
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
return false
}
}

Related

How to get specfic data of row as dictionary by search in coredata

i had added this code for search via product_id in coredata but that returns all records i want to just get specific data from row that contain that product_id
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "CartEntity")
let predicate = NSPredicate(format: "product_id == %#", "\(Product_id)")
request.predicate = predicate
request.fetchLimit = 1
do{
let count = try managedContext.count(for: request)
if(count == 0){
// no matching object
print("no")
self.savecoredata()
}
else{
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "CartEntity")
request.returnsObjectsAsFaults = false
do {
let result = try managedContext.fetch(request)
for dataresult in result as! [NSManagedObject] {
let userName = dataresult.value(forKey: "proname") as! String
let age = dataresult.value(forKey: "price") as! String
print("User Name is : "+userName+" and price is : "+age)
print(datastored)
}
} catch {
print("Fetching data Failed")
}
print("yes")
// deleteFeed(id: "\(Product_id)")
// first delete old and than insert new id
}
}
catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
The problem is that you have to different requests, first you use one with a predicate and then you use one without a predicate which will return all rows. Either reuse the predicate for the second request as well or even better skip the first count request that seems unnecessary and perform only the second one
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "CartEntity")
request.returnsObjectsAsFaults = false
request.predicate = NSPredicate(format: "product_id == %#", "\(Product_id)")
do {
let result = try managedContext.fetch(request)
for dataresult in result as! [NSManagedObject] {
//... rest of code
First of all use the predicate of the first request and secondly use a specific fetch request to return the actual NSManagedObject subclass. The benefit is to get the values directly with dot notation rather than with error-prone KVC (key-value coding).
This is the corresponding logic of your entire code, however the savecoredata line seems to be pointless
let request : NSFetchRequest<CartEntity> = CartEntity.fetchRequest()
request.predicate = NSPredicate(format: "product_id == %ld", Product_id)
do {
if let result = try managedContext.fetch(request).first {
let userName = result.proname
let price = result.price
print("User Name is : \(userName) and price is : \(price)")
} else {
// no matching object
print("no")
self.savecoredata()
}
} catch {
print(error)
}
The issue seems to be with your predicate. Check if the product_id is string or integer. If you are doing casting then apply format "%d", "%ld"
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "CartEntity")
let predicate = NSPredicate(format: "product_id = \(Product_id)")
request.predicate = predicate
request.fetchLimit = 1
var count = 0
do{
count = try managedContext.count(for: request)
}
catch let error {
print("Could not fetch \(error), \(error.localizedDescription)")
}
guard count != 0 else {
// no matching object
print("no")
self.savecoredata()
return
}
// remove predicate, which is actually not required.
request.predicate = nil
request.returnsObjectsAsFaults = false
do {
let result = try managedContext.fetch(request)
for dataresult in result as! [NSManagedObject] {
let userName = dataresult.value(forKey: "proname") as! String
let age = dataresult.value(forKey: "price") as! String
print("User Name is : "+userName+" and price is : "+age)
print(datastored)
}
} catch let error {
print("Fetching data Failed - \(error)")
}
print("yes")
// deleteFeed(id: "\(Product_id)")
// first delete old and than insert new id

Core Data fetching data and looking for duplicate

I want to fetch data from Core data and look for duplicats and then only save the data then there is no duplicate of the movieid.
Maybe some one can help me ..
How can I compare the result with the movieid string ?
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "MovieData")
//request.predicate = NSPredicate(format: "movieid = %#", movieID)
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
print(data.value(forKey: "movieid") as! String)
}
} catch {
print("Failed")
}
Almost. Apply the predicate to get only the record with the specific movieID. However it assumes that movieID is an object (NSNumber), if it's an scalar Int you have to use %ld as placeholder.
If the fetch returns an empty array there is no duplicate and you can insert a new object
let request = NSFetchRequest<NSManagedObject>(entityName: "MovieData")
request.predicate = NSPredicate(format: "movieid = %#", movieID)
do {
let result = try context.fetch(request)
if result.isEmpty {
let newMovie = NSEntityDescription.insertNewObject(forEntityName: "MovieData", into: context) as! MovieData
newMovie.movieid = movieID
try context.save()
}
} catch {
print(error)
}
While saving in core data you need to create predicate and in there you need to check if there are values already saved with same "movieid" then it has to be updated , this way you won't have duplicate data . Please refer the method and try using the same for saving the values in DB . This way duplicate values won't be saved in DB
class func insertupdaterecord (movieID:String, context: NSManagedObjectContext)
{
let entityDescription = NSEntityDescription.entity(forEntityName: "movie", in: context)
let pred = NSPredicate(format: "movieid = %#", movieID)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "movie")
fetchRequest.entity = entityDescription
fetchRequest.predicate = pred
let result = try! (context.fetch(fetchRequest) as NSArray).lastObject
let updateInsertInfo : movie
if result != nil
{
updateInsertInfo = result as! movie
}
else
{
print("Record not found!")
}
do
{
try context.save()
}
catch let error as NSError
{
print("Error while saving \(error) in database.")
}
}
Create a cache for movieid values to check for duplicates and loop through the fetched result and delete any objects with a movieid already in the cache and then save once the loop is done.
var selection: [String] = []
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "MovieData")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
guard let movieId = data.value(forKey: "movieid") as? String else {
context.delete(data) // or however you want to handle this situation
continue
}
if selection.contains(movieId) {
context.delete(data)
} else {
selection.append(movieId)
}
}
try context.save()
} catch {
print("Failed")
}

Predicate is not working with NSSet

I want to filter Places where categoryId == value but my predicate is failing.
Here is my code.
categoryList is an array of Objects of class VenueCategory and categoryId is property of Category class.
class Place: NSManagedObject {
class func GetPlaces(keys:[String],values:[String],forPlaceTab:Bool?,visitType:VisitType) -> [Place] {
//1
let managedContext = CoreDataStack.sharedStack().mainContext
var predicates = [NSPredicate]()
//2
let fetchRequest = NSFetchRequest(entityName:TABLE_PLACE)
for (index, key) in keys.enumerate() {
let value = values[index]
let predicateFormat = key != "categoryId" ? "\(key) == \(value)" : "ANY categoryList.categoryId == \(value)"
let resultPredicate = NSPredicate(format: predicateFormat)
predicates.append(resultPredicate)
}
if let forPlaceTab = forPlaceTab{
let predicateFormat = "isPlaceTab == \(forPlaceTab.boolValue)"
let resultPredicate = NSPredicate(format: predicateFormat)
predicates.append(resultPredicate)
}
fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
//3
//var error: NSError?
do {
if let results = try managedContext.executeFetchRequest(fetchRequest) as? [Place]{
return results
}
} catch let error as NSError {
print(error)
}
return []
}
}
I got the problem. issue was categories were not getting added in categoriesList. predicate was Ok.

Update core data object swift 3

I want to update a core data object in swift 3. After some googled I didn't found anything about swift 3.
So my question is: how can I update a core data object in swift 3?
Fetch the existing values using a fetch request with a predicate. Use a unique value in the predicate. Once you've fetched the object, update the object with new values and save the context.
let empId = "001"
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "EmpDetails")
let predicate = NSPredicate(format: "empId = '\(empId)'")
fetchRequest.predicate = predicate
do {
let result = try persistentContainer.viewContext.fetch(fetchRequest)
if let objectToUpdate = result.first as? NSManagedObject {
objectToUpdate.setValue("newName", forKey: "name")
objectToUpdate.setValue("newDepartment", forKey: "department")
objectToUpdate.setValue("001", forKey: "empID")
try persistentContainer.viewContext.save()
}
} catch {
print(error)
}
Using NSManagedObject subclass
let empId = "001"
let fetchRequest: NSFetchRequest<Employee> = Employee.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "%K = %#", #keyPath(Employee.id), empId)
do {
let results = try persistentContainer.viewContext.fetch(fetchRequest)
if let employee = results.first {
employee.name = "new name"
employee.department = "new department"
}
try persistentContainer.viewContext.save()
} catch let error as NSError {
print(error.localizedDescription)
}
Batch updates
Batch updates help to update multiple Core Data objects without having
to fetch anything into memory.
let batchUpdate = NSBatchUpdateRequest(entityName: "Employee")
batchUpdate.propertiesToUpdate = [#keyPath(Employee.isActive): true]
batchUpdate.affectedStores = persistentContainer.viewContext.persistentStoreCoordinator?.persistentStores
batchUpdate.resultType = .updatedObjectsCountResultType
do {
let batchResult = try coreDataStack.managedContext.execute(batchUpdate) as? NSBatchUpdateResult
print(batchResult?.result)
} catch let error as NSError {
print(error.localizedDescription)
}
Pass unique id in variable "id"(Unique variable created in Core data model) and all the variable as you want to update values:
func context() -> NSManagedObjectContext {
let context=(UIApplication.shared.delegate as!AppDelegate).persistentContainer.viewContext
return context
}
func save() {
(UIApplication.shared.delegate as! AppDelegate).saveContext()
}
func UpdateCartByTestId(id:Int64,name:String) {
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Update")
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = NSPredicate(format:"id == %d",id)
let result = try? context().fetch(fetchRequest)
if result?.count == 1 {
let dic = result![0]
dic.setValue(id, forKey: "id")
dic.setValue(name, forKey: "name")
save()
}
}

Swift fetch request returns 0 results, even though there are clearly 192 results

I make my fetch request like so :
let pageFetchRequest = NSFetchRequest(entityName: "Page")
let results = try managedObjectContext.executeFetchRequest(pageFetchRequest)
Here, results will return 0 results {}.
But I do this by itself :
managedObjectContext.executeFetchRequest(pageFetchRequest)
I get all 192 results. So long as I don't assign it to a variable such as results. Why is that? Does assigning it or using the method try prevent this from working?
Update
This is the full post. Notice how I'm using managedObjectContext twice for two different related requests. Maybe that's what is botching my results up?
let managedObjectContext = self.managedObjectContext
for item in items {
let word = Word(chapter: Int(item.chapter)!, verse: Int(item.verse)!, sanskrit: item.sanskrit, english: item.english, insertIntoManagedObjectContext: managedObjectContext)
// Assign the Page
let pageFetchRequest = NSFetchRequest(entityName: "Word")
let chapterPred = NSPredicate(format: "(chapter = %d)", Int(item.chapter)!)
let versePred = NSPredicate(format: "(verse = %d)", Int(item.verse)!)
pageFetchRequest.fetchLimit = 1
pageFetchRequest.predicate = NSCompoundPredicate(type: .OrPredicateType, subpredicates: [chapterPred, versePred])
do {
let results = try managedObjectContext.executeFetchRequest(pageFetchRequest)
if let page = results.first as? NSManagedObject {
word.setValue(page, forKey: "page")
}
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
do {
try managedObjectContext.save()
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
So evidently the answer.. I think.. was to create a separate managedObjectContext that wouldn't be confused with the parent one.. Like so :
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let secondManagedContext = appDelegate.managedObjectContext
let pageFetchRequest = NSFetchRequest(entityName: "Page")Int(item.verse)!)
pageFetchRequest.fetchLimit = 1
pageFetchRequest.predicate = NSCompoundPredicate(type: .OrPredicateType, subpredicates: [chapterPred, versePred])
And then I had to also write this :
do {
var results:[NSManagedObject]
results = try secondManagedContext.executeFetchRequest(pageFetchRequest) as! [Page]
if let page = results.first {
word.setValue(page, forKey: "page")
}

Resources