how to convert array of bytes to base64 String in iphone? - iphone

I have a piece of code in vb. I need to convert array of bytes to base 64 string. Following is the vb code.
If arrLicence.Count > 0 Then
LicenceBytes = CType(Array.CreateInstance(GetType(Byte),6), Byte())
LicenceBytes(0) = Convert.ToByte(arrLicence(0).ToString(), 16)
LicenceBytes(1) = Convert.ToByte(arrLicence(1).ToString(), 16)
LicenceBytes(2) = Convert.ToByte(arrLicence(2).ToString(), 16)
LicenceBytes(3) = Convert.ToByte(arrLicence(3).ToString(), 16)
LicenceBytes(4) = Convert.ToByte(arrLicence(4).ToString(), 16)
LicenceBytes(5) = Convert.ToByte(arrLicence(5).ToString(), 16)
LicenceString = Convert.ToBase64String(LicenceBytes) '6 byteArray - passed by the user - Base64Encoded
I need its equivalent in iphone. I tried with NSData and base64 conversion but result defers.
I have used this link for conversion.
http://www.cocoadev.com/index.pl?BaseSixtyFour
I tried by creating individual bytes using memcpy and then creating an array but with no success.
What I have tried is as follows:
NSData *d1 =[#"64" dataUsingEncoding:NSUTF16StringEncoding];
NSData *d2 = [#"37" dataUsingEncoding:NSUTF16StringEncoding];
NSData *d3 = [#"81" dataUsingEncoding:NSUTF16StringEncoding];
NSData *d4 = [#"d4" dataUsingEncoding:NSUTF16StringEncoding];
unsigned char *buffer = (unsigned char*)malloc(8);
buffer[0] = [d1 bytes] ;
buffer[1] = [d2 bytes] ;
buffer[2] = [d3 bytes] ;
buffer[3] = [d4 bytes] ;
NSData *data = [NSData dataWithBytes:buffer length:4];
NSString *str = [self encodeBase64WithData:data];
free(buffer);
This results in IJCgkA== while code in .NET returns ZDeB1A==
Please note that the conversion is for first four bytes of arrLicence and the input is 64, 37, 81, d4

Try this one, i hope this will surely help you.
get-base64-nsstring-from-nsdata

unsigned char *buffer = (unsigned char*)malloc(8);
buffer[0] = [d1 bytes] ;
buffer[1] = [d2 bytes] ;
buffer[2] = [d3 bytes] ;
buffer[3] = [d4 bytes] ;
Not sure what you expect this to do. bytes return an array, and you are assigning the addresses of the arrays to char elements of your buffer. This buffer won't be filled with any of the data you expect, and the "data" from d2 will partially overwrite those from d1 etc.
Also, you shouldn't make much assumptions about the lengths of your byte arrays, especially not if using UTF-16.
In a word: You don't throw the data you expect at your conversion routine. Maybe check that in the debugger.

See code sample, Very self-explained ...
http://www.cocoadev.com/index.pl?BaseSixtyFour
Also check below SO post .
How do I do base64 encoding on iphone-sdk?

//strBusiCode = #"64-37-81-d4-39-6d";
NSArray *tmp_arr = [strBusiCode componentsSeparatedByString:#"-"];
NSMutableData *commandToSend= [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [tmp_arr count]; i++) {
byte_chars[0] = [[tmp_arr objectAtIndex:i] characterAtIndex:0];
byte_chars[1] = [[tmp_arr objectAtIndex:i] characterAtIndex:1];
whole_byte = strtol(byte_chars, NULL, 16);
[commandToSend appendBytes:&whole_byte length:1];
}
return commandToSend;
This commandToSend is then converted to base64 data.

If you look at the 2 last numbers you give as example, you will notice conversion match. Because the hi and low parts are the same.
Just swap the hi and low words.

You can use this base64.h and base64.m class to decode to base64 string.
base64.h
#import <Foundation/Foundation.h>
#interface NSData (Base64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (id)initWithBase64EncodedString:(NSString *)string;
- (NSString *) base64Encoding;
- (NSString *) base64EncodingWithLineLength:(unsigned int) lineLength;
#end
base64.m
#import "base64.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 (VQBase64)
- (id)initWithString:(NSString *)string {
if (self = [super init]) {
[self initWithBase64EncodedString:string];
}
return self;
}
+ (NSData *) dataWithBase64EncodedString:(NSString *) string {
return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] 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 ASCII data.
base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
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;
}
- (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];
unsigned short i = 0;
unsigned 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 appendString:#"="];
ixtext += 3;
charsonline += 4;
if( lineLength > 0 ) {
if( charsonline >= lineLength ) {
charsonline = 0;
[result appendString:#"\n"];
}
}
}
return [NSString stringWithString:result];
}
#end
Please check and let me know if any issue.

Related

No visible #interface for 'NSData' declares the selector

I am using Triple DES Encryption using this code. I am getting errors that say
No visible #interface for 'NSData' declares the selector 'initWithBase64EncodedString:'
No visible #interface for 'NSData' declares the selector 'base64Encoding:'
I have imported "CommonCrypto/CommonCryptor.h"
There is no initWithBase64EncodedString: and base64Encoding: in the default NSData class.
If you need to add these function to NSData class then you need to extend the NSData class like:
#interface NSData (NSDataAdditions)
- (id) initWithBase64EncodedString:(NSString *)string;
- (NSString *) base64Encoding;
#end
Then you need to implement these methods.
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 (NSDataAdditions)
+ (NSData *) dataWithBase64EncodedString:(NSString *) string {
return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] 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]; // buffer sizes fixed by AOL LLC
short i = 0, ixinbuf = 0;
BOOL flignore = NO;
BOOL flendtext = NO;
NSData *base64Data = nil;
const unsigned char *base64Bytes = nil;
// Convert the string to ASCII data.
base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
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;
}
- (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 appendString:#"="];
ixtext += 3;
charsonline += 4;
if( lineLength > 0 ) {
if (charsonline >= lineLength) {
charsonline = 0;
[result appendString:#"\n"];
}
}
}
return [NSString stringWithString:result];
}
#end
You will get these methods implemented in the following links:
NSDataAdditions.h
NSDataAdditions.m
You need to add files to your project that add those selectors to NSData. You can find some code for that in this answer.
The methods you're trying to use are not Apple's code, but a category on NSData which you can find online. See this SO post about converting NSData to base64, there's a link to the category. As mentioned in that post, the category comes from a post on Cocoa with Love. You can find the download link on that SO post or at the bottom of the page in that Cocoa with Love post.

iPhone - finalizing Apple's vague "VerificationController.m"

I am trying to implement the new VerificationController.m class that Apple released to fix the in-app purchase fraud problem.
As everything released by Apple, this is one more vague, incomplete and bad explained document with a lot of voids and unknowns that cannot be circumvented/understood by everyone.
I am trying to implement that, but at the end of the code we see these four methods:
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
#warning Replace this method.
return nil;
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
#warning Replace this method.
return nil;
}
#warning Implement this function.
char* base64_encode(const void* buf, size_t size)
{ return NULL; }
#warning Implement this function.
void * base64_decode(const char* s, size_t * data_len)
{ return NULL; }
You can see that Apple was lazy to implement the C functions at the end of the code. As my C/C++ abilities stink, I see I need to implement these two functions in C/C++ and that they must return char and void (???). Other people have posted routines to do that on SO, but they are either in Objective-C or not returning chars and void (??).
NOTE: this is another problem I have: how can a method return void if it is used by Apple in this form?
uint8_t *purchase_info_bytes = base64_decode([purchase_info_string cStringUsingEncoding:NSASCIIStringEncoding], &purchase_info_length);
shouldn't it be returning uint8_t?
NOTE2: another problem I have is that apple says base64_encode is required but it is not being used on the code provided by them. I think they are smoking bad stuff or my C/C++ knowledge really stink.
So, returning to my first question. Can someone post/point a method that can do the job that follows the requirements of the declared methods base64_encode and base64_decode? Please refrain from posting objective-c methods that are not compatible with these requirements imposed by Apple.
Thanks.
This solution should be pretty straight forward, which includes all the methods to populate the missing information. Tested and functional within the sandbox.
// single base64 character conversion
static int POS(char c)
{
if (c>='A' && c<='Z') return c - 'A';
if (c>='a' && c<='z') return c - 'a' + 26;
if (c>='0' && c<='9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
if (c == '=') return -1;
[NSException raise:#"invalid BASE64 encoding" format:#"Invalid BASE64 encoding"];
return 0;
}
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)];
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
size_t retLen;
uint8_t *retStr = base64_decode([input UTF8String], &retLen);
if (length)
*length = (NSInteger)retLen;
NSString *st = [[[NSString alloc] initWithBytes:retStr
length:retLen
encoding:NSUTF8StringEncoding] autorelease];
free(retStr); // If base64_decode returns dynamically allocated memory
return st;
}
char* base64_encode(const void* buf, size_t size)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* str = (char*) malloc((size+3)*4/3 + 1);
char* p = str;
unsigned char* q = (unsigned char*) buf;
size_t i = 0;
while(i < size) {
int c = q[i++];
c *= 256;
if (i < size) c += q[i];
i++;
c *= 256;
if (i < size) c += q[i];
i++;
*p++ = base64[(c & 0x00fc0000) >> 18];
*p++ = base64[(c & 0x0003f000) >> 12];
if (i > size + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000fc0) >> 6];
if (i > size)
*p++ = '=';
else
*p++ = base64[c & 0x0000003f];
}
*p = 0;
return str;
}
void* base64_decode(const char* s, size_t* data_len_ptr)
{
size_t len = strlen(s);
if (len % 4)
[NSException raise:#"Invalid input in base64_decode" format:#"%d is an invalid length for an input string for BASE64 decoding", len];
unsigned char* data = (unsigned char*) malloc(len/4*3);
int n[4];
unsigned char* q = (unsigned char*) data;
for(const char*p=s; *p; )
{
n[0] = POS(*p++);
n[1] = POS(*p++);
n[2] = POS(*p++);
n[3] = POS(*p++);
if (n[0]==-1 || n[1]==-1)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid BASE64 encoding"];
if (n[2]==-1 && n[3]!=-1)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid BASE64 encoding"];
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] != -1) q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
if (n[3] != -1) q[2] = ((n[2] & 3) << 6) + n[3];
q += 3;
}
// make sure that data_len_ptr is not null
if (!data_len_ptr)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid destination for output string length"];
*data_len_ptr = q-data - (n[2]==-1) - (n[3]==-1);
return data;
}
Here is a base 64 encode function for NSString to NSString:
+(NSString *) encodeString:(NSString *)inString
{
NSData *data = [inString dataUsingEncoding:NSUTF8StringEncoding];
//Point to start of the data and set buffer sizes
int inLength = [data length];
int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
const char *inputBuffer = [data bytes];
char *outputBuffer = malloc(outLength);
outputBuffer[outLength] = 0;
//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//start the count
int cycle = 0;
int inpos = 0;
int outpos = 0;
char temp;
outputBuffer[outLength-1] = '=';
outputBuffer[outLength-2] = '=';
while (inpos < inLength){
switch (cycle) {
case 0:
outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
cycle = 1;
break;
case 1:
temp = (inputBuffer[inpos++]&0x03)<<4;
outputBuffer[outpos] = Encode[temp];
cycle = 2;
break;
case 2:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
temp = (inputBuffer[inpos++]&0x0F)<<2;
outputBuffer[outpos] = Encode[temp];
cycle = 3;
break;
case 3:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
cycle = 4;
break;
case 4:
outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
cycle = 0;
break;
default:
cycle = 0;
break;
}
}
NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
free(outputBuffer);
return pictemp;
}
and Here is a base 64 decode function for NSString to NSString:
+(NSString *) decodeString:(NSString *)inString
{
const char* string = [inString cStringUsingEncoding:NSASCIIStringEncoding];
NSInteger inputLength = inString.length;
static char decodingTable[128];
static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (NSInteger i = 0; i < 128; i++) {
decodingTable[encodingTable[i]] = i;
}
if ((string == NULL) || (inputLength % 4 != 0)) {
return nil;
}
while (inputLength > 0 && string[inputLength - 1] == '=') {
inputLength--;
}
NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:outputLength];
uint8_t* output = data.mutableBytes;
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < inputLength) {
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';
output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
}
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
}
}
NSLog(#"%#",data);
NSString *finalString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return finalString;
}
These were pieced together from examples I found in various places on the internet when I was searching for them a while ago. They, may be easier for you to implement. I just created a Base64 class and placed these methods in it.
Here are the C wrappers around Justin's answer:
char* base64_encode(const void* buf, size_t size)
{
NSData* data = [NSData dataWithBytesNoCopy:(void*)buf length:size];
NSString* string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return [[_Class_ encode:string] UTF8String];
}
void* base64_Decode (const char* s, size_t* data_len)
{
NSString* result = [_Class_ decode:[NSString stringWithCString:s encoding:NSASCIIStringEncoding]];
*data_len = result.length;
return [result UTF8String];
}
Where Class is the class that contains Justin's functions.

