Parsing html page Objective C - html

I try to parse some website using XPath in Objective C (iOS). Everything is OK when I try to parse URL like "url.com/news", but when I parse something like this "ulr.com/news.html" I get node is nil. I think I have to save the content of news.html into local html file and then parse it maybe?
Here's the code that isn't working, thanks a lot.
NSURL *newsURL = [NSURL URLWithString:#"http://www.ukr.net/news/politika.html"];
NSData *newsHtmlData = [NSData dataWithContentsOfURL:newsURL];
TFHpple *newsParser = [TFHpple hppleWithHTMLData:newsHtmlData];
NSString *newsXpathQueryString = #"//article/section[#class='im'][1]/time";
NSArray *newsNodes = [newsParser searchWithXPathQuery:newsXpathQueryString];

Related

How to play an audio file from JSON output?

I have an iOS app that outputs JSON information(from a mySQL database) in the form of a UITableView. This includes audio, images and text. While I can call the images and text, I am having trouble calling the audio (This is stored as a URL in the mySQL database) for example, this is the JSON output for the path to my audio file:
[{"audiopath = "http://my-website.com/audio/5552643-audio.caf"}]
This is the code I use to call the images and text but the audio isn't working. I have tried logging the path but it just comes up as NULL.
NSDictionary *words = [self.wordsArray objectAtIndex:index];
label.text = [words objectForKey:#"new"];
NSDictionary *images = [self.thumbArray objectAtIndex:index];
[imgView setImageWithURL:[NSURL URLWithString:[images objectForKey:#"thumbnail"]]];
NSDictionary *audio = [self.audioArray objectAtIndex:index];
NSURL *path = [NSURL URLWithString:[audio objectForKey:#"audiopath"]];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:path error:nil];
NSLog(#"PATH:%#", path);
The error I am getting is:
'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
The audio is stored on my server so it is not included in the app bundle.. does that mean I need to download the file into my app? or is there another way? Anyone know what I am doing wrong? Any help appreciated.
I have figured it out. This is how I can target the image path:
NSURL *url = [NSURL URLWithString:[_wordDetail objectForKey:#"audiopath"]];
NSData *soundData = [NSData dataWithContentsOfURL:url];
audioPlayer = [[AVAudioPlayer alloc] initWithData:soundData error:NULL];
audioPlayer.delegate = self;
[audioPlayer play];

Parse <img src> tag in JSON - iOS

I have an iOS app which downloads a JSON feed. I have managed to parse everything just fine apart from one element left, which is the images.
The JSON feed I am downloading is from a PHP script online which converts certain RSS feeds to JSON. Thus why there are HTML image tags in one of the elements of the JSON feed which contains the images.
I am using the following code to access things like titles, dates, link URLS, etc... and it works great:
NSArray *titles = [[[[data_dict objectForKey:#"rss"] valueForKey:#"channel"] valueForKey:#"item"] valueForKey:#"title"];
As you can see from my code above, the titles are stored in the JSON tag called "title". Very easy to parse. The images are stored in a tag called "description".
How this tag also contains text as well as image URLS. So how can I parse the <img src> tags from it?
Here is one of the JSON description tags:
How can I go about parse the image links in an array?
Thanks for your time, Dan
Please try with below code -
NSString *yourHTMLSourceCodeString = #"";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"
options:NSRegularExpressionCaseInsensitive
error:&error];
[regex enumerateMatchesInString:yourHTMLSourceCodeString
options:0
range:NSMakeRange(0, [yourHTMLSourceCodeString length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSString *img = [yourHTMLSourceCodeString substringWithRange:[result rangeAtIndex:2]];
NSURL *candidateURL = [NSURL URLWithString:img];
if (candidateURL && candidateURL.scheme && candidateURL.host)
{
NSLog(#"img src %#",img);
}
}];
Update
Same thing can be done using below regex change -
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"]((http|https)://.*?)['\"][\\s\\S]*?>)+?"
options:NSRegularExpressionCaseInsensitive
error:&error];

Converting NSString to NSData for use in XCODE

I am getting data from the Yummly API and I would like to use it as though it were serialized JSON data. However, it is currently a string, and I cannot figure out how to turn it to data correctly. The code is as following:
NSString *searchParameters = #"basil"; //should be from text box
//NSError *error1 = nil;
NSString *searchURLName = [#"http://api.yummly.com/v1/api/recipes?_app_id=myAPIId&_app_key=myAPIkey&" stringByAppendingString:searchParameters];
NSURL *searchURL = [NSURL URLWithString:searchURLName];
NSString *searchResults = [NSString stringWithContentsOfURL:searchURL encoding:NSUTF8StringEncoding error:nil];
// Here, the search results are formatted just like a normal JSON file,
// For example:
/* [
"totalMatchCount":777306,
"facetCounts":{}
]
*/
// however it is a string, so I tried to convert it to data
NSData *URLData = [searchResults dataUsingEncoding:NSUTF8StringEncoding];
URLData = [URLData subdataWithRange:NSMakeRange(0, [URLData length] - 1)];
_searchArray = [NSJSONSerialization JSONObjectWithData:URLData options:NSJSONReadingMutableContainers error:nil];
Somewhere over the last four lines, it didn't do what it was supposed to and there is no data in the data object. Any advice or quick hints in the right direction are much appreciated! Thank you1
Look at the error being returned from the NSJSONSerialization object like
NSError *error;
_searchArray = [NSJSONSerialization JSONObjectWithData:URLData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"%#", error);
This might give you a hint of what's wrong. This should work though.
And why exactly are you doing URLData = [URLData subdataWithRange:NSMakeRange(0, [URLData length] - 1)];? You don't need to copy the data, if that's why you're doing that.
Plus, it seems like you're assuming to get an array as the top level object (judging by
/* [
"totalMatchCount":777306,
"facetCounts":{}
]
*/
but this is a dictionary. Basically you probably want a dictionary, not array. This it should be
/* {
"totalMatchCount":777306,
"facetCounts":{}
}
*/
But the error getting returned will tell you that.
It looks like you're over-complicating things a bit. You do not need to bring in this data as an NSString at all. Instead, just bring it in as NSData and hand that to the parser.
Try:
NSString *searchParameters = #"basil"; //should be from text box
NSString *searchURLName = [#"http://api.yummly.com/v1/api/recipes?_app_id=myAPIId&_app_key=myAPIkey&" stringByAppendingString:searchParameters];
NSURL *searchURL = [NSURL URLWithString:searchURLName];
NSData *URLData = [NSData dataWithContentsOfURL:searchURL];
_searchArray = [NSJSONSerialization JSONObjectWithData:URLData options:NSJSONReadingMutableContainers error:nil];
Note that you'll want to verify that the parsed JSON object is indeed an array as expected, and is not/does not contain [NSNull null].

Parsing JSON which contains html data

I want to parse json data which contains html but there is a problem
I made a parser with this lines but always I got this error: The operation couldn’t be completed. (Cocoa error 3840.)
NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSASCIIStringEncoding];
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingMutableContainers error:&error];
You need to fix the incoming JSON object. You will need to encode that HTML in your web-service (whatever that may be). You should be able to see the issue when you run your JSON through a validator like JSONViewer or JSONLint.

Encoded NSData for a url not saving to the documents directory

I'm trying to save a html page locally on the iPhone's documents directory so I can load the page if the phone is in an offline state
My issue is when I call my NSData object directly to be written to file all the raw data is saved in a file in the documents directory.
But as soon as I cast my NSData to a NSString using encoding it stops writing the file in the documents directory. But when I print my content object it logs out the correct data. I just want that to be saved to a file.
NSURL *url = [NSURL URLWithString:#"http://anyurl"];
NSData *urlHtmlData = [NSData dataWithContentsOfURL:url];
NSString *myString = [[NSString alloc]initWithData:urlHtmlData encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:#"index.html"];
[myString writeToFile:fileName atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
What could be causing the content to stop writing to my file?
Or if anyones got a better solution to view offline webpages rather than saving it to the documents directory?
Thanks
There could be a few things wrong with this. One: You don't use stringWithFormat: to append a path component. NSString has a method for that:
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:#"index.html"];
Two: NSStringEncodingConversionAllowLossy is part of an enum that is not defined for writeToFile:, so by using it, you're actually specifying NSASCIIStringEncoding without realizing it. In my opinion, just use NSUTF8StringEncoding instead.
Also, NSString *content = [[NSString alloc]initWithFormat:#"%#", myString]; does absolutely nothing except duplicate myString. Erase that line and just use [myString writeToFile:....