I'm sending a file between two devices using iOS 7's Multipeer Connectivity Framework. I'm using NSStreams to tranfer the file, as my previous attempt using MCSession's sendData:toPeers:withMode was really unreliable. Unfortunately the transfer speeds I'm getting are really slow, around 100kb/s, which won't work for the application I'm working on. Here are my Input and Output stream delegate methods, which is where the file transfer happens.
Output Stream (in the delegate for the stream)
...//previous code
case NSStreamEventHasSpaceAvailable: {
//we will only open the stream when we want to send the file.
NSLog(@"Stream has space available");
//[self updateStatus:@"Sending"];
// If we don't have any data buffered, go read the next chunk of data.
if (totalBytesWritten< outgoingDataBuffer.length) {
//more stuff to read
int towrite;
int diff = outgoingDataBuffer.length-packetSize;
if (diff <= totalBytesWritten)
{
towrite = outgoingDataBuffer.length - totalBytesWritten;
} else
towrite = packetSize;
NSRange byteRange = {totalBytesWritten, towrite};
uint8_t buffer[towrite];
[outgoingDataBuffer getBytes:buffer range:byteRange];
NSInteger bytesWritten = [outputStream write:buffer maxLength:towrite];
totalBytesWritten += bytesWritten;
NSLog(@"Written %d out of %d bytes",totalBytesWritten, outgoingDataBuffer.length);
} else {
//we've written all we can write about the topic?
NSLog(@"Written %d out of %d bytes",totalBytesWritten, outgoingDataBuffer.length);
[self endStream];
}
// If we're not out of data completely, send the next chunk.
} break;
Input Stream
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
NSLog(@"Bytes Available");
//Sent when the input stream has bytes to read, we need to read bytes or else this wont be called again
//when this happens... we want to read as many bytes as we can
uint8_t buffer[1024];
int bytesRead;
bytesRead = [inputStream read:buffer maxLength:sizeof(buffer)];
[incomingDataBuffer appendBytes:&buffer length:bytesRead];
totalBytesRead += bytesRead;
NSLog(@"Read %d bytes, total read bytes: %d",bytesRead, totalBytesRead);
}break;
case NSStreamEventEndEncountered:
{
UIImage *newImage = [[UIImage alloc]initWithData:incomingDataBuffer];
[[self.detailViewController imageView] setImage:newImage];
NSLog(@"End Encountered");
[self closeStream];
//this should get called when there aren't any more bytes being sent down the stream
}
}
}
Is there a way to speed up this file transfer through either multithreading or using a slightly modified NSStream subclass that makes use of asynchronous sockets?
There are a couple of things I have noticed that cause slow file transfers:
I have been getting decent speeds (and by decent I mean 500K / second) between an iPhone 5S, iPad Air and iPhone Simulator on the MAC.
I had some pretty decent transfer rates going for a while and suddenly it seemed that I was receiving one packet every 15 to 30 seconds. All looked fine on the sender side, but the packets trickle into the receiver. I use sendData:toPeers:withMode in my app.
One of my devices had WiFi turned off. Turning it back on restored my performance even though neither device is connected to a wifi network.
So I'm only ever doing peer-to-peer ad-hoc connections with MPC, but still, with no WiFi hub involved, it appears that iOS is making use of the WiFi signal to carry my data.) I did see in a presentation from Apple a while back that MPC over straight BlueTooth is a dog and I can tell you for a fact that it is.
MPC work on WiFi or bluetooth so it depends on what you are using. If you are using wifi to send files than you will get maximum speed as per the network strength.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With