How to print raw data of ASIHTTPRequest

I want to send an image to a web server running .Net which is not Restful .
I have tried a lot of things to convert the image into string and then sending it.Like using initWithData:encoding: and also tried it with converting the image data into base64encodedstring by the method given in this question
iPhone to MS SQL Image Data Type Conversion Question
But no luck.
Then I thought of looking on facebook api for uploading images on facebook wall.Using this tutorial the image can be uploaded to facebook
http://www.raywenderlich.com/1626/how-to-post-to-a-users-wall-upload-photos-and-add-a-like-button-from-your-iphone-app
But the problem is, it is using asihttprequest to send the data on the facebook wall and I cannot see the raw data in the request will uploading the image . Can anyone help me out.
I tried it at my end. First I converted to base64encoding like this:
NSString *str64;
if(Image){
NSData *imageData = UIImageJPEGRepresentation(Image,0.75);
str64 = [imageData base64Encoding];
}
Then I added into a dictionary and then added that dictionary into an array so that I can pass it as a JSON string in request's body.
NSMutableArray *ParaArray =[[NSMutableArray alloc]init];
NSDictionary *ParaDictionary=[NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:#"%#",Userid], #"userid",
[NSString stringWithFormat:#"%#",[Imagename URLEncodedString]], #"imagename",
[NSString stringWithFormat:#"%#",DateNTime], #"datetime",
[NSString stringWithFormat:#"%#",ImageLocation], #"imagelocation",
str64,#"image",
nil]; // set the parameter
[ParaArray addObject:ParaDictionary];
There after using ASIFormDataRequest I sent the image to server using this snippet:
ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setPostValue:[ParaArray JSONRepresentation] forKey:#"bulk_data"];
//[ParaDictionary release];
[ParaArray release];
[request setTimeOutSeconds:20];
[request startSynchronous];
It worked fine for me. I hope it helps you as well.
Data is passed in form of a string and we can directly use the base64Encoding methods by copy pasting them. Though you might know them still here they are:
- (NSString *) base64Encoding {
return [self base64EncodingWithLineLength:0];
}
- (NSString *) base64EncodingWithLineLength:(NSUInteger) 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];
unsigned short i = 0;
unsigned 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 appendString:#"="];
ixtext += 3;
charsonline += 4;
if( lineLength > 0 ) {
if( charsonline >= lineLength ) {
charsonline = 0;
[result appendString:#"\n"];
}
}
}
return [NSString stringWithString:result];
}

Problem UIImage initWithData

I have a NSData with a image decode of Base 64.
I want to convert this data in UIImage but ....
NSData * data = [[NSData alloc] initWithContentsOfFile:#"/Users/.../Library/Caches/images/david.txt"];
UIImage * i = [[UIImage alloc] initWithData:data];
NSLog(#"%#",i);
NSData *datai = UIImagePNGRepresentation(i);
UIImage * i2 = [[UIImage alloc] initWithData:datai];
imagen = [[UIImageView alloc] initWithImage:i2];
[imagen setFrame:CGRectMake(0, 0, 320, 480)];
imagen --> variable
I know that the content in data is correct but in my console :
[Session started at 2011-08-24 20:44:25 +0200.]
2011-08-24 20:44:30.579 P[50194:207] (null)
I have decoded with this Objective C code:
- (NSData *)base64DataFromString: (NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[3], outbuf[4];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil)
{
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true)
{
if (ixtext >= lentext)
{
break;
}
ch = tempcstring [ixtext++];
flignore = false;
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 = true;
}
else if (ch == '/')
{
ch = 63;
}
else
{
flignore = true;
}
if (!flignore)
{
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext)
{
if (ixinbuf == 0)
{
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2))
{
ctcharsinbuf = 1;
}
else
{
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
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++)
{
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak)
{
break;
}
}
}
return theData;
}
and i encoded with this Java code:
File f = new File(url);
BufferedInputStream bi = new BufferedInputStream(new FileInputStream(f));
int bytes = (int) f.length();
byte[] buffer = new byte[bytes];
int readBytes = bi.read(buffer);
bi.close();
/*BASE 64 ENCODE*/
byte[] encodedString = Base64.encode(buffer);
String image = new String(encodedString, "UTF8");
NSData doesn't magically decode base64, you'll have to do that yourself. There's an example how to do this in this blog post.

