Reputation: 1444
I have a coreData NSManagedObject
as follows:
public class Records: NSManagedObject {
@NSManaged public var uid: String
@NSManaged public var datetime: Date
}
In addition, I have a helper to retrieve the record by UID:
func getRecordByUid(uid: String) -> Records!{
do {
let fetchRequest : NSFetchRequest<Records> = Records.createFetchRequest()
fetchRequest.predicate = NSPredicate(format: "uid = %@", uid)
let result: [Records] = try container.viewContext.fetch(fetchRequest)
return result.first
} catch {
print(error.localizedDescription)
return nil
}
}
Now, in my view controller I used a core-data object as non-optional (for adding new record or editing existing record purpose) as described below:
class AddRecordViewController: UIViewController {
var container: NSPersistentContainer!
var record: Records!
var currentUid = ""
@IBOutlet weak var dateTextField: PickerBasedTextField!
override func viewDidLoad() {
super.viewDidLoad()
// initialise core data
container = NSPersistentContainer(name: "MyModel")
container.loadPersistentStores { (storeDescription, error) in
self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if let error = error {
print("Unsolved error \(error.localizedDescription)")
}
}
if let existingRecord = Facade.share.model.getRecordByUid(uid: currentUid) {
record = existingRecord
} else {
record = Records(context: self.container.viewContext)
}
// datePicker
let formatter = DateFormatter()
formatter.dateStyle = .medium
dateTextField.text = formatter.string(from: record.datetime)
...
}
}
The problem is that it cause an error in dateTextField.text = ...
line, because it thinks the record
is optional, however it isn't a case:
(lldb) po record
▿ Optional<Records>
Fatal error: Unexpectedly found nil while unwrapping an Optional value
What should I do?
Upvotes: 0
Views: 309
Reputation: 51993
I think your code would behave much better if you wrapped the fetch with the create into one method that always returns an object.
Something like
func getOrCreateRecord(uid: String) -> Records{
var record: Records?
do {
let fetchRequest : NSFetchRequest<Records> = Records.createFetchRequest()
fetchRequest.predicate = NSPredicate(format: "uid = %@", uid)
let result: [Records] = try container.viewContext.fetch(fetchRequest)
record = result.first
} catch {
print(error.localizedDescription)
}
return record ?? Records(context: container.viewContext)
}
There still might be an issue with the text field but I still think it makes sense to create a wrapper method for this logic.
Upvotes: 1
Reputation: 2044
I think that dateTextField
is probably nil, and the fatal error is related to it. Either that, or Records(context: self.container.viewContext)
is a failable initializer that returns a nil object in some cases.
Upvotes: 1