external device http-based control API

trying to get xcode to send commands to an external device which uses http-based API with following URL syntax:


http://<usr>:<pwd>@<ipAddress>/Gadget/syncconnect/sdk.aspx?command=<command>


any advice on how that might be implemented in viewcontroller?

Replies

According to manufacturer of external device, C# needs the following line of code:

webclient.Credentials = new NetworkCredential("<username>", "<pass- word>");

using (Stream stream = webclient.OpenRead(new Uri ( "http://<ipAd- dress>/Gadget/syncconnect/sdk.aspx?command=<command>")))

Can anyone please point to examples or advise where this might be placed in viewcontroller?

thanks

I'm not an expert but you are asking...."(how do I) send commands to an external device" and "us(ing) http-based ...syntax". Your big question is 'how do i send commands to an external device". That depends on how the external device is connected to your device. If it is connected to the internet then you can make various requests through HTTP following this:

https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/WorkingWithHTTPAndHTTPSRequests/WorkingWithHTTPAndHTTPSRequests.html


But if your device is connected some other way then the answer to your question is buried in the documents relating to that other way.

HI PBK,


Thanks for response. You're right, I should be asking, 'how do i send commands to an external device?"


The device is connected via LAN.


I'll work through the link you've provided and try to get communication working.


Many thanks,

Hi PBK,


I've read (and re-read) the link you provided, thanks, but haven't quite determined which of the methods (e.g. NSURLSession, NSURLConnection, socket, or socket-stream) might be appropriate to this situation.


The manufacturer has provided examples of a few applications and scripting languages for use with their LAN-based external device:

  • GNU Wget
  • cURL
  • C# (C Sharp)

Heres the C#


using System.Net;
WebClient webclient = new WebClient();

webclient.Credentials = new NetworkCredential("<username>", "<password>");
string pageContent = string.Empty;
try

{
using (Stream stream = webclient.OpenRead(new Uri ("http://<ip address>/Gadget/syncconnect/sdk.aspx?command=<command>")))Example third-party tools{

{

using (StreamReader reader = new StreamReader(stream))

{

pageContent = reader.ReadToEnd(); }

}

}

}

catch (WebException e)

{
}

}


Any pointers on where to look/read next?


Many thanks,



>The device is connected via LAN.


You might want to move this to theNetworking forum. Might provide a better chance of catching the expert's eye.


Good luck.

I think that a C# programmer will be able to define appropriate NSURL commands using the program above, link above and also:

https://developer.apple.com/reference/foundation/nsurl?language=objc

The challenge is that the API's force you into developing in a completely asynchronous way with no real easy way for doing similar in a synchronous way. I think someone coming into this new (like me) is in the mindset of testing device/REST APIs using curl and trying to emulate that in Apple API's ... and thinking "all I need to do is request a URL and the API is requiring multiple object creation using call backs / blocks in a completely round about way, why can't I get what I need in 1 simple call?. Using NSURLSession, there is no way to simply submit a URL request and expect a synchronous reply with the data you want.


If your device/REST API is very simplistic, you might look and see if NSData dataWithContentsOfURL: does what you need. It's a synchronous call but I have't tested it to see how well it tolerates username/password and query string. NSData returns an object filled with the return data, you will need to figure out what that data means and parse it.

In my project I roughy did the following:

- create NSURLSessionConfguration object and added in desired headers

- create the NSURLSession with configuration object

- create NSMutableURLRequest object so I could change http request type, timeout, etc.

- I use NSURLSession dataTaskWithRequest: completionHandler: to set up the task. The handler block is very basic, all it does is copy the return data into instance variables, so something like this:

// Instance variables:
    __block NSData * blockData;
    __block NSURLResponse * blockResponse;
    __block NSError * blockError;
// Callback
callback = ^(NSData *d, NSURLResponse *r, NSError *e) {
        blockData = [d copy];
        blockResponse = [r copy];
        blockError = [e copy];
    };

- [task resume] call to start the query

- Then I do the following which I am sure will make the API developers howl in rage:

while([task state] == NSURLSessionTaskStateRunning ) { [NSThread sleepForTimeInterval:.2]; }


This basically is a spin-lock on the task request and relies on the NSMutableURLRequest timeout to cancel and return error if the expected call takes too long. For my device I expect a response within about 5s and if it is longer, there's likely a problem.


I already know this is the wrong way to do things, but for my simple project it got me some tangible results while I continue to learn how to do these things more asychronously and/or use delegates to handle requests.


I hope that helps

>I continue to learn how to do these things more asychronously


Some interesting discussion in this 2015 thread, I think:

https://forums.developer.apple.com/thread/11519


And for bedtime reading:

Asynchronous Versus Synchronous Operations