Not being able to access functions or get variables on Photon from iOS app (swift)

No sure where I am getting it wrong.
I can successfully retrieve the device. But cannot call any functions or retrieve variables from it. The SDK methods are returning errors or nil results.
Am I missing some configuration on my .INO file to make it listen for iOS calls?

My error:

Led error Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: not found (404)" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7f8c0041c610> { URL: https://api.particle.io/v1/devices/3a0035000b47343432313031/ledToggle } { status code: 404, headers {
    "Access-Control-Allow-Origin" = "*";
    Connection = "keep-alive";
    "Content-Length" = 50;
    "Content-Type" = "application/json; charset=utf-8";
    Date = "Sat, 06 Aug 2016 01:55:58 GMT";
    Etag = "W/\"32-43c76b0e\"";
    Server = nginx;
} }, NSErrorFailingURLKey=https://api.particle.io/v1/devices/3a0035000b47343432313031/ledToggle, com.alamofire.serialization.response.error.data=<7b0a2020 226f6b22 3a206661 6c73652c 0a202022 6572726f 72223a20 22566172 6961626c 65206e6f 7420666f 756e6422 0a7d>, NSLocalizedDescription=Request failed: not found (404)}

My iOS functions:

override func viewDidLoad() {
    super.viewDidLoad()
    getDevices()
}

func getDevices(){
    print("getDevices")
    SparkCloud.sharedInstance().getDevices { (sparkDevices:[AnyObject]?, error:NSError?) -> Void in
        if let e = error
        {
            print("Check your internet connectivity \(e)")
        }
        else
        {
            if let devices = sparkDevices as? [SparkDevice] {
                for device in devices
                {
                    print("\(device.name)")
                    if device.name == "watermate"
                    {
                        let myDeviceVariables : Dictionary? = device.variables as? Dictionary<String,String>
                        print("MyDevice first Variable is called \(myDeviceVariables!.keys.first) and is from type \(myDeviceVariables?.values.first)")
                        
                        let myDeviceFunction = device.functions
                        print("MyDevice first function is called \(myDeviceFunction!.first)")

                        self.ledToggle(device)
                    }
                }
            }
        }
    }
}

func ledToggle(device: SparkDevice){
    print("ledToggle")
    device.getVariable("ledToggle", completion: { (result:AnyObject?, error:NSError?) -> Void in
        if let e = error
        {
            print("Led error \(e)")
        }
        else
        {
            print("Led status \(result)")
        }
    })
}

My .ino file

int led1 = D0; // Instead of writing D0 over and over again, we'll write led1
int led2 = D7; // Instead of writing D7 over and over again, we'll write led2

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop() {
  digitalWrite(led1, HIGH);
  delay(1000);
  digitalWrite(led1, LOW);
  delay(1000);
    ledToggle ("on");
}

int ledToggle(String command) {
    if (command=="on") {
        digitalWrite(led2, HIGH);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(led2, LOW);
        return 0;
    }
    else {
        return -1;
    }
}

You seem to have some confusion over functions and variables; in your Swift code, you’re getting “ledToggle” as if it were a variable, but in your .ino file, you have a function called ledToggle, not a variable with that name. The problem is, you have no Particle functions or variables in your .ino file (also, I don’t see anything in your iOS code that tries to call a function). You do try to access a variable, but you need to have a variable in your .ino code, and you need to have a statement that registers that variable as a Particle.variable. So, for instance, if you had a variable called ledStatus and a function called ledToggle, you would need something like this,

int ledStatus;

void setup() {
  Particle.variable("ledStatus", ledStatus); // the name doesn't have to be the same as the variable name. It can be anything as long as it's not longer than 12 characters
  Particle.function("ledToggle", ledToggle);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

int ledToggle(String command) {
    if (command=="on") {
        digitalWrite(led2, HIGH);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(led2, LOW);
        return 0;
    }
    else {
        return -1;
    }
}

Of course, you would also need to be setting the value of ledStatus somewhere in your code.
This is all explained in the docs.

2 Likes