0

Based off this question regarding an animated Progressbar WebView in Swift, I tried to implement the code from the chosen answer. The build failed and I received the following error in Xcode 6.1.1:

Class 'WebView' has no initializers

Xcode prompts me to then input this code:

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

The build succeeds but then the app crashes when I try to load the aforementioned WebView. It gives me this error:

Thread 1: EXC_BAD_INSTRUCTION

Starscream later clarified that if the variables are added to a class "they need to be initialized at init time." Wasn't sure how to initialize the variables, so here was my attempt:

class WebView: UIViewController {
required init(coder aDecoder: NSCoder) {
    var theBool: Bool = false
    var myTimer = NSTimer()
}

@IBOutlet var webView: UIWebView!
@IBOutlet var myProgressView: UIProgressView!

var theBool: Bool
var myTimer: NSTimer

override func viewDidLoad() {
    super.viewDidLoad()
    let url = NSURL(string: "http://www.stackoverflow.com")
    let request = NSURLRequest(URL: url!)
    webView.loadRequest(request)
}

func funcToCallWhenStartLoadingYourWebview() {
    self.myProgressView.progress = 0.0
    self.theBool = false
    self.myTimer = NSTimer.scheduledTimerWithTimeInterval(0.01667, target: self, selector: "timerCallback", userInfo: nil, repeats: true)
}

func funcToCallCalledWhenUIWebViewFinishesLoading() {
    self.theBool = true
}

func timerCallback() {
    if self.theBool {
        if self.myProgressView.progress >= 1 {
            self.myProgressView.hidden = true
            self.myTimer.invalidate()
        } else {
            self.myProgressView.progress += 0.1
        }
    } else {
        self.myProgressView.progress += 0.05
        if self.myProgressView.progress >= 0.95 {
            self.myProgressView.progress = 0.95
        }

Which brings this error:

Super.init isn't called before returning from initializer.

How do I go about correctly initializing the variables? Sorry if this was overly longwinded.

Community
  • 1
  • 1
kuzogari
  • 1
  • 3

2 Answers2

0

You don't need to use a required-init method. Xcode shows that you need it ,because you've initialized these variables the wrong way:

var theBool: Bool
var myTimer: NSTimer

Also you shouldn't initialize your variable in the init method like you did, because that way, you can't access it inside another method, because the variables aren't global. If you want to use this init-method you have to add the super.init to it and move the variables outside of the init too. Just the initialization should happen inside:

var theBool: Bool!
var myTimer: NSTimer!

required init(coder aDecoder: NSCoder) {
    self.theBool = false
    self.myTimer = NSTimer()

    super.init(coder: aDecoder)
}

But to resolve that error, you could init your variables like that, outside of a function as a global variable, inside the class body, and you don't need the required-init anymore:

//Straight initialize it
var theBool: Bool = false
var myTimer: NSTimer = NSTimer()

or:

//Say, that they will be initialited later in the code with the '!'
var theBool: Bool!
var myTimer: NSTimer!
Christian
  • 22,585
  • 9
  • 80
  • 106
  • Thank you for the response @ChristianWoerz. I used `var theBool: Bool = false var myTimer: NSTimer = NSTimer()` and the build succeeds and I can properly load the WebView. However, the ProgressBar doesn't animate and it doesn't disappear when the page is loaded. Any suggestions to fix these issues? I had to make the following change too: `func timerCallback() { if (self.theBool != nil) { ...}` – kuzogari Feb 18 '15 at 20:51
0

As the error message say:

Super.init isn't called before returning from initializer.

so you must call super.init(coder: aDecoder) from your class initializer. In your case you have to options to fix this:

1.- Initialize your variables and call super.init

required init(coder aDecoder: NSCoder) {
    self.theBool = false
    self.myTimer = NSTimer()

    super.init(coder: aDecoder)
}

2.- As you are setting default values to the properties assign then "inline" and remove the init method:

var theBool: Bool = false
var myTimer: NSTimer = NSTimer()
tkanzakic
  • 5,499
  • 16
  • 34
  • 41