dsonawave
dsonawave

Reputation: 167

getting initialization error when trying to segue or instantiate to vc

So my goal is to do a data transfer to the CheckoutViewController() that Stripe provides for their API. So as normal, I went to storyboards and connected a new vc with the CheckoutViewController() class so I can segue to it from my other vc and do a data transfer.

Before this, I was just pushing the vc, and it was working normally and knew I could instantiate it and do a data transfer as well, but even when I try to do it, I get a fatal error saying :

Fatal error: init(coder:) has not been implemented

This is the code I have in the CheckoutVC:

let paymentContext: STPPaymentContext?
let config: STPPaymentConfiguration

let customerContext = STPCustomerContext(keyProvider: MyAPIClient())

init() {
    let config = STPPaymentConfiguration()
    let paymentContext = STPPaymentContext(customerContext: customerContext, configuration: config, theme: .defaultTheme)
    config.requiredBillingAddressFields = .name
    self.paymentContext = paymentContext
    self.config = config
    super.init(nibName: nil, bundle: nil)
    self.paymentContext?.delegate = self
    self.paymentContext?.hostViewController = self
}

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
}

I changed the required init because I read this post on init errors but now it gives an error before even running saying:

Property 'self.paymentContext' not initialized at super.init call

This was all working before I connected the class to a vc in the storyboard, but I literally have no choice, I need to do a data transfer for users to pay the right amount. I don't get how the self.paymentContext wasn't initialized, I was using this just fine before. Does anybody know how I can solve this or work around it?

init() {
   
    super.init(nibName: nil, bundle: nil)
    
}

required init?(coder aDecoder: NSCoder) {
    let config = STPPaymentConfiguration()
    let paymentContext = STPPaymentContext(customerContext: customerContext, configuration: config, theme: .defaultTheme)
    config.requiredBillingAddressFields = .name
    self.paymentContext = paymentContext
    self.config = config
    self.paymentContext?.delegate = self
    self.paymentContext?.hostViewController = self
   super.init(coder: aDecoder)
}

Like this?

Upvotes: 0

Views: 74

Answers (2)

dsonawave
dsonawave

Reputation: 167

The way buddy explained it above really just tripped me out, but eventually I realized he was basically right, all I needed to do was this:

let paymentContext: STPPaymentContext
let config: STPPaymentConfiguration

let customerContext = STPCustomerContext(keyProvider: MyAPIClient())

required init?(coder aDecoder: NSCoder) {
    let config = STPPaymentConfiguration()
    let paymentContext = STPPaymentContext(customerContext: customerContext, configuration: config, theme: .defaultTheme)
    config.requiredBillingAddressFields = .name
    self.paymentContext = paymentContext
    self.config = config
    super.init(coder: aDecoder )
    self.paymentContext.delegate = self
    self.paymentContext.hostViewController = self
}

Works good now.

Upvotes: 0

Shadowrun
Shadowrun

Reputation: 3867

When coming out a storyboard it’s initWithCoder: that is called, not your init() function, and your implementation of initWithCoder calls super before initing all properties

It may be helpful to make a function called commonInit and have all the different initWith..s call commonInit, so your view controller can be instantiated programatically or from nibs etc

Upvotes: 0

Related Questions