DrWhat DrWhat - 1 year ago 100
iOS Question

Variable instantiated in prepare for Segue has nil properties in ViewDidLoad

My view controller is loading before Core Location data is available from the model.

I've a Master View controller that modally pushes a new view controller with two

subclasses - records and locations - which are instantiated in a

if segue.identifier == "newRecord"
let controller = (segue.destinationViewController as! NewRecordVC)

let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate // instantiate the delegate methods in AppDelegate

let managedContext = appDelegate!.managedObjectContext // create context from delegate methods

let recordEntity = NSEntityDescription.entityForName("RecordData", inManagedObjectContext: managedContext)
let locationEntity = NSEntityDescription.entityForName("Location", inManagedObjectContext: managedContext)

controller.location = Location(entity: locationEntity!, insertIntoManagedObjectContext: managedContext)
controller.record = Record(entity: recordEntity!, insertIntoManagedObjectContext: managedContext)
controller.managedContext = appDelegate?.managedObjectContext

Both managed objects have
for various values. Records have simple pre-assigned values assigned to properties that show up on the new view. Location properties, however, mainly require location services to assign property values. Printing property values shows that while a location is instantiated in
, the location properties assigned by location services are still nil. Location services are working - the properties print from within the model, BUT this is after
. On load, I need at least the
property, which provides text for the view.

override func viewDidLoad()
if let recordNotNil = record
iD.text = "ID: \(recordNotNil.iD)"

if let locationNotNil = location
record!.location = location!
if let geoPlacemarkNotNil = location.geoPlacemark

Do I have to run the location services from within every view controller, not the model? Or is there a way to get the view to wait for the location delegate methods?

Answer Source

The problem here came from using the normal override init method for the NSManagedObject.

class Record: NSManagedObject
override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?)
    super.init(entity: entity, insertIntoManagedObjectContext: context)
    let randomBit = String(arc4random_uniform(100))
    iD = NSDate().toIDTimeDateString() + "-" + randomBit + "OtR"

    believers = 0
    deviceTime = NSDate()
    doubters = 0
    eventTimeStarted = NSDate()
    eventTimeEnded = NSDate()
    featureImageIndex = 0
    coreLocationUsed = 0
    photoTaken = 0
    tableSection = "My Records"
    timeRecorded = deviceTime
    validationScore = 0

As per the apple doc.s, custom NSManagedObjects should be initiated using awakeFromInsert or awakeFromFetch.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download