1

I am working on a project that sends some HTTP commands with an IP address that the user defines in a text field. The IP address is essentially piped into many different functions for my app. As I have done this I keep running into the "Instance member cannot be used on type" error. At the fundamentals of variable declaration, what would be the correct way to do the following? I will have about 40-50 different requests.

@IBOutlet weak var myIPaddress: UITextField!
var baserequest = "http://\(myIPaddress):8088/api/?function="
var requestA = "\(baserequest)myFunctionA&value=abc"
var requestB = "\(baserequest)myFunctionB&value=xyz"
var requestC = "\(baserequest)myFunctionC&value=123"
...
...

I am not sure if this matters but because we are using HTTP commands one of the declarations looks like this

var program1 = NSMutableURLRequest(URL: NSURL(string: "\(baseRequest)activeinput&input=1" )!)

* UPDATE *

I am not sure what my issue is. Here is the code I have and it's still throwing that error. On

var request1 = NSMutableURLRequest(URL: NSURL(string: "\(baserequest)activeinput&input=1" )!)

So this is my entire code

import UIKit
import Foundation


func httpGet(request: NSURLRequest!, callback: (String?, NSError?) -> Void) {
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
    guard error == nil && data != nil else {
        callback("", error)
        return
    }

    callback(String(data: data!, encoding: NSUTF8StringEncoding), nil)
}
task.resume()
}

class FirstViewController: UIViewController, UITextFieldDelegate {

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.
}



@IBOutlet weak var vmixip: UITextField!
var baserequest: String = ""

func textFieldDidEndEditing(textField: UITextField) {
    updateBaseRequest(textField.text!)
}

func updateBaseRequest(vmixip: String) {
    baserequest = "http://\(vmixip):8088/api/?function="
}

var request1 = NSMutableURLRequest(URL: NSURL(string: "\(baserequest)activeinput&input=1" )!)
@IBAction func Program1(sender: UIButton) {
    if let image = UIImage(named:"g1") {
        sender.setImage(image, forState: .Normal)
    }
    httpGet(request1) { string, error in
        guard error == nil && string != nil else {
            print(error?.localizedDescription)
            return
        }

        print(string!) //
    }


}

}
halfer
  • 19,824
  • 17
  • 99
  • 186
Seth Haberman
  • 131
  • 1
  • 13
  • Where exactly do you get this error? – beeef Nov 13 '15 at 21:10
  • You have a couple of problems, 1, you would need to refer to `myIPaddress.text` to get the string in the text field, but more importantly you can't use the value at that point anyway because you end to update `baseRequest` and all of the other variables when the user changes the field, so you are going to need to write code in something like the UiTextFieldDelegate to do that – Paulw11 Nov 13 '15 at 21:11
  • Hi Seth. Would you consider upvoting any of the answers you receive, and/or accepting one of them? This is how we reward helpful answers here. – halfer Jan 05 '16 at 19:43

2 Answers2

2

You should be initializing the request variables in a function after you have the user's IP address. The error is trying to tell you that the default value of variables can't something that hasn't been initialized yet (myIPaddress).

Something like:

@IBAction func addressEntered(sender: UIButton) {
    // NOTE: Use myIPaddress.text to get the text
    baserequest = "http://\(myIPaddress.text):8088/api/?function="
    requestA = "\(baserequest)myFunctionA&value=abc"
    requestB = "\(baserequest)myFunctionB&value=xyz"
    requestC = "\(baserequest)myFunctionC&value=123"
}

In addition, you'd need to declare those variables as optionals if you need them throughout the class:

class MyClass {
    var requestA: String?
    ...
}

Alternatively, you could turn your request variables into computed properties:

class MyClass {
    var baseRequest: String?
    var requestA: String {
        // Beware, this would crash if used before baseRequest was initialized
        return "\(baseRequest!)myFunctionA&value=abc"
    }
}
Community
  • 1
  • 1
Andrew
  • 15,357
  • 6
  • 66
  • 101
1

The "Instance member cannot be used on type" error is being caused by referencing values that are not available yet.

For example, you can't have

var myValue = "something"

and then reference that value again in

var myValueAgain = self.myValue

The initialization of properties doesn't work like code in a function. This is because "self" is not available until the object is created. You are trying to access "self" before it is available.


Another problem is that you are referring to a UITextField in

var baserequest = "http://\(myIPaddress):8088/api/?function="

whereas the value with the String type that you can use is in

myIPaddress.text

Assigning the value at initialization also will not update the value automatically as it changes in your UI.

Handling the change of the text field requires implementing methods for UITextFieldDelegate such as

  • textFieldDidBeginEditing:
  • textFieldDidEndEditing:

You use those methods to update your baserequest when the user updates the text in the text field.

Therefore, your class will have something like this

class MyViewController: UIViewController, UITextFieldDelegate {

    var baserequest: String

    func textFieldDidEndEditing(textField: UITextField) {
        updateBaseRequest(textField.text)
    }

    func updateBaseRequest(ipAddress: String) {
        baserequest = "\(ipAddress)..."
    }
}
Daniel Zhang
  • 5,778
  • 2
  • 23
  • 28
  • I'm sorry, I am not sure what I am missing here. This is my code. – Seth Haberman Nov 13 '15 at 22:16
  • If you make a function to get your requests based on the request number or something such as `func getRequest(requestNumber: Int) -> String` then you will avoid that problem where the instance members cannot be used. You'll need to remove `var request1 = NSMutableURLRequest(URL: NSURL(string: "\(baserequest)activeinput&input=1" )!)` to clear the error. Replacing it by a function is my recommendation. Every time you need to get the URL, you would use the function. – Daniel Zhang Nov 13 '15 at 22:35
  • @SethHaberman I've updated my answer to better explain what is happening. Let me know if that helps. – Daniel Zhang Nov 13 '15 at 22:46