ilan
ilan

Reputation: 4462

super init isn't called on all paths before returning from initializer

I made a framework that wraps Alamofire.

In my Framework when testing (in Test target) i have this code that works grate.

import Foundation
@testable import NetworkManager

class MockRouter: Router {


enum APICalls {
    case func1
    case func2
}

var calls: APICalls!

init(calls: APICalls) {
    self.calls = calls
}

}

When i add it as a framework to a different project

import Foundation
import NetworkManager

class JokesRouter: Router {

enum APICalls {
    case func1
    case func2
}

var calls: APICalls!

init(calls: APICalls) {
    self.calls = calls
}


}

I get an error:

super init isn't called on all paths before returning from initializer

So i added Super.init()

init(calls: APICalls) {
    super.init()
    self.calls = calls
}

And now i get this error:

super.init cannot be called outside of an initializer

Any idea what is the problem?

Upvotes: 4

Views: 12883

Answers (2)

Anil Gupta
Anil Gupta

Reputation: 1225

I was trying to create an Inheritance feature of the Swift Programming.

I created the ViewController as super class. Then I created another class as subclass name as ViewControllerA of super class ViewController

ViewController Class :

import UIKit

class ViewController: UIViewController {

  //: public variables
  var area:               CGFloat?


  override func viewDidLoad() {
      super.viewDidLoad()
      // Do any additional setup after loading the view, typically from a nib.
  }

  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }

  public func printArea(){
      print("Print area in Super class")
  }

  public func calculateArea(){

  }

}

ViewControllerA as subclass :

import UIKit

class ViewControllerA: ViewController {

    var length:                 CGFloat?


     init( len: CGFloat) {
        self.length = len
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func printArea() {
        print("The are of A \(area!)")
    }


    override func calculateArea() {
        area = length! * length!
    }
}

I have got the error. Must call a designated initializer of the superclass 'ViewController' in subclass init method.

So I declare the empty init method in super class i.e ViewController

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nil, bundle: nil)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

It worked for me.

Upvotes: 0

Karlin Fox
Karlin Fox

Reputation: 191

You'll need to declare an empty public init() {} in Router.

Though it's a cryptic error, the problem is that the subclass cannot call super.init() because that initializer is not accessible outside of the NetworkManager module unless you declare it as public. The automatically-generated init() in Router is not public by default.

It worked in your test class because the @testable import sidestepped the default internal access restriction.

Upvotes: 4

Related Questions