initWithBase64Encoding deprecated base64 - ios

I am receiving a warning in Xcode after upgrading to Xcode 7 in my project, I'm using CoacoSecurity which uses Base64 for encryption in the following line of code :
if (![NSData instancesRespondToSelector:#selector(initWithBase64EncodedString:options:)])
{
decoded = [[self alloc] initWithBase64Encoding:[string stringByReplacingOccurrencesOfString:#"[^A-Za-z0-9+/=]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [string length])]];
}
Its telling me that initWithBase64Encoding is deprecated, so how can i get over this warning and fix it.
I've converted it but I'm getting another warning:
decoded = [[self alloc] initWithBase64EncodedString:[string stringByReplacingOccurrencesOfString:#"[^A-Za-z0-9+/=]" withString:#""] options:NSRegularExpressionSearch];
The warning says:
Implicit conversion from enumeration type enum NSStringCompareOptions to different enumeration type NSDataBase64DecodingOptions (aka enum NSDataBase64DecodingOptions)

use this
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
instand of
NSData *data=[[NSData alloc]initWithBase64Encoding:(NSString *)dict];

Here's a solution that works with OSX 10.8 and up.
// assume sData is an NSString that's already been set
NSData *vData;
if ([vData respondsToSelector:#selector(base64EncodedStringWithOptions:)]) {
vData = [[NSData alloc] initWithBase64EncodedString:sData options:kNilOptions];
} else { // 10.8 or earlier
vData = [[NSData alloc] initWithBase64Encoding:sData];
}
NSString *sResult = [[NSString alloc]
initWithData:vData encoding:NSUTF8StringEncoding];
I threw in the sResult line only if you wanted to convert it to an NSString instead of an NSData.
So, that gives you a Base64 encoded string. If you want to now unencode it, you would do:
// assuming sData is an NSString that's already been set
NSString *sResult = #"";
NSData *vData = [sData dataUsingEncoding:NSUTF8StringEncoding];
if ([vData respondsToSelector:#selector(base64EncodedStringWithOptions:)]) {
sResult = [vData base64EncodedStringWithOptions:kNilOptions];
} else { // 10.8 or earlier
sResult = [vData base64Encoding];
}

Well, first i used initWithBase64Encoding as #Ske57 recommended and then to get over that warning i had to cast it to NSDataBase64DecodingOptions and it should work fine :
decoded = [[self alloc] initWithBase64EncodedString:[string stringByReplacingOccurrencesOfString:#"[^A-Za-z0-9+/=]" withString:#""] options:(NSDataBase64DecodingOptions)NSRegularExpressionSearch];

Related

want to have this string "مرحبا 😀 Hello" save it to database and display back to uilabel

I am looking for solution where i want to store English + Arabic + Emoji Character to store to Database and retrieve it back while display.
Below is the code what i have used to support Emoji, after that Arabic text is not showing.
+(NSString *)emojiToSave:(NSString *)str
{
NSData *dataForEmoji = [str dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *encodevalue = [[NSString alloc]initWithData:dataForEmoji encoding:NSUTF8StringEncoding];
return encodevalue;
}
+(NSString *)emojiToDisplay:(NSString *)str
{
NSData *msgData = [str dataUsingEncoding:NSUTF8StringEncoding];
NSString *goodMsg = [[NSString alloc] initWithData:msgData encoding:NSNonLossyASCIIStringEncoding];
return goodMsg;
}
Can anyone pls suggest to give support for Arabic what change i should do?
Thanks in advance.
Try convert it into base64 code, then insert base64 code to database:
//Original string to base64 string
NSString *emojiString = #"مرحبا 😀 Hello";
NSData *emojiData = [emojiString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [emojiData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
//Base64 string to original string
NSData *base64Data = [[NSData alloc] initWithBase64EncodedString:base64String options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSString *originalString =[[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];
NSLog(#"Result: %#",originalString);
Output:
You have to use an encoding that supports emoji and arabic characters. ASCII doesn't support that.
You should use NSUTF8StringEncoding everywhere, and you're fine.
Why are you using ASCII anyways? Why are you converting a string to an NSData and then back to NSString again? It doesn't make sense.

iOS objective-C NSData to NSString return nil, how to ignore the invalid UTF-8

data is downloaded from website,
NSString * html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
html is nil, but
NSString * html = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
will have the content.
Since the website contains Chinese characters, if using Ascii, the Chinese cannot be displayed. I guess there are some invalid UTF-8 in the website, so that make the first code not working.
Is there any methods can keep using UTF-8 but ignore some invalid error?
I think I found a solution.
Vincent Guerci's answer
add libiconv to your project and let it clean the invalid UTF-8, after cleaning, the NSData is safe to pass to [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Details implementation is:
Add "libiconv.2.dylib" in "Link Binary With Libraries" to your target.
#include "iconv.h"
Add this function:
Objective C:
- (NSData *)cleanUTF8:(NSData *)data {
// this function is from
// https://stackoverflow.com/questions/3485190/nsstring-initwithdata-returns-null
//
//
iconv_t cd = iconv_open("UTF-8", "UTF-8"); // convert to UTF-8 from UTF-8
int one = 1;
iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one); // discard invalid characters
size_t inbytesleft, outbytesleft;
inbytesleft = outbytesleft = data.length;
char *inbuf = (char *)data.bytes;
char *outbuf = malloc(sizeof(char) * data.length);
char *outptr = outbuf;
if (iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft)
== (size_t)-1) {
NSLog(#"this should not happen, seriously");
return nil;
}
NSData *result = [NSData dataWithBytes:outbuf length:data.length - outbytesleft];
iconv_close(cd);
free(outbuf);
return result;
}

NSString from NSData is nil

I try to get an NSString from NSData but I get a nil value.
This is my code:
NSString *dataString = [[NSString alloc] initWithData:self.message.data encoding:NSUTF8StringEncoding];
When I log self.message.data I get:
Printing description of self->_message->_data:
<OS_dispatch_data: data[0x17e48290] = { leaf, size = 331233, buf = 0x3aac000 }>
That means my data is not nil…
Can anyone help?
As answer to your question in comments:
OS_dispatch_data is dispatch_data_t which has toll-free bridging with NSData on iOS 7 and Mavericks. You can simply cast it to NSData *.
So, in your case you can write:
NSData *dataCast = self.message.data;
NSString *dataString = [[NSString alloc] initWithData:dataCast encoding:NSUTF8StringEncoding];
And now you get the correct string!
In my case it appeared, when AFNetworking cast internal NSMutableData to NSData.
And this simple cast helps me.
UPD: As #Daij-Djan mentioned: If it's not works - try to check your text encoding.
For example if you're yousing NSURLSessionTask:
NSURLSessionTask *task; // Your NSURLSessionTask
NSString *encoding = [[task response] textEncodingName];
In your case (NSUTF8StringEncoding) it should be "utf-8".
Try UTF-16 encoding instead. It may be an error converting to UTF-8 if any data in there is not recognized.

EMoji Unicode for IOS

I call api and get the string which include the android java unicode in NSDictionary :
\ud83d\ude25\ud83d\ude1e\U2764\ud83d\ude2d
When get the the value above and assign to string, I just will get the string as:
\ud83d\ude25\ud83d\ude1e❤\ud83d\ude2d
I totally can not get the value \U2764 but get the value ❤
So I can not replace the code \U2764 to IOS unicode.
How can I get it \U2764? I convert into UTF-8.
Thanks
Edit:
This is get the directory from api (dic):
{
message = "\ud83d\ude25\ud83d\ude1e\U2764\ud83d\ude2d";
mesgid = "213133";
Thumbnail = "";
}
Then i get the message, but the dic2 string is still get \ud83d\ude25\ud83d\ude1e❤\ud83d\ude2d:
const char *cString = [[dic6 objectForKey:#"Message"] UTF8String];
NSString *dic2 = [[NSString alloc] initWithUTF8String:cString];
if ([dic2 rangeOfString:#"\\U"].location==NSNotFound && [dic2 rangeOfString:#"\\u"].location==NSNotFound)
{
NSLog(#"Substring Not Found");
}
else
{
NSLog(#"Substring Found");
}
I totally can not get the unicode.
Why?
try this
NSString *uniString = [NSString stringWithUTF8String:#"\ud83d\ude25\ud83d\ude1e❤\ud83d\ude2d
"];
Hopefully this will resolve your problem
char cString[] = "\ud83d\ude25\ud83d\ude1e\U2764\ud83d\ude2d";
NSData *data = [NSData dataWithBytes:cString length:strlen(cString)];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

IOS stringByReplacingOccurrencesOfString coming back null

I've been banging my head against the wall on this, I must be missing something. This code is called just after I base64 encode some encrypted text. At the point where I call NSLog signature is always valid. However sometimes the rest works great and other times removePlus or finalSig come back null. Also I'm using Xcode 4.5, ios6 and I have ARC enabled for the project. I feel like maybe something is getting auto released before I want it to, or something like that. If anyone has any ideas any help is appreciated.
// Get the data out of the context
char *outputBuffer;
long outputLength = BIO_get_mem_data(context, &outputBuffer);
NSMutableString *signature = [[NSMutableString alloc] init];
[signature appendString:[NSMutableString stringWithCString:outputBuffer encoding:NSASCIIStringEncoding]];
NSLog(#"Base64 Pre Encoded: %#", signature);
signature = [[signature stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding] mutableCopy];
NSMutableString *removePlus = [[signature stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"] mutableCopy];
NSString *finalSig = [removePlus stringByReplacingOccurrencesOfString:#"=" withString:#"%3D"];
//now we create the url request portion
NSMutableString *variables = [[NSMutableString alloc] init];
//set the variables we're going
[variables appendString:finalSig];
Try swapping your code for the following, as I imagine it will show you exactly where your problem is:
// Get the data out of the context
char *outputBuffer;
long outputLength = BIO_get_mem_data(context, &outputBuffer);
outputBuffer[outputLength] = '\0';
if(outputLength != strlen(outputBuffer)) NSLog(#"SOMETHING VERY WRONG");
NSString * signature = [NSString stringWithCString:outputBuffer encoding:NSASCIIStringEncoding]];
NSLog(#"Base64 Pre Encoded: %#", signature);
signature = [[signature stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSLog(#"Base64 Post Encoded: %#", signature);
signature = [signature stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
NSLog(#"Base64 Remove '+': %#", signature);
signature = [removePlus stringByReplacingOccurrencesOfString:#"=" withString:#"%3D"];
NSLog(#"Base64 Remove '=': %#", signature);
//now we create the url request portion
NSMutableString *variables = [NSMutableString alloc] initWithString:signature];
…
//set the variables we're going
[variables appendString:finalSig];
Turns out that NSString * signature = [NSString stringWithCString:outputBuffer encoding:NSASCIIStringEncoding]]; requires a null terminated string and my string was not. Anyway this was a more effective way to create the string:
NSData *myRequestData = [ NSData dataWithBytes: [ variables UTF8String ] length: [ variables length ] ];

Resources