nsstring - out of scope - objective-c

-(void)loadWebAdress:(NSString*)textAdress {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
adressurl=[NSString stringWithFormat:#"http://%#", textAdress];
NSURL *url=[NSURL URLWithString:adressurl];
NSURLRequest *requestObj=[NSURLRequest requestWithURL:url];
[webview loadRequest:requestObj];
}
although url takes it's value from adressurl, adressurl is all the time out of scope when checked in debugger. what is going on? i would like to use it in some other places too. not only in this method. because is out of scope, the app crashes. But, I repeat, it is the one who gives its value to url.

It depends on where the adressurl variable is declared. Since it is generated from the method parameter, it seems odd that you'd want to use it elsewhere in the code. If you have it as a static variable, it could be getting stomped by other code. (For example, if you set it to one value in this method, and another elsewhere, it's not unusual to get crashes, especially if you don't coordinate or synchronize between the two. One reason to avoid globals/statics.) You're free to use the same local variable name in different methods if you like.
Here's what I'd suggest doing instead: (Note: I've fixed some typos.)
- (void) loadWebAddress:(NSString*)textAddress {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#", textAddress]];
[webview loadRequest:[NSURLRequest requestWithURL:url]];
}
This is shorter and avoids unnecessary variables. Since the "http://" prefix is fairly common, it doesn't seem like reusing that will provide that much benefit. Is there something else I'm missing?
Edit: To clarify a typo in my comment, you can get the URL as a string from the UIWebView as follows:
[[[webview request] URL] absoluteString]
This uses the following methods chained together:
-[UIWebView request]
-[NSURLRequest URL]
-[NSURL absoluteString]

Related

How do you set what about:home is on webView, Obj-C

I am creating a Cocoa web browser, and I noticed that if the webview loads a nil location, it just loads about:home. Since I have not set it, the page just appears white. Is there a way I can change what about:home looks like. Even if it is a simple .rtf file or something.
I looked around, but don't see any way to do this. Am I suppose to create a NSURL and set it to whatever file?
Thanks. Oh, and if code is ever needed, I would be glad to add it.
Try something like this:
// Inside your App Delegate
-(void)applicationDidFinishLaunching:(NSNotification *)notification {
// Assuming WebView is called myWebView
NSString *currentURL = [myWebView mainFrameURL];
if(!currentURL) {
NSString *homeResource = [[NSBundle mainBundle] pathForResource:#"home" ofType:#"html" inDirectory:#"default"];
NSURL *homeURL = [NSURL fileURLWithPath:homeResource];
NSURLRequest *request = [NSURLRequest requestWithURL:homeURL];
[myWebView loadRequest:request];
}
}
You'll need to have a pre-made file called home.html within a folder called default located in the Resources section of your project.
I suppose this isn't exactly replacing about:home, but you can always check for about:home and handle that appropriately as well.

How do you override the amount of redirects a webView can handle. Obj-C, Cocoa

This is really annoying me. I have a webView, and I am trying to get it too load drive.google.com. However, because of the amount of redirects on that site, the webView does nothing. I know that the code for loading a webView works, and that URL is correct, as I get the didFailWithProvisionalLoadWithError message. That is how I know that it is the redirect problem.
I have looked all over, but can find no way to alter the amount of allowed redirects. I know that it is possible, as Safari can handle it. There has to be some kind of delegate method to override. No code today, as all my searches (4 days worth of them) have lead me to nothing.
If anyone has an idea, let me know. FYI, this is Cocoa (WebView) not cocoa touch (UIWebView). Thanks.
That for which you have been searching is
– webView:decidePolicyForNavigationAction:request:frame:decisionListener:
which is part of the WebPolicyDelegate protocol.
Read the documentation for WebPolicyDelegate, particularly the discussion for this delegate method. The documentation for WebPolicyDecisionListener describes the messages you can send to the listener. You might identify a redirect inside this delegate method, and you could instruct the decision listener to use or ignore it.
EDIT:
I appreciate the 50 points, but if I didn't help you solve your problem, I hardly think I deserve them, and that was enough guilt to motivate me to sit down and try out your problem.
I built a tiny app, one that isn't document based, or uses ARC or garbage collection. I turned off Auto Layout in the MainMenu.xib file, and simply placed an instance of WebView inside it. I modified AppDelegate to include an outlet for the WebView instance.
I then created fleshed out the -applicationDidFinishLaunching: stub like this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString *urlString = #"http://drive.google.com";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[[[self webView] mainFrame] loadRequest:urlRequest];
}
and if I'm getting redirects, they don't seem to be affecting my ability to display the page.
Are we on the same page (no pun intended)?
EDIT 2:
Good news (or bad news, depending on your POV): Redirects were never the problem (though they did help to shed light on what was really going on).
When it comes to Google Drive, WebView isn't an approved browser. You can, however, fix that (N.B., below) by modifying the user agent string. Here's the revised code:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString *urlString = #"http://drive.google.com";
NSURL *url = [NSURL URLWithString:urlString];
NSString *customUserAgent = [NSString stringWithFormat:#"%# Version/6.0.2 Safari/8536.26.17", [[self webView] userAgentForURL:url]];
[[self webView] setCustomUserAgent:customUserAgent];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[[[self webView] mainFrame] loadRequest:urlRequest];
}
N.B.: The user interface appears to be fully functional, but even so, Google may change its means of determining what the browser is and break this scheme, so consider yourself warned. You might want to explore their SDK for possible alternate means of accessing Google Drive.
As always, good luck to you in your endeavors.
According to the WebView reference class in the Apple documentation, you have to set a delegate that conforms to the webframeloaddelegate protocol.
[webView setFrameLoadDelegate:object];
Then in object, you have to set this method:
- (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame

Reliable way to compare two NSURL or one NSURL and an NSString?

I recently had a problem when comparing two NSURLs and compare one NSURL with an NSString(which is a URL address), the situation is I got an NSURLRequest from somewhere, I may or may not know the URL address it points to, and I have an URL NSString, say "http://m.google.com", now I need to check if the URL in that NSURLRequest is the same as the URL string I had:
[[request.URL.absoluteString lowercaseString] isEqualToString: [self.myAddress lowercaseString]];
this returns NO as the absoluteString gives me "http://m.google.com/" whereas my string is "http://m.google.com" without a slash in the end, even if I create the NSURLRequest using
[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://m.google.com"]]
it still gives me "http://m.google.com/" for absoluteString, I wonder is there any reliable way to compare to NSURL or one NSURL and one NSString?
check if one 'contains' another, but this is not reliable as 'http://m.google.com/blabla' contains 'http://m.google.com'.
convert the NSString to NSURL and use the isEqual method to compare two NSURL and hopefully NSURL's implementation of isEqual can figure it out?
based on step 2, but convert each NSURL to a standard URL using standardizedURL?
Thanks a lot!
If you care only about the trailing slash ambiguity, you can dispense with this question quickly by knowing that NSURL path trims the trailing slash.
But I like the idea of a category method on NSURL that implements some standards-based equivalence ("equivalence" is probably a better term than equality in this case).
#RobNapier refers to a related question with a good answer that points to RFC2616. Another relevant standard for url syntax is RFC1808.
The tough part is deciding what we mean by equivalence, for example, what about differing queries or fragments (anchor links)? The code below errs on the side of permissiveness for most of these ambiguities...
// in NSURL+uriEquivalence.m
- (BOOL)isEquivalent:(NSURL *)aURL {
if ([self isEqual:aURL]) return YES;
if ([[self scheme] caseInsensitiveCompare:[aURL scheme]] != NSOrderedSame) return NO;
if ([[self host] caseInsensitiveCompare:[aURL host]] != NSOrderedSame) return NO;
// NSURL path is smart about trimming trailing slashes
// note case-sensitivty here
if ([[self path] compare:[aURL path]] != NSOrderedSame) return NO;
// at this point, we've established that the urls are equivalent according to the rfc
// insofar as scheme, host, and paths match
// according to rfc2616, port's can weakly match if one is missing and the
// other is default for the scheme, but for now, let's insist on an explicit match
if ([self port] || [aURL port]) {
if (![[self port] isEqual:[aURL port]]) return NO;
if (![[self query] isEqual:[aURL query]]) return NO;
}
// for things like user/pw, fragment, etc., seems sensible to be
// permissive about these.
return YES;
}
I know this is answered. But i don't think , its clear.
I would like to recommend the following.
if ([[url1 absoluteString] isEqualToString:[url2 absoluteString]])
{
//Add your implementation here
}
Having recently encountered the situation where the [NSURL isEqual] method returns false when comparing two URLs like https://www.google.com/ and https://www.google.com I have found that applying the URLByAppendingPathComponent with an empty-string as the parameter to both URLs will return the correct result.
So something like:
[[urlOne URLByAppendingPathComponent:#""] isEqual:[urlTwo URLByAppendingPathComponent:#""]]
will add the trailing slash if missing and leave it alone if it is already included and so the comparison will work as expected.
Seems to me like I am relying on one strange behavior to work-around another strange behavior but this is what I am going with unless I can be convinced otherwise ;-).
Easy way is:
NSString*urlString=[NSString stringWithFormat:#"%#",request.URL];
so you compare with NSString method isEqual:
BOOL equalty=[urlString isEqual:anotherNSString];
XD

Declare an NSString With Format Specifiers and use it as a URL to open in UIWebview

I have an int containing a number. I am wanting to declare an NSString so I can use use format specifiers when assigning a value to it.
I thought it might be something like this:
NSString[NSString stringWithFormat] myString;
myString = [#"http://myurl.com/%d",myInt];
I gather this is not the case, so question one is: How do I declare an NSString that can handle format specifiers and then assign it a value using format specifiers? The purpose of this NSString is to hold a URL, exactly like the second line above.
Question two is, How do I then use this string as a URL to open in a UIWebView?
I assume I use something like this:
[webView loadRequest:
Sadly, this is as far as my knowledge stretches. Is there a way I can tell my UIWebView (webView above) to use the NSString with the URL I mentioned earlier?
I intend on having the NSString as a global variable, as it will be assigned it's value inside a C function. And 'webView' will use it inside a (what I think is a) method. All of this code is in the same file, the Delegate.m file. It is all executed on launch of the application.
Your string should look like this:
NSString *myString = [NSString stringWithFormat:#"http://myurl.com/%d", myInt];
What you missed: adding the * to indicate a pointer, and thinking that you had to/could first state that the string would have a format and then later state the format. It all happens at once, creating the string with the specified format.
Edited to add NSURL
To create a url you're creating an object of class NSURL, like this:
NSURL *myURL = [[NSURL alloc] initWithString:myString];
And then you create the url request:
NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
And finally, tell your webView to load the request:
[webView loadRequest:request];
For your first part:
NSString *myString = [NSString stringWithFormat:#"http://myurl.com/%d", myInt];
Then, based on a tutorial from iphonesdkarticles.com:
//Create a URL object.
NSURL *url = [NSURL URLWithString:myString];
//URL Request Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];

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)