Can EADemo send http request - iphone

Can someone suggest if it is possible to modify the EADemo to send HTTP request (custom header and body). In the project I am working on, the external accessory will be receiving the data using http request.
The method which is for writing on EADemo is
- (void)writeData:(NSData *)data;

Ok, so I found an example which I will be using but instead of GET I will use POST. Below is the example of GET request:
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
NSLog(#"stream:handleEvent: is invoked...");
switch(eventCode) {
case NSStreamEventHasSpaceAvailable:
{
if (stream == oStream) {
NSString * str = [NSString stringWithFormat:
#"GET / HTTP/1.0\r\n\r\n"];
const uint8_t * rawstring =
(const uint8_t *)[str UTF8String];
[oStream write:rawstring maxLength:strlen(rawstring)];
[oStream close];
}
break;
}
// continued ...
}
}
https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/Streams/Articles/NetworkStreams.html

Related

How to init NSInputStream with a part of file?

I was woking on YouTube Resumable Uploads: https://developers.google.com/youtube/2.0/developers_guide_protocol_resumable_uploads#Sending_a_Resumable_Upload_API_Request
I use ASIHttpRequest to upload the videos.
For a direct uploading, I can use this method.
- (void)appendPostDataFromFile:(NSString *)file
But for an resume uploading, I can't append post data from the whole video file.
Maybe I can write a method like this:
- (void)appendPostDataFromFile:(NSString *)file offset:(long long)offset
But I don't know how to make it work. Any help will be appreciated!
And here is the code from ASIHttpRequest:
- (void)appendPostDataFromFile:(NSString *)file
{
[self setupPostBody];
NSInputStream *stream = [[[NSInputStream alloc] initWithFileAtPath:file] autorelease];
[stream open];
NSUInteger bytesRead;
while ( !_isTryCanceled && [stream hasBytesAvailable] ) {
unsigned char buffer[1024*256];
bytesRead = [stream read:buffer maxLength:sizeof(buffer)];
if (bytesRead == 0) {
break;
}
if ([self shouldStreamPostDataFromDisk]) {
[[self postBodyWriteStream] write:buffer maxLength:bytesRead];
} else {
[[self postBody] appendData:[NSData dataWithBytes:buffer length:bytesRead]];
}
}
[stream close];
}
As the code show above, if I can get a seekable NSInputStream, the problem will be solved. Is it possible to do so?

GCDAsyncSocket - Read stream never completes

I am playing with GCDAsyncSocket (MRC / iOS5.1) for a while, especially with "large" files (5 - 10 mb). Unfortunately sometimes the read stream is never completed (e.g. it gets stuck) just a few bytes at the end of the stream; the didReadPartialDataOfLength: stops giving me information and the didReadData is not fired at all.
Here's some of my code (for both writing / reading examples the connection between the host and client have been established)
WRITING
#define kHeadTag 0
#define kDataTag 1
typedef struct {
NSUInteger size;
} head_t;
-(void)sendData:(NSData *)__data {
_sendData = [__data retain];
head_t header;
header.size = __data.length;
[_socket writeData:[NSData dataWithBytes:&header
length:sizeof(header)]
withTimeout:-1
tag:kHeadTag];
}
-(void)socket:(GCDAsyncSocket *)sock
didWriteDataWithTag:(long)tag {
if (tag == kHeadTag) {
[sock writeData:_sendData withTimeout:-1 tag:kDataTag];
[_sendData release];
_sendData = nil;
}
}
READING
-(void)socket:(GCDAsyncSocket *)sock
didReadData:(NSData *)data
withTag:(long)tag {
switch (tag) {
// ------------------------------------- HEAD
case kHeadTag:{
head_t head;
[data getBytes:&head length:sizeof(head)];
_readHead = head;
NSLog(#"Received header (total size = %i bytes)", head.size);
[sock readDataToLength:head.size
withTimeout:-1
tag:kDataTag];
}
break;
// ------------------------------------- BODY
case kDataTag: {
NSLog(#"Data received with %i bytes", data.length);
[sock readDataToLength:sizeof(head_t) withTimeout:-1 tag:kHeadTag];
}
break;
}
};
-(void)socket:(GCDAsyncSocket *)sock
didReadPartialDataOfLength:(NSUInteger)partialLength
tag:(long)tag {
if (tag == kDataTag) {
NSLog(#"Data read with %i bytes", partialLength);
}
};
I hope this is enough code to see what I'm doing wrong or maybe this is a bad practice for writing/reading large chunks of data.
I added
[self.partnerSocket writeData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
at the end of sendData: method, and it works fine for me. You just have to append separator chars at the end of the data.
I can transfer around 48MB of file from one iDevice to other iDevice

how can i send a text to another device only after receiver side instream and outstream setup is done?

i created a network Application to transfer text message between two devices through WiFi network.when i select a device to pair there is a delegate called "TCPServerAcceptCallBack" will trigger in receiver side and it will setup the input and output streams.
but it will take milliseconds to do the setup of streams.whenever i am sending a data from my device there is checking of [_outStream hasSpaceAvailable].i mentioned that instream and outstream setup in receiver side will take milliseconds .so first time the condition will false.i used while loop to stop doing send method before setup is done.but there is a problem that when execution in while loop there is a chance to connection lose in receiver side and also not confident with while loop.
next i created a sleep of 3 millisecond ,it working fine but there is chance of occur error when network is very slow.
i am planning to trigger a delegate from receiver side to sender device at the time of instream and outstream setup is done.so please tell me how can do it (or) provide me any other good way to solve this problem...
My Code...receiver side
case NSStreamEventHasBytesAvailable:
{
if (stream == _inStream) {
// read it in
unsigned int len = 0;
//here the length is assigning..i can send text files only after this below statement is executed.but it will take few minitus.
len = [_inStream read:buf maxLength:buffSize];
buf[len] = '\0';
if(!len) {
if ([stream streamStatus] != NSStreamStatusAtEnd)
NSLog(#"Failed reading data from peer");
} else {
NSString *message = [NSString stringWithUTF8String:(char *)buf];
//Display image from app bundle
NSString *path=[[NSBundle mainBundle] pathForResource:message ofType:#"png"];
if(path !=nil)
{
[imageView setImage:[UIImage imageWithContentsOfFile:path]];
}
else
{
UIImage *image = [UIImage imageNamed:#"no_image.png"];
[imageView setImage:image];
}
// here you do whatever you need with your received NSString *message
[txtUserInput setText:message];
}
}
break;
Sender part..
[- (void) sendText:(NSString *)string {
const uint8_t *message = (const uint8_t *)[string UTF8String];
//waiting up to outStream hasSpaceAvailable
while (![_outStream hasSpaceAvailable]) {
continue;
}
//once outStream hasSpaceAvailable it will send datas.
if (_outStream && [_outStream hasSpaceAvailable])
if([_outStream write:message maxLength:strlen((char *)message)] == -1)
NSLog(#"Failed sending data to peer");
}
#end
Don't use a while loop,that's just wasting CPU cycles. Do it in the callback.

how can i pass a NSArray over WiFi network?

can any one provide me a good way to send a NSArray object over wifi network.
I have a code to sent a text message(string) over wifi network.
my code is
Send
- (void) sendText:(NSString *)string {
const uint8_t *message = (const uint8_t *)[string UTF8String];
if (_outStream && [_outStream hasSpaceAvailable])
if([_outStream write:message maxLength:strlen((char *)message)] == -1)
NSLog(#"Failed sending data to peer");
}
Receiver Side
- (void) stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if (stream == _inStream) {
// read it in
unsigned int len = 0;
len = [_inStream read:buf maxLength:buffSize];
buf[len] = '\0';
if(!len) {
if ([stream streamStatus] != NSStreamStatusAtEnd)
NSLog(#"Failed reading data from peer");
} else {
NSString *message = [NSString stringWithUTF8String:(char *)buf]; }}
now the message contains my received message...
However i need to send a NSArray object over wifi.can any one help me to do it..
You can use the NSKeyedArchiver to get a NSData object out of your NSArray, the NSData object is just a wrapper for binary data so you can send it over your socket. When you received the data, first transform it back into an NSData object and then use the NSKeyedUnarchiver class to get the array back.
You need mechanism (protocol) that will send elements of array from sender end and in the same way it will receive at the reception end

Have been cursing over data packets for 36 hours now, please help!

Ok Here is the problem. I am trying to send through a structure or anything through the apple bluetooth send network packet code. The code to send is below
-(void)sendMessagePacket:(GKSession *)session packetID:(int)packetID withData:(void *)data ofLength:(int)length reliable:(BOOL)howtosend {
static unsigned char networkPacket[maxPacketSize];
const unsigned int packetHeaderSize = 2 * sizeof(int); // we have two "ints" for our header
if(length < (maxPacketSize - packetHeaderSize)) { // our networkPacket buffer size minus the size of the header info
int *pIntData = (int *)&networkPacket[0];
// header info
pIntData[0] = 10;
pIntData[1] = packetID;
// copy data in after the header
memcpy( &networkPacket[packetHeaderSize], data, length );
NSData *packet = [NSData dataWithBytes: networkPacket length: (length+8)];
if(howtosend == YES) {
[session sendDataToAllPeers:packet withDataMode:GKSendDataReliable error:nil];
} else {
[session sendDataToAllPeers:packet withDataMode:GKSendDataUnreliable error:nil];
}
}
}
If anyone could go through this with a comb and explain what is going on that would be greatly appreciated. Next, the receive code.
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
// Caller whenever data is received from the session
unsigned char *incomingPacket = (unsigned char *)[data bytes];
//EXPECTS THAT WHAT IS IN INCOMING PACKET [0] TO BE OF DATA TYPE INTEGER
int *pIntData = (int *)&incomingPacket[0];
int packetTime = pIntData[0];
int packetID = pIntData[1];
static int lastPacketTime = -1;
switch (packetID) {
case NETWORK_COINTOSS:
//DO SOMETHING
break;
case NETWORK_TEXT_EVENT:
NSString *fewMore = (NSString *)&incomingPacket[8];
fewThings *bitMore = &fewMore[peer];
//NSLog(#"Trace Bit More: %#",fewMore);
break;
default:
break;
}
NSInteger lengthBytes = [data length];
NSLog(#"Length of data : %i", lengthBytes);
}
What i am struggling to understnad being a newcome to objective c is how all this works, how do i access the string that i have send as all efforts to log it cause the program to crash.
Below is the code used to start the send:
NSString *bigWord = #"BigWordBigWord";
NSInteger len = [bigWord length];
[self sendMessagePacket:gameSession packetID:NETWORK_TEXT_EVENT withData:bigWord ofLength:(len) reliable:YES];
Any help would be so appreciated. Thank You.
You really need to change the NSString object into either a UTF8 representation to send, or to archive it as an NSData object you send with the full length - you can't just cast an NSString as a C string (either for sending or receiving!!!).
You can get a C string version of NSString using:
const char *sendString = [bigWord cStringUsingEncoding:NSUTF8StringEncoding]
And then get it out of your incoming NSData object with
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
This guy is sending and receiving the string over network just fine. But, I'm also still getting error on the receiving end.
http://discussions.apple.com/thread.jspa?messageID=10215848
At last got it. GKTank is transferring the data using struct, so I placed my string inside the struct and rest is the history.
typedef struct {
NSString *strInfo;
} myInfo;