How to check if NSURL contains NSString null? - objective-c

I use the following code to get a NSString from a NSDictionary and then cast it into NSUrl:
NSURL * url = [NSURL URLWithString:[self.item objectForKey:#"website"]];
The NSDictionary self.item comes from a web server and it's correctly filled using JSON data. All the other objects inside the NSDictionary work perfectly fine.
But sometimes the web server passes a website url with the text "null" because the object has no website filled in. From debugging i learned that the NSURL object can contain a url with the text "null". But how do i prevent this, or how can i write an if statement that checks this?
I tried the following:
NSString * niks = [eventUrl absoluteString];
if(niks == #"null")
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Event" message:#"Event heeft geen website" delegate:nil cancelButtonTitle:#"Oke" otherButtonTitles:#"Oke", nil];
[message show];
}
else
{
[webView loadRequest:[NSURLRequest requestWithURL:eventUrl]];
NSLog(#"%#",eventUrl);
}
But this doesn't work, it always passes the url directly to the webview. Can someone set me in the right direction?

Your comparison;
if(niks == #"null")
only compares if the pointers are equal (i.e. if the two are the same string object instance). Since one is a constant and the other is created dynamically from JSON fetched from the server, it's very unlikely.
To compare the content of two strings, you should instead do;
if([niks isEqualToString:#"null"])
For the link thirsty, here is the [NSString isEqualToString:] documentation.

To do string comparison, you need to do [niks isEqualToString:#"null"], that's why the first condition is broken.
You can also use [niks RangeOfString:#"null"];

I believe you can do this:
id str = [self.item objectForKey:#"website"];
if([str isMemberOfClass[NSNull class]]) {
... its null
}
The JSON convertors all change null to a NSNull object (in my experience).

I am not 100% clear of my memory, but I encountered a situation where [NSDictionary objectForKey:] actually returned NSNull class instance instead of "null" string.
If this is the case, you can check the class of [self.item objectForKey:#"website"] by using isKindOfClass method.

Related

Xcode HTTP GET Request

I am making an app in which you type a value into a textbox, and the app sends an HTTP GET request to my webserver, ie www.mywebserver.server.com/ihiuahdiuehfiuseh?' + textbox variable' However, I have no idea how to work with Xcode. I am experienced in basic PHP and HTML, and advanced C++, but I am so baffled by this Xcode stuff. In all other languages I have worked with, you could look up something like "how to play a sound file in (language)", and you will get something like "oh yeah just do play(mp3url). But, with Xcode, you have to initiate the connection, initiate the variables, etc etc. I bought 2 $30 books, but I am still so confused. So, back to the point, I just need the textbox numerical number to be parsed after the ? in the URl to be parsed as a variable.
This is an example of a non-http get synchronized
You can find more
-(void)aget:(NSString *)iurl{
NSURL*url = [NSURL URLWithString:iurl];
NSURLRequest *res = [NSURLRequest requestWithURL:url];
NSOperationQueue*que=[NSOperationQueue new];
[NSURLConnection sendAsynchronousRequest:res queue:que completionHandler:^(NSURLResponse*rep,NSData*data,NSError*err){
if ([data length]> 0 && err == nil) {
NSString* rel=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#",rel);
}else{
NSLog(#"isnull");
}
}
];
}
Through this launch him
NSString * str = [self getDataFrom: # "your url"];
     NSLog (# "% #", str);
If you have a UITextFiled, you would do the following
NSString baseUrl = #"www.mywebserver.server.com/ihiuahdiuehfiuseh?"
NSString variable = textField.text;
NSString absoluteURL = [NSString stringWithFormat:#"%#%#", baseUrl, variable];
//Send the absolute variable now to the server
If you go for a solution like Omar Abdelhafith suggests, don't forget to url-encode your 'querystring'. There is a method in the string class for this: "stringByAddingPercentEscapesUsingEncoding", but it's not perfect.
I've recently used the solution suggested here: http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/.

Objective C, NSDictionary loop through each object

I am new to Facebook Developer. I want to create Mac OSX application using Facebook API. When i request FQL and its return me JSON data only like below:
My Code:
[self.result_text setString:[NSString stringWithFormat:#"%#",[result objectForKey: #"result"]];
It display:
[{"name":"My Name","first_name":"My First Name","last_name":"My Last Name"}]
I want to read the object inside this Dictionary. Example I just want to display "My Name" string. But I don't know how to it.
Thanks,
As Ashley Mills wrote, you should check the documentation. You can loop through the all dictionary keys like this:
for ( NSString *key in [dictionary allKeys]) {
//do what you want to do with items
NSLog(#"%#", [dictionary objectForKey:key]);
}
Hope it helps
You can parse the JSON contents from the server into a NSDictionary object via Lion's brand new NSJSONSerialization class (documentation linked for you).
e.g.
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData: [self.result_text dataUsingEncoding: NSUTF8StringEncoding] options: nil error: &error];
And once you have it in a NSDictionary object, it's easy to do something like:
NSString * myLastNameContent = [jsonDictionary objectForKey: #"last_name"];
Sergio's answer (which he keeps editing, even as I type :-) is very good too. +1 to him.
You can use JSONKit to transform the JSON string into a dictionary:
NSDictionary *resultsDictionary = [resultString
objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode|JKParseOptionValidFlags error:&err];
NSString* name = [resultDictionary objectForKey:#"name"];
JSONKit is straightforward to use and will make your application work also on older SDK versions.
You should read the documentation for NSDictionary here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsdictionary_Class/Reference/Reference.html
in particular the section titled Accessing Keys and Values

dataWithContentsOfURL return value not nil when URL empty

i have a problem using dataWithContentsOfURL.
I'm loading some images from the internet in a loop.
The Problem is: if the image at the URL doesn't exist, dataWithContentsOfURL does NOT return nil as expected. The apple reference says it returns nil if NSData could not be created.
Here's the Code:
NSString *TermineImgFileName = nil;
NSString *TermineImgPath = nil;
NSURL *TermineImgURL = nil;
NSData *TermineImg = nil;
for (deviceTermineHighInt; deviceTermineHighInt <= serverTermineHighInt; deviceTermineHighInt++) {
TermineImgFileName = [NSString stringWithFormat:#"Termine%i.png", deviceTermineHighInt];
TermineImgURL = [rootURL URLByAppendingPathComponent:TermineImgFileName];
TermineImg = [NSData dataWithContentsOfURL:TermineImgURL];
if (TermineImg != nil) {
TermineImgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:TermineImgFileName];
[TermineImg writeToFile:TermineImgPath atomically:YES];
updateCount += 1;
NSLog(#"File %# saved", TermineImgFileName);
}
else {
NSLog(#"Write Error");
}
TermineImg = nil;
}
Do you know why the method doesn't return nil if the file at the URL doesn't exist?
And a second question: Does it make sense to use the Strings, NSURL and NSData as i did? I thought for memory reasons it would be the best way.
Thank you in advance,
Nikos
Edit: The variables for the loop are defined before the code, the loop works fine. Also the variable rootURL is a constant defined in the header. The URL is built fine and it works.
I'd say the question is what the server actually does if you request a non-existing image.
If it gives you a 404, -dataWithContentsOfURL: should return nil - but if it doesn't, a NSData instance with the results will be created which just happens to not contain any useful image data.
Testing the code (on a single run ). If the image does not exist I get the Write Error as expected. Whats returned is (NULL). Which I think acts the same in this case, and points to a zero value.
There is a stackoverflow post which tries to explain it Here. are-null-and-nil-equivalent

Objective-C: initWithContentsOfURL returning null

I'm working on an app that would display a remote html and use local images, so what I'm trying to do is download the HTML of the website and display it as a "local" page, that would have access to images in my bundle.
For some reason I can't get initWithContentsOfURL to work. I checked all manuals and examples I could find and it seems that I'm doing it correctly, but the thing just won't work, returns null all the time. The same page loaded with NSURLRequest requestWithURL works fine.
Here is the code:
- (void)awakeFromNib
{
appURL = #"http://dragontest.fantasy-fan.org";
notConnectedHTML = #"Could not connect.";
NSString *seedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/seed.php", appURL]]];
NSString *HTMLdata = #"";
if (seedString = #"(null)") {
NSLog(#"Can't connect on awakeFromNib.");
HTMLdata = notConnectedHTML;
}else {
HTMLdata = [NSString stringWithFormat:#"<body style='padding:0px;margin:0px;'>%#%#</body>", seedString, #"<br><img src='images/Default.png'>"];
}
[homeView loadHTMLString:HTMLdata baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]]];
}
Firstly, why aren't appURL and notConnectedHTML declared as NSString *? Are they declared this way elsewhere?
Secondly, you might be better off using NSURL's -urlWithString:relativeToURL: to create the actual request URL.
Thirdly (and this is your actual problem here I suspect), to compare two C primitives, you use ==. = is the assignment operator (it makes the thing on the left equal to the thing on the right). To compare two Objective-C objects, use a comparison method, like -isEqual: or -isEqualToString: (which is specifically for NSStrings).
So instead of:
if (seedString = #"(null)")
You should use
if ([seedString isEqualToString:#"(null)"])
However I suspect the reason you're trying to compare to "(null)" is because that's what NSLog spits out when an object is equal to nil. When an object is nil, the object reference itself is equal to the nil constant, so you should use this to see if an object is nil:
if (seedString == nil)
Just for good measure, some people like to use this syntax which does exactly the same thing:
if (!seedString)

Converting File Path From NSString To NSURL

I'm working through Cocoa smoothly, but this problem seems so basic it cancels out all the cool stuff I learned. :/
I have a generated file path, and it needs to be in NSURL format. From research, this is the code I wrote:
NSLog(#"Old path = %#", pathToFile);
NSURL *xmlURL = [[[NSURL alloc] init] fileURLWithPath:pathToFile];
NSLog(#"New path = %#", [xmlURL absoluteString]);
And the output:
2010-01-27 15:39:22.105 MusicLibraryStats[28574:a0f] Old path = file://localhost/Users/[username]/Music/iTunes/iTunes%20Music%20Library.xml
2010-01-27 15:39:22.105 MusicLibraryStats[28574:a0f] New path = (null)
First off, the alloc-init shouldn't even be necessary; other people seem to get away with it. In this case, if I don't alloc-init, I get an 'unrecognized selector' error on that line. Of course, now I'm just getting plain old (null).
Where did I goof?
Thanks!
The [[NSURL alloc] init] is not just unnecessary, it's invalid. fileURLWithPath: is a class method, which means you can only call it on the class object (that is, NSURL itself). It does not produce a compile error because -(NSURL *)init returns an object of type id, and does not result in a runtime error because -(NSURL *)init actually returns nil, and messages sent to nil will just cascade another nil as their return value.
This code should work:
NSString* pathToFile = #"/this/is/a/path";
NSURL* url = [NSURL fileURLWithPath:pathToFile];
I found your problem.
-[NSOpenPanel URLs] returns an array of NSURL objects, which you treat as NSString objects. That's not right. You should use the following:
NSURL* url = [[oPanel URLs] objectAtIndex:0];
The debugger could've show you that if you looked at the pathToFile variable. Make sure to check it next time. :) Hovering a variable with your mouse should get you its type.
However, remember that there are situations where you will legitimately encounter another type than the one you expected. For instance, the private NSPathStore2 class is part of the NSString cluster, and you can do everything NSString supports on NSPathStore2 objects. (If this happens and you're not too sure, check the documentation to see if the type you expect is a cluster type. That's how they're called in the documentation.)