Unexpected error when trying to use NSLog() - iphone

I'm new to iOS develoment, and I'm trying to write an app that can scrape a website (HTML). Scraping google is just an example - I'm planning on scraping something a bit more complex...
My code is as follows:
#import "KppleViewController.h"
#import "TFHpple.h"
#implementation KppleViewController
#synthesize theButton;
- (IBAction)buttonPressed:(UIButton *)sender {
NSLog(#"button Pressed");
NSURL *url = [NSURL URLWithString: #"http://www.google.com"];
NSData *htmlData = [NSData dataWithContentsOfURL: url];
TFHpple *xpathParse = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *elements = [xpathParse searchWithXPathQuery:#"//h3"];
TFHppleElement *element = [elements objectAtIndex:0];
NSString *h3Tag = [element content];
NSLog(#"x",h3Tag);
}
The problem is that I get an error when I attempt to write to console (via NSLog) to see if anything worked. The error that I get is "Data argument not used by format string"
I've searched all over the internet, to no avail. If I comment out the NSLog to see if I my previous code is correct, I get an error about the variable immediately above the NSlog (h3Tag) declared but not being used.
Any help would be greatly appreciated...
I'm also open to any other methods of scraping HTML...

You're being confused by this line:
NSLog(#"x",h3Tag);
All this line does is log the string x. The second argument is completely unused. What you want is something like this:
NSLog(#"%#", h3Tag);
or perhaps a bit more descriptive:
NSLog(#"h3Tag: %#", h3Tag);
The token %# inside of the format string indicates that this is where the next argument will be printed. You may want to read up on the String Format Specifiers or on Formatting String Objects in general.

use
NSLog(#"%#", h3Tag);
or
NSLog(h3Tag);

NSLog(#"x = %#",h3Tag);
Above line prints the value of h3Tag.
For more help about NSLog refer link: [http://www.cocoadev.com/index.pl?NSLog]

Related

ios - NSString losing content when used in NSUrl

I have the following code - note it has to objects with temp, but I will explain.
NSString *temp = _passedOnURL;
NSString *temp = #"http://google.com"; //I comment the one out that I do not use.
NSLog(#"TEMP - %#", temp);
NSURL *feedURL = [NSURL URLWithString:temp];
NSLog(#"FEED URL - %#", feedURL);
The _passedOnURL is a string with the contents passed from a Segue.
Now when I use the 1st temp, the FEED URL returns (null), but when I Log Temp it is still there, so somehow the NSURL does not read the string.
When I hardcode the string with the second temp - there is no issue.
In my mind there is no difference for the NSURL when it is reading the NSString yet, it seems to behave different.
Is there any reason for this??
EDIT
When I do the following code I have no issues:
_passedOnURL = #"http://www.google.com";
so I really have no explanation for this???
try escaping it : [NSURL URLWithString: [temp stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding]]
It seems you have an invalid url string stored in temp. Not every string can be converted to a url but the valid url. Invalid chars and format will lead a nil object after +URLWithString:. So would you let us know what is stored in temp when you try this?
According to the doc for URLWithString:
Parameters
URLString
The string with which to initialize the NSURL object. Must be a URL
that conforms to RFC 2396. This method parses URLString according to
RFCs 1738 and 1808.
Return Value
An NSURL object initialized with URLString. If the string was
malformed, returns nil.
So my guess is that your _passedOnURL is not a valid URL.
I would do a NSLog on your _passedOnURL to check if you are getting the string correctly from the other segue.

Youtube API auto-complete search

I'm using Youtube API, I'd like to have a search auto-complete feature, just like int the site, when you type into the search input box for iPhone App, it gives you terms suggestions. I've read the docs, but still missing, Is this possible using the API?
Well, i know it's too late to answer here, but i will post this answer because it's something that drove me crazy for a couple of days!!! and hope it will save to others...
So... i'm using this API :
http://suggestqueries.google.com/complete/search?client=youtube&ds=yt&alt=json&q=%#
(q is the query for the autocomplete search).
Now, if you try to open a browser, paste this API and change q=%# to (lets say): q=br, you will notice that some file with the suffix .js is downloaded to your computer.
For some reason, i couldn't parse the JSON like that, so i did that trick:
#property(strong, nonatomic) NSMutableArray *ParsingArray // Put that in .h file or after #interface in your .m file
-(void)autocompleteSegesstions : (NSString *)searchWish{
//searchWish is the text from your search bar (self.searchBar.text)
NSString *jsonString = [NSString stringWithFormat:#"http://suggestqueries.google.com/complete/search?client=youtube&ds=yt&alt=json&q=%#", searchWish];
NSString *URLString = [jsonString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // Encoding to identify where, for example, there are spaces in your query.
NSLog(#"%#", URLString);
NSData *allVideosData = [[NSData alloc]initWithContentsOfURL:[[NSURL alloc]initWithString:URLString]];
NSString *str = [[NSString alloc]initWithData:allVideosData encoding:NSUTF8StringEncoding];
NSLog(#"%#", str); //Now you have NSString contain JSON.
NSString *json = nil;
NSScanner *scanner = [NSScanner scannerWithString:str];
[scanner scanUpToString:#"[[" intoString:NULL]; // Scan to where the JSON begins
[scanner scanUpToString:#"]]" intoString:&json];
//The idea is to identify where the "real" JSON begins and ends.
json = [NSString stringWithFormat:#"%#%#", json, #"]]"];
NSLog(#"json = %#", json);
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] //Push all the JSON autocomplete detail in to jsonObject array.
options:0 error:NULL];
self.ParsingArray = [[NSMutableArray alloc]init]; //array that contains the objects.
for (int i=0; i != [jsonObject count]; i++) {
for (int j=0; j != 1; j++) {
NSLog(#"%#", [[jsonObject objectAtIndex:i] objectAtIndex:j]);
[self.ParsingArray addObject:[[jsonObject objectAtIndex:i] objectAtIndex:j]];
//Parse the JSON here...
}
}}
That's it. now ParsingArray is the array that contains all autocomplete information from youTube! to be able to change it every time the user clicks another character on the searchBar, use this function:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self autocompleteSegesstions:self.searchBar.text];}
Now, this is the main code you should have. to make this code faster (because you can now see that you have a writing delay on the keyboard), use another thread to download ParsingArray or use Asynchronous block. (just insert the content of the first method to Async block...)
Remember- maybe there is another way to implement autocomplete youTube search much better then this, but i just did not found it, and i searched a lot! if anyone know a better way, i'll be more then glad if he post it here.
Have fun!!!
Not the Youtube API -- but you can use the Google Suggest API. Make calls to this URL:
http://suggestqueries.google.com/complete/search?client=youtube&ds=yt&q=QUERY
Which will return a json response of the suggest terms that your app can parse and display. If you prefer XML to json, change
client=youtube
to
output=toolbar
(leave the rest of the parameters the same).

Instance method '-jsonValue'not found (return type defaults to 'id')

I got problem in following statement.
NSArray *feedsData = [strFeedsResponse JSONValue];
I presume strFeedsResponse is an instance of NSString. There is no such method as JSONValue in NSString. You need NSString category and add the JSONValue method there.
You can use for example SBJson library https://github.com/stig/json-framework/, which contains NSString+SBJson.h header, which adds the JSONValue method for NSString.
This header must be than imported in the source file where you want to use the JSONValue method:
#import NSString+SBJSON.h
More about categories for example here: http://macdevelopertips.com/objective-c/objective-c-categories.html
One of two things is happening:
strFeedsResponse is not ACTUALLY an instance of an NSString. Maybe it is null or it has been initiated with an incorrect value. You can add a breakpoint to your code to check the value that is stored in strFeedsResponse before you call JSONValue on it.
You have not correctly imported the JSON framework that you are using into your class. You need to add the JSON header to your class.
Hope this helps future searchers on this error...
The reason for the error is that the current version of SBJson seems to not contain the NSString category "NSString+SBJSON.h" referred to by an earlier poster. So, you could easily write your own, or just use the SBJsonParser class directly ("address" is just an NSString containing something like "24 Elm Street, Yourtown, New Mexico"):
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *response = [NSString stringWithContentsOfURL: [NSURL URLWithString: req] encoding: NSUTF8StringEncoding error: NULL];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *googleResponse = [parser objectWithString:response];
Cheers!
If you are using a webservice, then give the URL for that.
try this way...
NSArray* latestentry = (NSDictionary*)[responseString JSONValue];
NSArray *feedsData = [[strFeedsResponse JSONValue] mutableCopy];
Use this Line, it will be useful to you..
This error generally comes when method not found.Here it comes because JSONValue function is not found.
Please make sure you have included json header files where you calling this function.

variable is not a CFStringRef

I have this:
partenaire_lat = 48.8160525;
partenaire_lng = 2.3257800;
And obtain a NSString like this:
NSString *endPoint =[NSString stringWithFormat:#"%#,%#", partenaire_lat, partenaire_lng];
and after using this NSString in some context I get this stupid error:
Variable is not a CFString.
But if I create the NSString like this:
endPoint = #"48.8160525,2.3257800" it then works perfect!
For this error Variable is not a CFString I tried the following:
NSString *endPoint1 =[NSString stringWithFormat:#"%#,%#", partenaire_lat, partenaire_lng];
CFStringRef endPoint =(CFStringRef)endPoint1;
and tried to use endPoint but not working neither this way.Anyone any miraculous idea?Thx
EDIT:partenaire_lat and partenaire_lng are both NSString!!
You have
partenaire_lat = 48.8160525;
partenaire_lng = 2.3257800;
You keep saying that the two variables are NSStrings but you aren't assigning NSStrings to them. You need to assign NSString objects to NSString variables - they aren't created for you automatically.
So the answers which are telling you to use formatted strings are correct. You really should be doing it like this:
partenaire_lat = [[NSString stringWithFormat:#"%f", 48.8160525] retain];
partenaire_lng = [[NSString stringWithFormat:#"%f", 2.3257800] retain];
what are lat and lng? i'm assuming float or double..so you should use [NSString stringWithFormat:#"%f,%f", lat, lng]; (or however you want the floats to be formatted)
You code has several potential problems:
%# format specifier expects object parameter, while it looks like you pass plain float (I may be wrong here as there's not enough context to be sure). Change format to %f to fix your problem if that's really the case:
NSString *endPoint1 =[NSString stringWithFormat:#"%f,%f", partenaire_lat, partenaire_lng];
Your endPoint1 string is autoreleased and may become invalid outside of current scope if you don't retain it. So if you try to use your variable in another method you probably should retain it.
All you need to do
NSString *latStr=[[NSNumber numberWithFloat:partenaire_lat] stringValue];
NSString *lngStr=[[NSNumber numberWithFloat:partenaire_lng] stringValue];
and do whatever you want to do with these two string :)

Multiple parameters in NSURL object

I would like to pass multiple parameters from the iphone sdk to a server-side php which interfaces with a mySQL database.
i found some answers on how to do this, but i'm having a hard time figuring out how to include several parameters.
what i have right now is
- (IBAction)sendButtonPressed:(id)sender
{
NSString *urlstr = [[NSString alloc] initWithFormat:#"http://server.com/file.php?date=%d", theDate];
NSURL *url = [[NSURL alloc] initWithString:urlstr];
[urlstr release];
[url release];
}
which would work for 1 parameter, but what i'm looking for would be something like
http://server.com/file.php?date=value&time=value&category=value&tags=value&entry=value
how would i going about doing this?
The - initWithFormat method takes multiple arguments for the format string.
So you can do things like this:
NSString *urlstr = [[NSString alloc] initWithFormat:#"http://server.com/file.php?date=%d&second=%d&third=%d", theDate, 2, thirdIVar];
- initWithFormat works almost identically to printf() and it variants.
Here is some printf() examples http://stahlforce.com/dev/index.php?tool=csc02
Edit: Where are the variables nameField, tagsField, dreamEntry defined and set?
Unless they are NSStrings and defined in the #interface you can not uses them in this way.
I suggest hard coding some values for testing:
NSString *urlstr = [[NSString alloc] initWithFormat:#"http://server.com/file.php?date=%#&time=%#&name=%#&category=%d&tags=%#&entry=%#", nil, nil, #"Name", nil, #"Tags", #"Dream"];
Creating an NSURL doesn't open communications with a server. It's just a data structure for holding a URL. You want to read up on NSURLConnection.
Are all the variables you're passing in your format really numbers? %d is the placeholder for a number; %# is an object. It's very surprising to be passing nil if you're expecting a number, even for testing purposes. It'll "work" because nil is 0, but it suggests that these aren't really numbers.