Display local UIImage on UIWebview

My setup:
I have a webview in my iPhone app, going to www.mysite.com.
Trials
If I set "backgroundcolor uicolor clearcolor" to my webview and draw an uiimage behind my webview, it won't scroll with my webview!
My problem:
I would like the image to with the webview. Also, this image should be stored in the iPhone app and not on the webserver (Of course, if I put the image on the webserver I can simply draw it as background with CSS).
What is the best way to access this image via html/javascript/Objective C, so I can see this local image as background of my website? Is there a way at all?
You have a couple of options. You can load the page with a baseURL of
[[NSBundle mainBundle] bundleURL]
or you can use javascript to set the path to your image using the following method.
[[NSBundle mainBundle] URLForResource:#"myimage" withExtension:#"png"]
Edit: Check here Link to resources inside WebView - iPhone. It looks like you will use pathForResource rather than URLForResource.
Edit 2: You may want to use Data URI's to add your own local files to the web site.
YourCode.m
#import "NSString+DataURI.h"
#import "NSData+Base64.h"
...
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *imgPath = [[NSBundle mainBundle] pathForResource:#"image" ofType:#"png"];
NSData *imgData = [NSData dataWithContentsOfFile:imgPath];
NSString *imgB64 = [[imgData base64Encoding] pngDataURIWithContent];
NSString *javascript = [NSString stringWithFormat:#"document.body.style.backgroundImage='url(%#)';", imgB64];
[webView stringByEvaluatingJavaScriptFromString:javascript];
}
The following code I DID NOT WRITE and I am not sure of the origin
NSData+Base64.h
#interface NSData (Base64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (id)initWithBase64EncodedString:(NSString *)string;
- (NSString *)base64Encoding;
- (NSString *)base64EncodingWithLineLength:(unsigned int) lineLength;
#end
NSData.Base64.m
#import "NSData+Base64.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 (VQBase64)
- (id)initWithString:(NSString *)string {
if ((self = [super init])) {
[self initWithBase64EncodedString:string];
}
return self;
}
+ (NSData *) dataWithBase64EncodedString:(NSString *) string {
return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] 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 ASCII data.
base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
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];
unsigned short i = 0;
unsigned 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 appendString:#"="];
ixtext += 3;
charsonline += 4;
if( lineLength > 0 ) {
if( charsonline >= lineLength ) {
charsonline = 0;
[result appendString:#"\n"];
}
}
}
return [NSString stringWithString:result];
}
#end
NSString+DataURI.h
#import <Foundation/Foundation.h>
#interface NSString(DataURI)
- (NSString *) pngDataURIWithContent;
- (NSString *) jpgDataURIWithContent;
#end
NSString+DataURI.m
#import "NSString+DataURI.h"
#implementation NSString(DataURI)
- (NSString *) pngDataURIWithContent;
{
NSString * result = [NSString stringWithFormat: #"data:image/png;base64,%#", self];
return result;
}
- (NSString *) jpgDataURIWithContent;
{
NSString * result = [NSString stringWithFormat: #"data:image/jpg;base64,%#", self];
return result;
}
#end
You could simply add this line
webView.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"light.jpg"]];