Core Data Condition - swift

I need to add a Core Data condition How do I do it? . If the record is in this condition, the "sonuc" variable will be true
Core data model:
If "kullaniciadi" is "emre" and "otogiris" is "1" then the "sonuc" will
be true
func getContext () -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if #available(iOS 10.0, *) {
return appDelegate.persistentContainer.viewContext
} else {
return DatabaseController.managedObjectContext
}
}
func otomatikGirisKontrol() -> Bool
{
var sonuc = false
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Kullanicilar")
fetchRequest.returnsObjectsAsFaults = false
do{
let results = try getContext().fetch(fetchRequest)
if results.count > 0
{
sonuc = true
}
else
{
sonuc = false
}
}
catch
{
}
return (sonuc)
}

Use a NSPredicate to fetch only Kullaniciar objects fitting your condition:
let fetchRequest = ...
let kullaniciadi = "emre"
let otogiris = "1"
let predicate = NSPredicate(format: "kullaniciadi = %# AND otogiris = %#", kullaniciadi, otogiris)
request.predicate = predicate
//... execute fetch request

Related

CoreData batch insert Entities with Relationship

Is there anyway to insert entities with relationship? I get error "Illegal attempt to establish a relationship 'content' between objects in different contexts"
addUsers(users: [userData])
func addUsers(users: [User]) {
let taskContext = container.viewContext
taskContext.perform {
let batchInsertRequest = self.newBatchInsertRequest(with: users)
if let fetchResult = try? taskContext.execute(batchInsertRequest),
let batchInsertResult = fetchResult as? NSBatchInsertResult,
let success = batchInsertResult.result as? Bool, success {
return
}
}
}
crash happens in below code
private func newBatchInsertRequest(with users: [Users]) -> NSBatchInsertRequest {
var index = 0
let total = message.count
let batchInsertRequest = NSBatchInsertRequest(entity: WaUser.entity(), managedObjectHandler: { managedObject in
guard index < total else { return true }
let user = users[index]
if let waUser = managedObject as? WaUser {
waUser.name = user.name
let waUserInfo = waUserInfo(context: self.container.viewContext)
waUserInfo.pass = "12345"
waUserInfo.key = "asdfgh"
waUser.info = waUserInfo **//crash occurs here**
}
index += 1
return false
})
return batchInsertRequest
}

pull details from local database

I want to pull details from local database but when I do the necessary operations, it returns null as a result. I can't understand where I went wrong.
var chosenCar=""
var chosenCarId : UUID?
the arrays I created, I transfer data to these arrays, there is no problem with that, I did a test
if chosenCar != "" {
//core data
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "CarsInformation")
let idString = chosenCarId?.uuidString
fetchRequest.predicate = NSPredicate(format: "id = %#", idString!)
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let name = result.value(forKey: "models") as? String {
modelTextField.text = name
}
if let year = result.value(forKey: "year") as? Int {
yearTextField.text = String(year)
}
if let price = result.value(forKey: "price") as? Int {
priceTextField.text = String(price)
}
if let imageData = result.value(forKey: "image") as? Data {
let image = UIImage(data: imageData)
imageView.image = image
}
}
}
} catch{
print("error")
}
} else {
modelTextField.text = ""
priceTextField.text = ""
yearTextField.text = ""
}
After doing these operations, I can't get the result I want.

Edit all records by ID (Swift 4, CoreData)

I have Int array with values
Example:
var SelectedCard = [Int] ()
[3, 1, 2]
Me need edit my all records by order
Im tried this but app crash
for item in 0...SelectedCard.count-1 {
let order = SelectedCard[item]
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Card")
fetchRequest.predicate = NSPredicate(format: "order == %#", order)
do {
if let fetchResults = try managedContext.fetch(fetchRequest) as? [Card] {
if fetchResults.count != 0 {
for index in 0...fetchResults.count-1 {
let managedObject = fetchResults[index]
managedObject.setValue("", forKey: "folderID")
}
appDelegate.saveContext()
}
}
} catch {
print(error)
}
}
self.tableView.reloadData()
Try changing the predicate to
NSPredicate(format: "order == \(order)")

Core Data - How can I get the max value from an entity attribute (Swift)

Recipe
recipeID: Int
recipeName: String
I have an entity Recipe with an attribute recipeID.
How can I get the max(recipeID) as an Int value in Swift?
I'm new in swift, please help me.
Thanks in advance.
func fetchMaxID() {
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Recipe")
fetchRequest.fetchLimit = 1
let sortDescriptor = NSSortDescriptor(key: "recipeID", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
let maxID = try [managedObjectContext?.executeFetchRequest(fetchRequest)].first
print(maxID)
} catch _ {
}
}
The way that Apple recommends and is the fastest is using NSExpressions. moc is a NSManagedObjectContext.
private func getLastContactSyncTimestamp() -> Int64? {
let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest()
request.entity = NSEntityDescription.entity(forEntityName: "Contact", in: self.moc)
request.resultType = NSFetchRequestResultType.dictionaryResultType
let keypathExpression = NSExpression(forKeyPath: "timestamp")
let maxExpression = NSExpression(forFunction: "max:", arguments: [keypathExpression])
let key = "maxTimestamp"
let expressionDescription = NSExpressionDescription()
expressionDescription.name = key
expressionDescription.expression = maxExpression
expressionDescription.expressionResultType = .integer64AttributeType
request.propertiesToFetch = [expressionDescription]
var maxTimestamp: Int64? = nil
do {
if let result = try self.moc.fetch(request) as? [[String: Int64]], let dict = result.first {
maxTimestamp = dict[key]
}
} catch {
assertionFailure("Failed to fetch max timestamp with error = \(error)")
return nil
}
return maxTimestamp
}
Learning from Ray Wenderlich's Core Data Tutorial
https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial/
func fetchMaxRecipe() {
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Recipe")
fetchRequest.fetchLimit = 1
let sortDescriptor = NSSortDescriptor(key: "recipeID", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
let recipes = try context.executeFetchRequest(fetchRequest) as! [Recipe]
let max = recipes.first
print(max?.valueForKey("recipeID") as! Int)
} catch _ {
}
}
Hope this helps =).
func fetchMaxID() {
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Recipe")
fetchRequest.fetchLimit = 1
let sortDescriptor = NSSortDescriptor(key: "recipeID", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
let results = try context.executeFetchRequest(fetchRequest) as! [Recipe]
if (results.count > 0) {
for result in results {
print(result.recipeID!)
}
} else {
print("No Recipe")
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
This works also!
To check the max of an entity attribute you can simply use:
func findMaxRecipeID() -> Int {
let maxRecipeID = recipe?.value(forKeyPath: "recipe.#max.recipeID") as! Int
return maxRecipeID
}
You can use this to #sum, #max, #min, #count - saves quite a few lines of code.

core data object not saved in sqlite

I'm having a problem that the sqlite file is only edited when adding the objects in the first time.After that only the sqlite-shm file is changed. So when I relaunch the app nothing changes.Here is the core data stack in the AppDelegate
lazy var managedObjectContext: NSManagedObjectContext = {
let modelURL = NSBundle.mainBundle().URLForResource("StoriesCoreData", withExtension: "mom")
let mom = NSManagedObjectModel(contentsOfURL: modelURL!)
let psc = NSPersistentStoreCoordinator(managedObjectModel: mom!)
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
print (urls[urls.endIndex-1])
let storeURL = (urls[urls.endIndex-1]).URLByAppendingPathComponent("stories.sqlite")
var error: NSError? = nil
var store: NSPersistentStore?
do {
store = try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
} catch var error1 as NSError {
error = error1
store = nil
} catch {
fatalError()
}
if (store == nil) {
print("Failed to load store")
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = psc
return managedObjectContext
}()
func saveContext() {
var error: NSError? = nil
let moc : NSManagedObjectContext? = self.managedObjectContext
if moc == nil {
return
}
if !managedObjectContext.hasChanges {
return
}
do {
try managedObjectContext.save()
return
} catch let error1 as NSError {
error = error1
}
print("Error saving context: \(error?.localizedDescription)\n\(error?.userInfo)")
abort()
}
Here is how the objects are initialized:
let aStory = NSEntityDescription.insertNewObjectForEntityForName("PersonalizedStory", inManagedObjectContext: managedObjectContext) as! PersonalizedStory
aStory.childrenMode = NSNumber(int: 0)
aStory.hidden = NSNumber(int: 0)
aStory.lastEdited = NSDate()
aStory.parentStoryDownloadDate = NSDate()
aStory.parentStoryID = "10000"
aStory.parentWriterID = "guest"
aStory.personalizedStoryID = "10"
aStory.pictureList = []
aStory.userID = "guest"
aStory.inSection = NSSet()
saveContext()
let aSection = NSEntityDescription.insertNewObjectForEntityForName("LibrarySection", inManagedObjectContext: managedObjectContext) as! LibrarySection
aSection.personalizedStoriesOrder = []
aSection.sectionName = "AllStories"
aSection.userID = "guest"
aSection.personalizedStoriesOrder!.append(aStory)
aSection.hasStory = NSSet()
saveContext()
aSection.addObject(aStory, forKey: "hasStory")
aStory.addObject(aSection, forKey: "inSection")
saveContext()
Here is the fetch request and modification:
func allStories () -> [PersonalizedStory]? {
var error : NSError? = nil
let fetchStories = NSFetchRequest(entityName: "LibrarySection")
let sectionsForUser = NSPredicate(format: "userID = %#", argumentArray: [userID])
let all = NSPredicate(format: "sectionName == %#", argumentArray: ["AllStories"])
let fetchPredicates = NSCompoundPredicate(andPredicateWithSubpredicates: [sectionsForUser,all])
fetchStories.predicate = fetchPredicates
var result : [LibrarySection]?
do {
result = try appDelegate.managedObjectContext.executeFetchRequest(fetchStories) as? [LibrarySection]
} catch {
result = nil
}
let theSection = result!.first!.personalizedStoriesOrder!
for story in theSection {
story.setValue(1, forKey: "childrenMode")
}
appDelegate.saveContext()
return theSection
}
So in when I print out the stories later on childMode is set to 1.
However when I relaunch every thing is set back to 0.
And when I check the app folder