Reputation: 55544
I'm transferring a reasonably large image over a local network from an iPhone to Mac using the AsyncSocket class. In the header the didReadData delegate method is declared as below:
/**
* Called when a socket has completed reading the requested data into memory.
* Not called if there is an error.
**/
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
It says this method will be called when the socket has completed reading the data. However this method is called many times, each time data length increasing. How am I meant to know when the download is finished? Am I meant to send the length of the data in the first few bytes?
Upvotes: 0
Views: 1537
Reputation: 11330
That delegate method will indeed be called when the socket has completed reading the data. The missing part of the equation is telling the AsyncSocket
when the received data is complete. It has no understanding of the data you're trying to receive, you have to tell it -- as you alluded to in your final question.
This is where AsyncSocket
really shines. You can indeed send the image prefixed by its length and let the class work its magic. Your code would look something like the following.
[sock readDataToData:[AsyncSocket CRLFData] withTimeout:0 tag:kLengthTag];
In your delegate method:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
if (tag == kLengthTag) {
NSUInteger length = /* read length out of nsdata */;
[sock readDataToLength:length withTimeout:0 tag:kImageTag];
} else if (tag == kImageTag) {
/* hurray, you have your image! */
}
}
Of course, if you are transferring reasonably large images, you may want to keep track of your progress. For this purpose, there is the -[AsyncSocket progressOfReadReturningTag:bytesDone:total:]
instance method. There's also the -[id<AsyncSocketDelegate> onSocket:didReadPartialDataOfLength:tag:]
delegate method.
Upvotes: 3