Unable to update core data object - ios

I able to insert,find,delete the core data object but unable to update the existing core data object.
StudentTable is the entity. id,rollnumber,classnumber,classid,classname are the attributes.
I had created NSEntityDescription , NSFetchRequest , NSPredicate but still data is not getting updated to existing core data object.
The whole object is getting deleted when the update button is pressed, which I have no idea how.
Update button action code
#IBAction func update(_ sender: UIButton) {
if(id.text != nil)
{
let entityDescription = NSEntityDescription.entity(forEntityName: "StudentTable", in: managedObjectContext)
let request: NSFetchRequest<StudentTable> = StudentTable.fetchRequest()
request.entity = entityDescription
let pred = NSPredicate(format: "(id = %#)", id.text!)
request.predicate = pred
let studenttable = StudentTable(entity: entityDescription!, insertInto: managedObjectContext)
do {
var results =
try managedObjectContext.fetch(request as! NSFetchRequest<NSFetchRequestResult>)
if results.count > 0 {
let match = results[0] as! NSManagedObject
match.setValue(String(describing: id.text), forKey: "id")
match.setValue(Int(rollnumber.text!), forKey: "rollnumber")
match.setValue(Int(classnumber.text!), forKey: "classnumber")
match.setValue(Int(classid.text!), forKey: "classid")
match.setValue(String(describing: classname.text!), forKey: "classname")
do {
try managedObjectContext.save()
beacondataobject.append(studenttable)
let alert = UIAlertController(title: "Alert", message: "updated data", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
} else {
//noting found
let alert = UIAlertController(title: "Alert", message: "No data found", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Search Again", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
} catch let error {
print("error %#", error)
}
}
else{
let alert = UIAlertController(title: "Alert", message: "Enter id to search", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Try Again", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
Any suggestion will appreciated, thank you.
using xcode 8.2, swift 3

Related

Checking if entity exist before saving it to core data swift4.

I'm trying to add data to Core Data in my application. When I save it without checking if it already exists it works fine. But I don't what duplicates in my core data so what I do I fetch all the entities with the name of entity im trying to add first and then check if it's 0 I add it else no. But I'm keep getting an error when trying to save. If anyone could help me with the problem.
This is my checking function:
func entityExists(name: String) -> Bool {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "name")
fetchRequest.includesSubentities = false
var entitiesCount = 0
do {
entitiesCount = try coreDataController.mainContext.count(for: fetchRequest)
}
catch {
print("error executing fetch request: \(error)")
}
if entitiesCount == 0{
return true
} else {
return false
}
}
This is my code when I save the data.
if entityExists(name: (scrimmagePassedOver?.name)!) == true{
coreDataController.saveContext()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
let alert = UIAlertController(title: "Saved!", message: "You have saved your Scrimmage.", preferredStyle: UIAlertControllerStyle.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "hey", message: "You have saved this Scrimmage before.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
You can check the record from your core data like that:
func checkRecordExists(entity: String,uniqueIdentity: String,idAttributeName:String) -> Bool {
let context = getManagedObjectContext()
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
fetchRequest.predicate = NSPredicate(format: "\(idAttributeName) CONTAINS[cd] %#", createdDate)
var results: [NSManagedObject] = []
do {
results = try context.fetch(fetchRequest)
}
catch {
print("error executing fetch request: \(error)")
}
return results.count > 0
}
and managedObjectContext is:
func getManagedObjectContext() -> NSManagedObjectContext{
let delegate = UIApplication.shared.delegate as? AppDelegate
return delegate!.persistentContainer.viewContext
}
If you get false then save it.

Swift 4 local variable value assignment

I am trying to recovery a value from firebase database and compare it with a UITextField value, in case of matching, I save it to a var that I will us. The problem is that the variable in question has a default value just when I use it.
Above I show my func code where the variable affected is "codeRecovered":
#IBAction func signUpAction(_ sender: AnyObject)
{
var codeRecovered: String = ""
if emailSignUpTextField.text == "" || self.secretCodeTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email, pin code and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else {
self.dbHandler = self.ref?.child("Companies").observe(.value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let value = snap.value as! [String:String]
if let auxSecretCode = value["secretCode"]
{
if auxSecretCode == self.secretCodeTextField.text{
print("Value recovered OK(works fine): \(auxSecretCode)")
codeRecovered = auxSecretCode
print("Recovered value saved OK(works fine): \(codeRecovered)")
}
}
}
})
//Here codeRecovered is already ""
print("\(codeRecovered) is the recovered value(empty) and \(self.secretCodeTextField.text ?? "def") is the textField value")
if codeRecovered != self.secretCodeTextField.text{
let alertController = UIAlertController(title: "Error", message: "Please enter a correct pin code", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
}
//....
Async calls with sync result use....
#IBAction func signUpAction(_ sender: AnyObject)
{
var codeRecovered: String = ""
if emailSignUpTextField.text == "" || self.secretCodeTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email, pin code and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else {
self.dbHandler = self.ref?.child("Companies").observe(.value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let value = snap.value as! [String:String]
if let auxSecretCode = value["secretCode"]
{
if auxSecretCode == self.secretCodeTextField.text{
print("Value recovered OK(works fine): \(auxSecretCode)")
codeRecovered = auxSecretCode
print("Recovered value saved OK(works fine): \(codeRecovered)")
}
}
}
//Here codeRecovered is already ""
print("\(codeRecovered) is the recovered value(empty) and \(self.secretCodeTextField.text ?? "def") is the textField value")
if codeRecovered != self.secretCodeTextField.text{
let alertController = UIAlertController(title: "Error", message: "Please enter a correct pin code", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
}
})
to use your codeRecovered in a sequence it must be within self.dbHandler = self.ref?.child("Companies").... block because it runs in async thread

DynamoDB load nil Error

I'm trying to load my data from dynamoBD and print them out with the labels.
Following the sample: https://github.com/awslabs/aws-sdk-ios-samples/tree/master/DynamoDBObjectMapper-Sample
I already created a table on the account and I can see their attributes using web browser.
Using this code to load data:
var tableRow: DDBTableRow?
func getTableRow() {
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
dynamoDBObjectMapper .load(DDBTableRow.self, hashKey: (tableRow?.PhotoId)!, rangeKey: tableRow?.UserId) .continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask!) -> AnyObject! in
if let error = task.error as? NSError {
print("Error: \(error)")
let alertController = UIAlertController(title: "Failed to get item from table.", message: error.description, preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
} else if let tableRow = task.result as? DDBTableRow {
self.photoIdLabel.text = tableRow.PhotoId
self.userIdLabel.text = tableRow.UserId
self.photoDateLabel.text = tableRow.PhotoDate
self.photoURLLabel.text = tableRow.PhotoURL
self.photoCategoryLabel.text = tableRow.PhotoCategory
}
return nil
})
}
In the log: tableRows [MyProject.DDBTableRow]? nil none.
The sample code is working fine, I don't know what wrong. Do I miss something before calling load? I feel very close to solve it. Please help!

Data is not being inserted under the node of user UID in Firebase in Swift 3

When I save data under userID the data is not being stored into the Firebase and give error unexpectedly found nil while unwrapping an optional value, however when I use childByAutoID the data is being stored successfully. Help me to save under userID node. Here I have explained that when I create the user under signup action this is happening.
#IBAction func createAccountAction(_ sender: Any) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else if (self.passwordTextField.text != self.retypePasswordfield.text) {
let alertController = UIAlertController(title: "Error", message: "Password does not match", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else {
ref.child("user_registration").setValue(["username": self.fullName.text, "email": self.emailTextField.text,"contact": self.numberText.text, "city": self.myCity.text, "state": self.countryText.text, "gender": genderGroup, "blood": bloodGroup])
FIRAuth.auth()?.createUser(withEmail: emailTextField.text!, password: passwordTextField.text!) { (user, error) in
if error == nil {
FIRAuth.auth()?.currentUser!.sendEmailVerification(completion: { (error) in
})
print("You have successfully signed up")
let alertController = UIAlertController(title: "Successful!", message: "Email Verification link sent", preferredStyle: .alert)
let alertActionOkay = UIAlertAction(title: "Okay", style: .default) { (action) in
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginFirstViewController")
self.present(vc!, animated: true, completion: nil)
}
alertController.addAction(alertActionOkay)
self.present(alertController, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
Only for reference
This is the current working code for me
On signUp Button
// Create new User
FIRAuth.auth()?.createUser(withEmail: self.tfEmail.text!, password: self.tfPassword.text!, completion: { (user, error) in
if error == nil{ // IF NO ERROR
let astrContact = self.strDialCode + " " + self.tfMobileNumber.text!
// Dict to add user data in firebase Db
let aDBDict : [String : String] = ["userName": self.tfFullName.text!,
"userEmail": self.tfEmail.text!,
"userContact": astrContact,
"userCountry": self.strCode,
"userID": (user?.uid)!]
// Add data in DB
ref?.child("Customer/\(String(describing: (user?.uid)!)/userProfileDetails").setValue(aDBDict)
DispatchQueue.main.async(execute: { () -> Void in
// goto home VC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navController = storyboard.instantiateViewController(withIdentifier: "MainController")
if let window = AppDelegate.getAppDelegate().window {
window.rootViewController = navController
}
})
}
else{ // If error in creating new user
print("error in creating new user")
print(error!)
}
})
In appDelegate
extension AppDelegate {
class func getAppDelegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}

If let statement error

Im trying to build a todo list with coreData, my goal is to have an error pop-up notification if a user tries to just click the "add" button without entering any text in the text-field.
I currently have the pop-up notification working but once i dismiss the notification and then add text into the text-field and click the "add" button the application crashes.
#IBAction func addBtnTaskPressed(_ sender: Any) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let task = Task(context: context)
//have to add an if let here.
if let text = textField.text, !text.isEmpty{
task.name = textField.text
//save data to coredata
(UIApplication.shared.delegate as! AppDelegate).saveContext()
} else {
let alert = UIAlertController(title: "Error:", message: "Cannot Add Empty Task", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Continue", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
I think you are not saving coreData properly. Try this (I haven't tested it though)
#IBAction func addBtnTaskPressed(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.managedObjectContext
let entity = NSEntityDescription.entity(forEntityName: "Task", in: context)
let task = NSManagedObject(entity: entity!, insertInto: context) as! Task
//have to add an if let here.
if let text = textField.text, !text.isEmpty{
task.name = textField.text
//save data to coredata
do {
try context.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
} else {
let alert = UIAlertController(title: "Error:", message: "Cannot Add Empty Task", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Continue", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}

Resources