Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COOk, I digged down a little deeper and created a new project just to test serializing and de-serializing my array. I filled the array with objects similar to those I have in my original project. Guess what? It worked. So what does that tell me? Maybe there is a problem with the string, that gets returned from my server? Not sure yet. I'll investigate and report back.
      singulars
    2. COAlright, that was fast. I think I found the problem. Let me explain: When I serialize my array, I get a string similar to this one (without quotes): "GwAAAPAWEgCQEhwAwBAcANAPHADwFhIAAFcZABBcGQCgUxsAQBAcALAhHADANRwA4CscADDcEACwERwAYDkcAPAUEgAQmBIAQFUbAOBaGwDQXRsAcB0cADBYGwAgUBsAkFUbAPBRGwDw/xsAMFkcAA==" Now, if I tell my app to deserialize this string right after serializing it, it works. However, when I want to deserialize the very same string like NSString *str = @"stringFromAboveHere"; it crashes. Know what I mean?
      singulars
    3. CONow this is weird. After some more testing I found something interesting. As already mentioned above, I created a new test app. I filled this app with objects. Those objects are the same every time and they are located at the same position every time. However, when I restart the app and serialize the array, the serialized string is completely different each time! Why is that? I'm sure, solving this is the key to getting rid of my problem.
      singulars
 

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