How can i decode the HTML Code in iOS? - ios

I am using below code to Decode the HTML code:
-(NSString *)decodeString:(NSString *)str
{
// To Remove the HTML code to Nsstring
NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *options = #{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType}; NSAttributedString *decodedString;
decodedString = [[NSAttributedString alloc] initWithData:stringData options:options documentAttributes:NULL error:NULL];
return decodedString.string;
}
This code takes a long time to decode the string. So is there is any other way to decode the HTML code?
I don’t want to use the async OR GCD, because I am using this code at the time of stoaring the records in the database.
So please suggest some alternative. Thanks in advance.

If you are storing records in the database then you can use background queue with and Loader or HUD.Because as much data you will decode it will take more time.So in my opinion please make it in background

Related

Getting null from NSDictionary when NSJSONSerialization is being used

I am new to developing and stackoverflow please help me. i am trying to do a simple application where the YQL link is used to get local data and display it in table format. For that i am converting the data into dictionary , later i want to send it into table. But when i tried to convert data to Dictionary it says null. Please help me. Check the Screenshot below. Thanks in advance.
NSString *str = #"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20local.search%20where%20zip%3D'94085'%20and%20query%3D'pizza'&diagnostics=true";
Here i took json query into a string (*str)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
// NSString *stringFromData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
// NSLog(#"%#", stringFromData);
When i tried to implement this commented code im getting the result as expected, but i want to put all the data into dictionary and display it, so i tried to convert the data into dictionary
NSDictionary *dataFromWeb = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSDictionary *queryDict = [dataFromWeb objectForKey:#"query"];
NSDictionary *results = [dataFromWeb objectForKey:#"results"];
NSString *allResults = [queryDict objectForKey:#"Results"];
NSLog(#"%#", dataFromWeb);
}
The response returning from Yahoo API is XML by default. You should append format=json to the querystring in order to get the response in JSON format so you can parse it using NSJSONSerialization class:
https://query.yahooapis.com/v1/public/yql?format=json&q=select...
Your Api Return xml data so you need to do xml parsing
NSJSONSerialization is used for json parsing
NSString *str = #"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20local.search%20where%20zip%3D'94085'%20and%20query%3D'pizza'&diagnostics=true";
NSURL *UrlFromStr = [NSURL URLWithString:str];
hit this UrlFromStr on your browser you see it return xml data not json
use NSXMLParser to parse xml data
Please Use NSXMLParser To Parse xml data instead of NSJSONSerialization.
NSJSONSerialization is used to parse JSON data.
Declare in .h file
#property (nonatomic, strong) NSXMLParser *xmlParser;
in .m file.
NSString *str = #"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20local.search%20where%20zip%3D'94085'%20and%20query%3D'pizza'&diagnostics=true";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
self.xmlParser = [[NSXMLParser alloc] initWithData:data];
self.xmlParser.delegate = self;
// Initialize the mutable string that we'll use during parsing.
self.foundValue = [[NSMutableString alloc] init];
// Start parsing.
[self.xmlParser parse];
The format of objects you wanna parse is XML,but you use the class of ParseJSON to parse it ,so it return NULL.You can use the class of NSXML to parse it and then set its delegate to execute the related methods...Good luck to you ..
your Api is not a json its XML format use the XML Parser, visit below link,
http://www.theappguruz.com/blog/xmlparsing-with-nsxmlparser-tutorial
hope its helpful.

JSON data in custom URL schemes

In my app, I am making a share function that sends another user an email with a URL to open my app and pass parameters. I googled around for a bit and came up with this.
I know its a terrible example, but that is all I could find. Since I need to pass a NSNumber, a NSDate, and an NSString, I figured this would be the most convenient way to do so. Right now, I cannot make sense of that code. I went ahead and got the SBJson library, which is what he appears to be using. Can someone help me out on this?
You don't have to use a library for JSON Serialization in iOS. From iOS 5.0 onwards there is a class NSJSONSerialization is available for doing this. https://developer.apple.com/library/ios/documentation/foundation/reference/nsjsonserialization_class/Reference/Reference.html
Consider this code for converting list of contacts to json string
+(NSString*) jsonStringRepresentationOfSelectedReceiptients:(NSArray*) contactsList {
NSMutableArray* contactsArray = [[NSMutableArray alloc]init];
for (ContactObject *contactObj in contactsList) {
NSDictionary* ltPair = #{#"phone_no": [NSNumber numberWithLongLong:contactObj.phoneNo, #"email_id": contactObj.emailId, #"display_name": contactObj.displayName], #"creation_date": [NSDate dateWithTimeIntervalSince1970:contactObj.timeStamp]]};
[contactsArray addObject:ltPair];
}
NSData *jsonData=[NSJSONSerialization dataWithJSONObject:contactsArray options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"json string: %#", recptJson);
return jsonString;
}
If you have proper NSDate instead of time stamp, u can directly use it.
Hope this helps.

iOS NSAttributedString to HTML

I have an NSAttributed string (coming from HTML) that I set for a UITextView.
- (void)setHtml:(NSString *)html {
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];
// Create the HTML string
NSDictionary *importParams = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSError *error = nil;
self.htmlString = [[NSAttributedString alloc] initWithData:htmlData options:importParams documentAttributes:NULL error:&error];
self.editorView.attributedText = self.htmlString;
}
I then let the user edit what they want, and I would like to then convert it out to HTML again, so I use:
- (NSString *)getHTML {
NSDictionary *exportParams = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [self.editorView.attributedText dataFromRange:NSMakeRange(0, self.editorView.attributedText.length) documentAttributes:exportParams error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}
It does return HTML, but it isn't how I want it. Everything is given a class attribute, and the CSS it put at the top of the document. Things like images and links are not even included in the returned HTML and probably tons more issues.
Is there a better way to get HTML from an NSAttributedString? Or, is there a way I could parse the NSAttributedString and write my own HTML?
May be you could look at that repository:
https://github.com/IdeasOnCanvas/Ashton
there is 2 interesting class:
AshtonHTMLReader.h
- (NSAttributedString *)attributedStringFromHTMLString:(NSString *)htmlString;
And the writer:
AshtonHTMLWriter.h
- (NSString *)HTMLStringFromAttributedString:(NSAttributedString *)input;
The html generated isn't very nice but if you try to display it in a uiwebview,
it looks pretty good.
Simple idea for image:
encode it with base64 and put it directly in a < img > tag with the right frame.
It's ugly but it works => I've used this process to create and edit some html file few month ago
This is a complex issue, and I will start with a shorter answer. You may ask me questions in the comments, and I will expand on the answer as needed.
We also tried to go the attributed string route, but found it not suited for full HTML editing. Many elements are just not supported, either because the converter is not fully developed, or these elements were deemed outside of scope by Apple. Parsing the attributed string is not good enough, because the attributed string has already lost most of the richness of the HTML by the time you attempt to recreate it.
Instead, we use a webview, load the document normally, and enable contentEditable on the body element. What this does is allow editing of the document in its fullest, limited only by WebKit. At the end, to retrieve the HTML back, we disable contentEditable and take the document.outerHTML to get an entire HTML as it was before, with changes made by the user.
Don't take the decision to implement this method lightly. It is a somewhat complex solution, but certainly possible. A webview is not as nice as a textview, but it can be, given enough massage.
I will expand on this answer as needed.
I also had to convert a NSAtttributedString to HTML in one of my projects. The code for doing this is as follows
//self.attributed String is the attributedString
NSDictionary *documentAttributes = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [self.attributedString dataFromRange:NSMakeRange(0, self.attributedString.length) documentAttributes:documentAttributes error:NULL];
NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
NSLog(#"%#", htmlString);

RNCryptor not working with JSON string

Here are my method's to use RNCryptor to encrypt/decrypt a JSON string that I am sending to the web service. I am using a static IV variable which may be bad practice but please don't focus on that. Here is how I'm doing it:
Note: I'm using Matt Gallagher's NSData+Base64 category found here (at bottom of page)
-(NSString*)encryptString:(NSString*)plaintext withKey:(NSString*)key error:(NSError**)error{
NSData *data = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptionKey = [NSData dataFromBase64String:key];
NSData *IV = [NSData dataFromBase64String:ENCRYPTION_IV];
RNCryptorEngine *engine = [[RNCryptorEngine alloc] initWithOperation:kCCEncrypt settings:kRNCryptorAES256Settings key:encryptionKey IV:IV error:error];
[engine addData:data error:error];
NSData *encryptedData = [engine finishWithError:error];
NSString *based64Encrypted = [encryptedData base64EncodedString];
NSLog(#"Encrytped: %#", based64Encrypted);
return based64Encrypted;
}
-(NSString*) decryptString:(NSString*)cipherText withKey:(NSString*)key error:(NSError**)error;{
NSData *data = [NSData dataFromBase64String:cipherText];
NSData *encryptionKey = [NSData dataFromBase64String:key];
NSData *IV = [NSData dataFromBase64String:ENCRYPTION_IV];
RNCryptorEngine *engine = [[RNCryptorEngine alloc] initWithOperation:kCCDecrypt settings:kRNCryptorAES256Settings key:encryptionKey IV:IV error:error];
[engine addData:data error:error];
NSData *decryptedData = [engine finishWithError:error];
NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
NSLog(#"Decrypted: %#", decryptedString);
return decryptedString;
}
When I use a string like hello world it works fine. When I use a string like {"username":"developer","password":"abcdefG*12"} I imagine it hase something to do with the encoding but I really know what to use.
when I encrypt that string I get a base64 string and when I try to decrypt that I get an empty string.
UPDATE
It looks like it's failing because of the : in the json string.
What's weirder is it only fails with the string is in json format, I thought it was the : cause I tried that first but upon further investigation if I broke any of the JSON requirements ,'s {'s }'s it stopped working. It works with the RNEncryptor however so I'm not sure what I'm doing wrong. Either way, I think we may redesign the current flow
UPDATE 2
Here is where I am calling these methods:
NSDictionary *credentials = #{#"username":#"developer",#"password":#"abcdefG*12"};
NSString *jsonString = [ credentials JSONStringWithOptions:JKSerializeOptionNone error:&error];
NSLog(#"json string: %#", jsonString); //OUTPUTS: {"username":"developer","password":"abcdefG*12"}
CCGEncryption *encryptionObject = [[CCGEncryption alloc] init]; //THIS IS THE OBJECT WHERE THE encrypt/decrypt methods are
NSString *encrypted = [encryptionObject encryptString:jsonString withKey:ENCRYPTION_KEY error:&error];
if(error){
NSLog(#"Error:%#", error); //NO ERROR
}
NSString *decrypted = [encryptionObject decryptString:encrypted withKey:ENCRYPTION_KEY error:&error];
if(error){
NSLog(#"Error:%#", error); //NO ERROR
}
NSLog(#"decrypted: %#", decrypted); //OUTPUT: decrypted:
You're not collecting the data returned by addData:. The engine encrypts/decrypts as you go so that you don't have to hold the entire plaintext and ciphertext in memory. It doesn't accumulate the data unless it has to (for padding reasons). I suspect that the tests that are working are of different lengths than the ones that aren't.
You are correct that using a fixed IV is bad practice. If you use the same IV and key in multiple messages, then it is possible for attackers to recover parts of your messages by comparing the ciphertexts. If you are using AES-CBC without a random IV and an HMAC, then your AES is insecure in several ways. That is the problem RNCryptor was built to address and why the data format looks the way it does.
#jbtule is correct that I didn't particularly mean for people to use the engine directly and haven't heavily documented it, but there's no problem using it, and I can document it better to support that. That said, the engine itself is insanely simple; I just created it as a way to share code between the encryptor and decryptor. There's not much reason to use RNCryptor if you're going to bypass most of the security it provides. For the above code, it'd be a lot simpler to just call the one-shot CCCrypt().

NSJSONSerialization from NSString

Is it possible if I have a NSString and I want to use NSJSONSerialization? How do I do this?
First you will need to convert your NSString to NSData by doing the following
NSData *data = [stringData dataUsingEncoding:NSUTF8StringEncoding];
then simply use the JSONObjectWithData method to convert it to JSON
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
You need to convert your NSString to NSData, at that point you can use the +[NSJSONSerialization JSONObjectWithData:options:error:] method.
NSString * jsonString = YOUR_STRING;
NSData * data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError * error = nil;
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (!json) {
// handle error
}
You can convert your string to NSData by saying:
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
You can then use it with NSJSONSerialization. Note however that NSJSONSerialization is iOS5 only, so you might be better off using a library like TouchJSON or JSONKit, both of which let you work directly with strings anyway, saving you the step of converting to NSData.
I wrote a blog post that demonstrates how to wrap the native iOS JSON class in a general protocol together with an implementation that use the native iOS JSON class.
This approach makes it a lot easier to use the native functionality and reduces the amount of code you have to write. Furthermore, it makes it a lot easier to switch out the native implementation with, say, JSONKit, if the native one would prove to be insufficient.
http://danielsaidi.com/blog/2012/07/04/json-in-ios
The blog post contains all the code you need. Just copy / paste :)
Hope it helps!

Resources