What would be the best way to send NSData through

2019-09-18 05:13发布

问题:

Ok I believe this must be a pretty common scenario. I need to send a NSData variable over a HTTP request through a PHP page which then subsequently stores it in MySQL. This will be retrieved later by some other HTTP call which then downloads it into a NSData again. What is the best way to do this?

Should I convert the NSData into some sort of string representation (base64 etc)? Should I store the data in MySQL as VARCHAR or Blob? The data length will not exceed the MySQL/HTTP limit.

回答1:

You're probably going to make things much easier on yourself by Base64 encoding the data for transmission back and forth to the server. (Or yEnc, or some other ASCII encoding of the bytes.) You certainly can transmit raw bytes back and forth (after all, that's what we do with images, right?), but there's less to worry about with encodings and other HTTP headers with string data.

On the server side, then, you could store the strings in character fields in the database, you could decode them and store in BLOBs, you could save them out to the file system.... Without knowing more about the requirements of your app, it's kind of hard to say what the "best" option would be.



回答2:

Easiest way is to Base64 encode the data and create a web service that lets you send the information back and forth.

Here's a category for doing Base64 encoding/decoding that I found on the web:

ECBase64.h

#import <Foundation/Foundation.h>



    @interface NSData ( NSDataBase64Additions )

    + (NSData*)dataWithBase64EncodedString: (NSString*)string;
    - (id)initWithBase64EncodedString: (NSString*)string;

    - (NSString*)base64Encoding;
    - (NSString*)base64EncodingWithLineLength: (NSUInteger)lineLength;

    @end

ECBase64.m:

   #import "ECBase64.h"

    static char encodingTable[64] = {
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };

    @implementation NSData ( NSDataBase64Additions )

    + (NSData*)dataWithBase64EncodedString: (NSString*)string 
    {
        NSData* result = [[NSData alloc] initWithBase64EncodedString: string];
        return [result autorelease];
    }

    - (id)initWithBase64EncodedString: (NSString*)string 
    {
        NSMutableData* mutableData = nil;

        if ( string ) 
        {
            unsigned long ixtext = 0;
            unsigned long lentext = 0;
            unsigned char ch = 0;
            unsigned char inbuf[4], outbuf[3];
            short i = 0, ixinbuf = 0;
            BOOL flignore = NO;
            BOOL flendtext = NO;
            NSData* base64Data = nil;
            const unsigned char* base64Bytes = nil;

            // Convert the string to UTF8 data.
            base64Data = [string dataUsingEncoding: NSUTF8StringEncoding];
            base64Bytes = [base64Data bytes];
            mutableData = [NSMutableData dataWithCapacity: [base64Data length]];
            lentext = [base64Data length];

            while ( YES ) 
            {
                if ( ixtext >= lentext ) 
                    break;

                ch = base64Bytes[ixtext++];
                flignore = NO;

                if ( ( ch >= 'A' ) && ( ch <= 'Z' ) ) 
                    ch = ch - 'A';
                else if ( ( ch >= 'a' ) && ( ch <= 'z' ) ) 
                    ch = ch - 'a' + 26;
                else if ( ( ch >= '0' ) && ( ch <= '9' ) ) 
                    ch = ch - '0' + 52;
                else if ( ch == '+' ) 
                    ch = 62;
                else if ( ch == '=' ) 
                    flendtext = YES;
                else if ( ch == '/' ) 
                    ch = 63;
                else 
                    flignore = YES; 

                if ( !flignore ) 
                {
                    short ctcharsinbuf = 3;
                    BOOL flbreak = NO;

                    if ( flendtext ) 
                    {
                        if ( !ixinbuf ) 
                            break;

                        if ( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) 
                            ctcharsinbuf = 1;
                        else 
                            ctcharsinbuf = 2;

                        ixinbuf = 3;
                        flbreak = YES;
                    }

                    inbuf [ixinbuf++] = ch;

                    if ( ixinbuf == 4 ) 
                    {
                        ixinbuf = 0;
                        outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
                        outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
                        outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );

                        for( i = 0; i < ctcharsinbuf; ++i ) 
                            [mutableData appendBytes: &outbuf[i] length: 1];
                    }

                    if ( flbreak )  
                        break;
                }
            }
        }

        self = [self initWithData: mutableData];
        return self;
    }

    #pragma mark -
    - (NSString* ) base64Encoding 
    {
        return [self base64EncodingWithLineLength: 0];
    }

    - (NSString*)base64EncodingWithLineLength: (unsigned int)lineLength 
    {
        const unsigned char* bytes = [self bytes];
        NSMutableString* result = [NSMutableString stringWithCapacity: [self length]];
        unsigned long ixtext = 0;
        unsigned long lentext = [self length];
        long ctremaining = 0;
        unsigned char inbuf[3], outbuf[4];
        short i = 0;
        short charsonline = 0, ctcopy = 0;
        unsigned long ix = 0;

        while ( YES ) 
        {
            ctremaining = lentext - ixtext;
            if ( ctremaining <= 0 ) 
                break;

            for( i = 0; i < 3; ++i ) 
            {
                ix = ixtext + i;
                if ( ix < lentext ) 
                    inbuf[i] = bytes[ix];
                else 
                    inbuf [i] = 0;
            }

            outbuf [0] = (inbuf [0] & 0xFC) >> 2;
            outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
            outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
            outbuf [3] = inbuf [2] & 0x3F;
            ctcopy = 4;

            switch ( ctremaining ) 
            {
                case 1: 
                    ctcopy = 2; 
                    break;
                case 2: 
                    ctcopy = 3; 
                    break;
            }

            for( i = 0; i < ctcopy; ++i )
                [result appendFormat: @"%c", encodingTable[outbuf[i]]];

            for( i = ctcopy; i < 4; ++i )
                [result appendFormat: @"%c",'='];

            ixtext += 3;
            charsonline += 4;

            if ( lineLength > 0 ) 
            {
                if ( charsonline >= lineLength) 
                {
                    charsonline = 0;
                    [result appendString: @"\n"];
                }
            }
        }

        return result;
    }

    @end


回答3:

1st Suggestion: you can store it in a session in PHP e.g. $_SESSION['mytext'] = <NSDATA>; don't forget to session_start(); to retrieve your string.

2nd Suggestion: you can store it in a XML FILE. That's if it supports XML

3rd Suggestion: just call it back from MYSQL to be safe.