Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Transfer Large Files over wifi in iOS

I downloaded WiTap Code From Apple's website. Its for transferring data over local wifi network. I am working in a project to interact as client - server architecture. I am sending NSData from client side to server.

I made 2 projects; one for client and one for server

At client side project, i made following Changes For that I modified the AppController.m file by adding following method

AppController.m (Client side)

- (void)sendData:(NSData*)pobjData
{
    assert(self.streamOpenCount == 2);

    if ( [self.outputStream hasSpaceAvailable] ) 
    {
        NSInteger   bytesWritten;

        NSUInteger length = [pobjData length];

        bytesWritten = [self.outputStream write:[pobjData bytes] maxLength:[pobjData length]];

        NSLog(@"written bytes -> %d",bytesWritten);
    }
}

Then by calling this method I send data.

At Server side project, I made following chagnes for that I modified the AppController.m file by modifying following method

AppController.m (Server side)

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
    #pragma unused(stream)

    switch(eventCode) {

        case NSStreamEventOpenCompleted: {
            self.streamOpenCount += 1;
            assert(self.streamOpenCount <= 2);

            // Once both streams are open we hide the picker and the game is on.

            if (self.streamOpenCount == 2) {
                [self dismissPicker];

                [self.server deregister];
            }
        } break;

        case NSStreamEventHasSpaceAvailable: {
            assert(stream == self.outputStream);
            // do nothing
        } break;

        case NSStreamEventHasBytesAvailable:
        {
            if (stream == self.inputStream)
            {

                NSInteger bytesRead;
                uint32_t buffer[32768];

                NSMutableData *_data = [NSMutableData data];

                // Pull some data off the network.
                bytesRead = [self.inputStream read:buffer maxLength:sizeof(buffer)];
                if (bytesRead == -1) {

                } else if (bytesRead == 0) {

                } else {
                    // FIXME: Popup an alert

                    const long long expectedContentLength = bytesRead;
                    NSUInteger expectedSize = 0;

                    // expectedContentLength can be represented as NSUInteger, so cast it:
                    expectedSize = (NSUInteger)expectedContentLength;

                    [_data appendBytes:buffer length:expectedSize];

                    NSLog(@"\"Data received has length: %d", _data.length);

                    [self performSelector:@selector(getData:) withObject:_data afterDelay:1.0];
                }
            }
        }
            break;

        default:
            assert(NO);
            // fall through
        case NSStreamEventErrorOccurred:
            // fall through
        case NSStreamEventEndEncountered: {
            [self setupForNewGame];
        } break;
    }
}

and added a method to write the received data as a file

     #define kUserDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)

-(void)getData:(NSMutableData *)pData
{
                NSFileManager *tmpmanager = [NSFileManager defaultManager];
                [tmpmanager createFileAtPath:[AppController getDocumentDirectoryPath:[NSString stringWithFormat:@"%@.png",[NSDate date]]] contents:pData attributes:nil];
}


+(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
            NSString *strPath=nil;

            if(pStrPathName)
                strPath = [[kUserDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];

            return strPath;
}

I convert .png files to NSData and send them from client side to server side. the server downloads the file to Document Directory

The matter is , when i transfer file from client side , it gets downloaded to server side at document directory. Everything works fine in case of tiny files. If file size exceeds to 8kB , file written at document directory gets corrupted.

Kindly help me to be able to send large files.

like image 853
HarshIT Avatar asked Apr 05 '13 09:04

HarshIT


1 Answers

The problem is that your code doesn't loop to gather all of the available data till the end (or loop to send all data either). So you only ever receive the first buffer of data. If the image is small then that works ok, if the image is bigger then it never will.

You need to write the code so that it keeps sending when there is buffer space until all data is sent and keep reading data (into an NSMutableData instance variable, not a local variable) until the end of the stream is reached.

like image 155
Wain Avatar answered Oct 18 '22 07:10

Wain