-2

I’m building an app with Swift. I have this code in my class:

var url : Url? = Url()

on ViewDidLoad() method I have this:

override func viewDidLoad() {
        super.viewDidLoad()

        //recuper ip di arduino
        url = UrlCoreDataController.shared.loadUrl()!

        self.setUpLuci()
        //    self.tabella.dataSource = self
        //    self.tabella.delegate = self
    }

the loadUrl() method can return nil value.

So if the method return nil value I have this error:

2018-03-06 12:29:47.150240+0100 ArduinoHomeKit_bis[2318:1060982] [error] error: CoreData: error: Failed to call designated initializer on NSManagedObject class 'Url'
CoreData: error: CoreData: error: Failed to call designated initializer on NSManagedObject class ‘Url'

How can I change my code ?

bircastri
  • 2,169
  • 13
  • 50
  • 119

3 Answers3

1

Update your code like this

override func viewDidLoad() {
        super.viewDidLoad()

        //recuper ip di arduino
        if let _url = UrlCoreDataController.shared.loadUrl() {
               url = _url
               self.setUpLuci()
        }
        //    self.tabella.dataSource = self
        //    self.tabella.delegate = self
    }

If-Let statement check if UrlCoreDataController.shared.loadUrl() return nil then it will not execute code inside curly braces and you app will be not crash.

Usman Javed
  • 2,437
  • 1
  • 17
  • 26
  • There's no need to a backing variable, such as `_url`, you can define another `url` variable in the optional unwrapping with local scope and simply do `url = url`. – Dávid Pásztor Mar 06 '18 at 11:36
  • Yes you need because this is recommended way to unwrap value from optional variable. Your are get exception because you are trying to get value from optional variable while is nil. – Usman Javed Mar 06 '18 at 11:39
  • You misunderstood me. I didn't say you should be using optional binding, I was just saying you don't need to declare a temporary variable with a different name. You can do `if let url = UrlCoreDataController.shared.loadUrl() { url = url; self.setUpLuci() }`. – Dávid Pásztor Mar 06 '18 at 11:41
  • hahaha yaa I misunderstood coz I thought you have a created a variable with a purpose thats why I created new variable. – Usman Javed Mar 06 '18 at 12:23
0

Failed to call designated initializer on NSManagedObject class ‘Url'

It means the class Url does n't has designated initializer. In simple world you need to create a init() in Url class

For eg.

class Url: NSObject {

    //variables

   //initializer
   init() {
   }
}

Refer this about Initializer

The loadUrl() method can return nil value.

for this you can use guard statement or use optional binging

guard let url = UrlCoreDataController.shared.loadUrl() else {
    print("url is not available.")
    return;
}

//here you have url
 print(url)

OR

if let url = UrlCoreDataController.shared.loadUrl() {
    print(url)
} else {
   print("url is not available.")
}
Mahendra
  • 8,448
  • 3
  • 33
  • 56
0

There are few possible ways to handle optionals :

1.if let

if let url = UrlCoreDataController.shared.loadUrl() {
    url = url
    self.setupLuci()
}

2.guard let :

guard let url = UrlCoreDataController.shared.loadUrl() {
     // do something here if url is nil
     return
}
 // and here if url is not nil

3.if statement

if url != nil {
  // do here Your stuff
}

I mostly use the 1st option.