Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Alright, I think I got a bit closer. However, I'm not quite there yet, since I ran into some "EXC_BAD_ACCESS" when converting data back to a new array.</p> <p>Let me share some code with you. The following is supposed to take care of converting the array to NSData, converting NSData to base64 and vice versa.</p> <pre><code>@interface NSArray (dataConversion) + (NSArray*) arrayWithData:(NSData*) data; - (NSData*) convertToData; @end @implementation NSArray (dataConversion) - (NSData*) convertToData { unsigned n= [self count]; NSMutableData* data = [NSMutableData dataWithLength: sizeof(unsigned)+ sizeof(id) *n]; unsigned* p = [data mutableBytes]; *p++= n; [self getObjects:(void*)p]; return data; } + (NSArray*) arrayWithData:(NSData*) data { unsigned* p = (unsigned*)[data bytes]; unsigned n = *p++; return [NSArray arrayWithObjects:(id*)p count:n]; } @end @interface NSData (MBBase64) + (id)dataWithBase64EncodedString:(NSString *)string; // Padding '=' characters are optional. Whitespace is ignored. - (NSString *)base64Encoding; @end static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @implementation NSData (MBBase64) + (id)dataWithBase64EncodedString:(NSString *)string; { if (string == nil) [NSException raise:NSInvalidArgumentException format:nil]; if ([string length] == 0) return [NSData data]; static char *decodingTable = NULL; if (decodingTable == NULL) { decodingTable = malloc(256); if (decodingTable == NULL) return nil; memset(decodingTable, CHAR_MAX, 256); NSUInteger i; for (i = 0; i &lt; 64; i++) decodingTable[(short)encodingTable[i]] = i; } const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding]; if (characters == NULL) // Not an ASCII string! return nil; char *bytes = malloc((([string length] + 3) / 4) * 3); if (bytes == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (YES) { char buffer[4]; short bufferLength; for (bufferLength = 0; bufferLength &lt; 4; i++) { if (characters[i] == '\0') break; if (isspace(characters[i]) || characters[i] == '=') continue; buffer[bufferLength] = decodingTable[(short)characters[i]]; if (buffer[bufferLength++] == CHAR_MAX) // Illegal character! { free(bytes); return nil; } } if (bufferLength == 0) break; if (bufferLength == 1) // At least two characters are needed to produce one byte! { free(bytes); return nil; } // Decode the characters in the buffer to bytes. bytes[length++] = (buffer[0] &lt;&lt; 2) | (buffer[1] &gt;&gt; 4); if (bufferLength &gt; 2) bytes[length++] = (buffer[1] &lt;&lt; 4) | (buffer[2] &gt;&gt; 2); if (bufferLength &gt; 3) bytes[length++] = (buffer[2] &lt;&lt; 6) | buffer[3]; } realloc(bytes, length); return [NSData dataWithBytesNoCopy:bytes length:length]; } - (NSString *)base64Encoding; { if ([self length] == 0) return @""; char *characters = malloc((([self length] + 2) / 3) * 4); if (characters == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (i &lt; [self length]) { char buffer[3] = {0,0,0}; short bufferLength = 0; while (bufferLength &lt; 3 &amp;&amp; i &lt; [self length]) buffer[bufferLength++] = ((char *)[self bytes])[i++]; // Encode the bytes in the buffer to four characters, including padding "=" characters if necessary. characters[length++] = encodingTable[(buffer[0] &amp; 0xFC) &gt;&gt; 2]; characters[length++] = encodingTable[((buffer[0] &amp; 0x03) &lt;&lt; 4) | ((buffer[1] &amp; 0xF0) &gt;&gt; 4)]; if (bufferLength &gt; 1) characters[length++] = encodingTable[((buffer[1] &amp; 0x0F) &lt;&lt; 2) | ((buffer[2] &amp; 0xC0) &gt;&gt; 6)]; else characters[length++] = '='; if (bufferLength &gt; 2) characters[length++] = encodingTable[buffer[2] &amp; 0x3F]; else characters[length++] = '='; } return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease]; } @end </code></pre> <p>Now, I use it like that:</p> <pre><code>NSData *messageData = [[NSArray arrayWithArray:myNSMutableArray] convertToData]; NSString *messageData = [messageData base64Encoding]; </code></pre> <p>messageData is the string I now send to my server. This works fine.</p> <p>Now the other way round:</p> <pre><code>NSData *arrayData = [NSData dataWithBase64EncodedString:serverResponseString]; //serverResponseString is the string returned from my server upon request NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:[NSArray arrayWithData:arrayData]]; //here it crashes and points to: "return [NSArray arrayWithObjects:(id*)p count:n];" </code></pre> <p>I'm either missing something here or completely off track. Any help appreciated. Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload