GCDAsyncSocket for iOS is not writing out the buffer - ios

Basically I write an NSData object:
[asyncSocket writeData:JSONRequestData withTimeout:-1 tag:1];
Which when run, invokes the delegate
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
But for some reason, when the write goes to the buffer... it's not written out to the server.
When I stop my build, I guess the socket decides to write everything and the server ends up seeing it.
How would I fix this? There's no way to flush a CocoaAsyncSocket since it's not necessary...
I've tried adding line endings, like "/n" and all, but that doesn't do anything either.

This is based on user523234's suggestion.
Basically the NSData that you're writing out needs to have some kind of signal to tell the socket that no more data will be coming in.
I appended
[GCDAsyncSocket CRLFData];
to the NSData object
Note: to use the
appendData:
Method, you must convert NSData to NSMutableData.

Related

GCDAsyncSocket readDataWithTimeout is not continuing to read data

I am using GCDasyncsocket in my iOS app to send a string over a socket connection and then to read a string every second over the same socket connection. I am also creating a second socket to the same server on a different port ad reading once a second there as well.
My write is working properly and the first few reads on each socket work properly, but then the connection appears to stop.
My current method of reading every second is to kick off the reads by calling
[asyncSocket readDataWithTimeout:1 tag:1];
[asyncSocket_Emove readDataWithTimeout:1 tag:2];
at the end of "didConnectToHost" and the similarly calling them again at the end of "didReadDatawithTag"
I can provide more details if needed, but does anyone have an idea why the socket is stopping?
Replace this line
[asyncSocket readDataWithTimeout:1 tag:1];
with this
[asyncSocket readDataWithTimeout:-1 tag:1];
may work for you.

GCDAsyncSocket lose data

when i use GCDasyncsocket to get socket Message from the server(java),it works in the ios simulator(xcode 6,iphone6+); but when i use my iphone6+ connect it to testing, it will lose data when it receive big data,details below
i send a request to the server and get 3 answers
the first data the server answer length is 9 ,and receive 9
the second is 149 and receive 149
the last data the server answer is :2912,but the code shows 1448,
i get the 1448 in the below code:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(#"receive datas from method 1");
NSLog(#"Data length = %d",[data length]);
...
and when i go deep,the code in the gcdasyncsocket shows the same,code below
if (currentRead->bufferOwner)
{
// We created the buffer on behalf of the user.
// Trim our buffer to be the proper size.
[currentRead->buffer setLength:currentRead->bytesDone];
result = currentRead->buffer;
NSLog(#"if %lu %lu",(unsigned long)currentRead->bytesDone,(unsigned long)result.length);
}
it works well in the simulator,but goes wrong in the real phone;i also test in the iphone4s,it works well most times ~~~~~~~~~~
how strange!
can anyone give me some suggests?
i have got the reason; it is that the protocol split the message ;
i use the method to send the length of the message to tell the protocol how to split it ;
also ,there are some other solutions to solve it ;
and after that ,i also found that the protocol will combine some message,so,when you try to solve it ,you can not just think about the split sitution!

Asynchronous Values Update using GCDAsynSocket api

I am developing one application in which I need to update multiple values like Engine RPM,Speed etc. parameters at a time using OBD connector. I need to achieve asynchronous command/response . For this I am sending commands using [gcdAsyncSocket writeData:data withTimeout:-1 tag:uniqueTag]; asynchronously with unique tag.
But when gcdAsync's delegate method "socketDidReadDatawithTag" is called, it returns the data but it is not proper.e.g. If I have sent one command "010C\r" (Read RPM), and "010D\r" (Speed),with Tag 263 and 264 respectively ,and if I parse the response with tag 264 in socketDidReadDatawithTag , sometimes it returns me the data of RPM. (My response gets Mixed up or OBD Device is unable to handle asynchronous response)
NSLog(#"Command Sent for Async : %#",commandString);
NSData *data = [commandString dataUsingEncoding:NSASCIIStringEncoding];
long obdObjectTag = [obdObject getPIDTag];//Unique Tag
[gcdAsyncSocket writeData:data withTimeout:-1 tag:obdObjectTag];
NSData *readData = [#">" dataUsingEncoding:NSASCIIStringEncoding];
[gcdAsyncSocket readDataToData:readData withTimeout:-1 tag:obdObjectTag];
And in socketdidReadDatawithTag data and tag are mismatched.
The OBD-II connector (I assume it's an ELM-327) cannot really handle asynchronous calls as far as I know.
It cannot handle multiple requests at once. You send 1 command, and the OBD-II device will gather that info from the OBD-bus and return with an answer. Then it will process your next command. Ofcourse, the commands you send end up in a buffer, that will be processed one by one.
I'm thinking this might be a problem for you to make it, but I'm not sure.
I'm not familiar at all with the ios programming and what happens with those tags. You set those tags to identify what paramters are the data for?
In the reply data, you can also see for what parameter it is meant, so in the answer itself you can see that data represents RPM or Speed etc.
I hope the OBD-II part has shed some light on it. Will check this question more for some discussion perhaps.

Handling network exceptions IOS

I am new to objective-c, I am doing the same app for android and iPhone.
When in Java I use a try-catch block to catch a network exception and handle it.
In Objective-C I am using:
[[NSXMLParser alloc] initWithContentsOfURL:url]
So, How can I handle a network exception when parsing that input stream, so if network goes down or there's any problem I can notify user and keep my app working?.
If you are using NSXMLParser then use its delgate method..
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(#"Error = %#", parseError);
}
It is never a good idea to use the initWithContentsOfURL: methods.
You are better of retrieving the the data via NSURLConnection or some library like AFNetworking. This will allow you to handle the HTTP status code and network error.
For example the NSURLConnectionDelegate has a call back method – connection:didFailWithError: which will be called in case of an error.
You can then examen the error object to see what went wrong.
Before you call the URL You can check the internet connectivity.
I suggest you to look the below link
How to check for an active Internet connection on iOS or OSX?
And I suggest for parsing XML file use raptureXML Which is very simple.
https://github.com/ZaBlanc/RaptureXML

Does App WAIT for -initWithContentsOfURL: to retrieve web-data?

I am trying retrieve data from a .php file on a server from within an iPhone OS app. In one method, I employ the following code:
NSString *aString = [[NSString alloc] initWithContentsOfURL:aURL encoding:anEncoding error:nil];
//See what I got
NSLog(aString);
When I run the App it seems like the App runs through the code so fast I doubt that there was enough time for a Data Request to have transpired. The resulting string is totally empty, which further supports my suspicions. What is happening here? Is the app not waiting for the -initWithContentsOfURL to retrieve data from the .php file on my server? If the app does not wait for this method, is there another method I can use to perform a Data Request in a manner that WAITS for the request to be completed before moving onto the next code?
(I've also read a little on NSURLConnection -- is this maybe what I should be looking into instead of -initWithContentsOfURL?)
NSURLConnection is great for getting a file from the web... It doesn't "wait" per se but its delegate callbacks:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
...allow you to be notified when data has been received and when the data has been completely downloaded. This way you can have the App show (if you like) a UIProgressBar as the data comes in and then handle the file as you please when it is completely received.

Resources