The WCF service clearly asks for base64binary so you have to send it in base64binary only.
base64binary is nothing but base64 encoded binary data.
1) Convert the image to binary using the following code snippet
NSData *binaryImageData = UIImageJPEGRepresentation([UIImage imageNamed:@"Photo.png"], 0.0);
2) Encode the binary into base64 format
Here is the class that I use to handle base64 binary and UIImage
@interface base64BinaryandImagehandler:NSObject
+(NSString *) base64BinaryStringFromBinaryData: (NSData *)data length: (int)length;
+(UIImage*)Base64BinaryToImage:(NSString *)Base64;
@end
@implementation base64BinaryandImagehandler:NSObject
static char base64EncodingTable[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', '+', '/'
};
+(NSString *) base64BinaryStringFromBinaryData: (NSData *)data length: (int)length{
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1)
return @"";
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0)
break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext)
input[i] = raw[ix];
else
input[i] = 0;
}
output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
for (i = ctcopy; i < 4; i++)
[result appendString: @"="];
ixtext += 3;
charsonline += 4;
if ((length > 0) && (charsonline >= length))
charsonline = 0;
}
return result;
}
+(UIImage*)Base64BinaryToImage:(NSString *)Base64{
NSString* base64String=[[NSString alloc]initWithFormat:@"data:image/png;base64,%@",Base64];
NSURL *base64url = [NSURL URLWithString:base64String];
NSData *imageData = [NSData dataWithContentsOfURL:base64url];
UIImage *img=[UIImage imageWithData:imageData];
return img;
}
@end
Here is the way to convert binary into base64binary
NSString *Base64Binary=[base64BinaryandImagehandler base64BinaryStringFromBinaryData:binaryImageData length:binaryImageData.length];
You can find more about here as well
Here is the base64 encoding and decoding part in C#
public static string Base64Encode(string plainText) {
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public static string Base64Decode(string base64EncodedData) {
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
Anyhow you can ignore about the C# part since you are doing iPhone part only.
You can use the below link to test if your encoded base 64 is proper.
base64toimage converter
Update 1
Here is the code that will confirm if the received string is in base64 format or not
private bool IsBase64String(string str){
try{
// If not exception is caught, then it is a base64 string
MemoryStream stream = new MemoryStream(Convert.FromBase64String(str));
return true;
}
catch{
// If exception is caught, then I assumed it is a normal string
return false;
}
}
Reference
The below code will create a image under Images folder for the given arriving base64 data and filename of your choice for example duraiamuthan.jpg and return the path of the image so that you can update it in the DB
(It will check if the arriving the data is in base64 or binary[just in case WCF framework converts the base64 to binary internally])
public string Getpath_CreateImageFromEncodedData(string Base64EncodedData, string fileName)
{
string fileHandle = "";
try
{
if(IsBase64String(Base64EncodedData))
byte[] imageBytes = Convert.FromBase64String(Base64EncodedData);
else
byte[] imageBytes= Base64EncodedData;
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
fileHandle = System.Web.HttpContext.Current.Server.MapPath("Images/" + fileName);
FileStream fsObj = new FileStream(fileHandle, FileMode.Create, FileAccess.Write);
ms.WriteTo(fsObj);
fsObj.Close();
ms.Close();
return fileHandle;
}
catch (Exception ex)
{
return "";
}
}
Update 2 (for timeout issues)
NSURLRequest and NSMutableURLRequest default timeout period is 60
seconds depending upon the Internet connectivity,Internet Traffic
congestiion at webserver,ImageCreating time and all it may not be
enough.so you can set the value higher than that using the following
syntax [urlReqObj setTimeoutInterval:180];
the timeout interval is
in seconds only.
Increase the ConnectionTimeout in IIS default value is 120 seconds sometimes if so many requests queue in the request will fail.Increasing the ConnectionTimeOut will help.(This timeout is also for idle time of a connection).To set it in IIS Advanced Settings
Click on your service in IIS Manager -> Advanced Settings -> Connection Limits
and there you can set the timeout or you could simple override the connection timeout in web.config
.
Turn on Keep-alive in IIS
so that same connection is reused thus increasing the effeceincy of IIS.
Click on your service in IIS Manager -> Advanced Settings -> Connection Limits -> Enable HTTP Keep-Alives
If you plan to store the binary of image in DB.you can increase the DB connectiontimeout
in connectionstring
or you can increase the sqlcommandtimeout
Hope this helps.
Feel free to ask if you have any doubts