-1

I have no idea why I cannot call token on this argument, I keep getting error on this line

.ExtraHeaders(["Authorization": token])

The error

Instance member 'token' cannot be used on type 'SocketIOManager'

Full code

import SocketIOClientSwift
import KeychainAccess

class SocketIOManager: NSObject {
    static let sharedInstance = SocketIOManager()



    let keychain = Keychain(server: "https://testing.herokuapp.com", protocolType: .HTTPS)

    var token: String {
        get {
            return String(keychain["token"])
        }
    }


    let socket = SocketIOClient(socketURL: NSURL(string: 
       "https://testing.herokuapp.com")!, 
       options: [.Log(true), .ExtraHeaders(["Authorization": token]) ])


    override init() {
        super.init()
    }


    func establishConnection() {
        socket.connect()
    }



    func closeConnection() {
        socket.disconnect()
    }


}
airsoftFreak
  • 1,450
  • 5
  • 34
  • 64

1 Answers1

0

The problem can be distilled into a tiny bit of code:

class Test {
    let test = "test"
    let test2 = test + "2" // instance member 'test' cannot be used on type 'Test'
}

The problem is that when those fields are initialized, the object doesn't exist yet. There are two ways of dealing with this:

 class Test {
    let test = "test"
    lazy var test2:String = self.test + "2" // since test2 is lazy, it only gets computed at a time when the object already exists
}

and

class Test {
    let test = "test"
    let test2:String

    init() {
        test2 = test + "2" // you can set constants in initializers
    }
}

The downside of the first option is that you have to use var, and you need to explicitly write self, the downside of the second is that your initializing code is not right where the declaration is. (though init() is a very logical place to look next) Both way require you to explicitly state the type. You have to decide what's more important to you, I'd opt for leaving constants constants when possible. But when you're using var already, might as well for the first option.

Note that if you choose the second option and your class inherits from another class, you need to initialize the member before calling super.init():

class Test: SuperTest {
    let test = "test"
    let test2:String

    override init() {
        test2 = test + "2"
        super.init()
    }
}

The compiler will yell at you if you don't do this, so it's hard to get it wrong.

overactor
  • 1,759
  • 2
  • 15
  • 23