{"id":298,"date":"2009-04-22T13:52:41","date_gmt":"2009-04-22T18:52:41","guid":{"rendered":"http:\/\/vgable.com\/blog\/2009\/04\/22\/getting-the-current-url-from-a-webview\/"},"modified":"2009-04-30T15:17:58","modified_gmt":"2009-04-30T20:17:58","slug":"getting-the-current-url-from-a-webview","status":"publish","type":"post","link":"https:\/\/vgable.com\/blog\/2009\/04\/22\/getting-the-current-url-from-a-webview\/","title":{"rendered":"Getting the Current URL from a WebView"},"content":{"rendered":"<p>UPDATED 2009-04-30: WARNING: <strong>this method will <em>not<\/em> always give the correct result.<\/strong><a href=\"http:\/\/developer.apple.com\/DOCUMENTATION\/Cocoa\/Reference\/Foundation\/Classes\/NSURL_Class\/Reference\/Reference.html#\/\/apple_ref\/occ\/clm\/NSURL\/URLWithString:\"> <code>+[NSURL URLWithString:]<\/code> requires it&#8217;s argument to have unicode characters %-escaped UTF8<\/a>.  But <code>stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding<\/code> will convert <code>#<\/code> to <code>%23<\/code>, so <code>http:\/\/example.com\/index.html#s1<\/code> would become <code>http:\/\/example.com\/index.html%23s1<\/code>. Unfortunately, the two URLs are <em>not<\/em> equivalent. The un-%-escaped one refers to section <code>#s1<\/code> in the file <code>index.html<\/code>, and the other tries to fetch the file <code>index.html#s1<\/code> (&#8220;index dot html#s1&#8221;). I have not yet implemented a workaround, although I suspect one is possible, by building the <code>NSURL<\/code> out of bits of the <a href=\"http:\/\/www.comptechdoc.org\/independent\/web\/cgi\/javamanual\/javalocation.html\">JavaScript location object<\/a>, rather then trying to convert the whole string.<\/p>\n<hr>\n<p><code>UIWebView<\/code>\/<code>WebView<\/code> does not provide a way to find the URL of the webpage it is showing. But there&#8217;s a simple (and neat) way to get it using embedded JavaScript.<\/p>\n<p><a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/UIKit\/Reference\/UIWebView_Class\/Reference\/Reference.html#\/\/apple_ref\/occ\/instm\/UIWebView\/stringByEvaluatingJavaScriptFromString:\"><code> - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script<\/code><\/a><\/p>\n<p>Is a deceptively powerful method that can execute dynamically constructed JavaScript, and lets you embed JavaScript snippets in Cocoa programs. We can use it to embed one line of JavaScript to ask a <code>UIWebView<\/code> for the URL it&#8217;s showing.<\/p>\n<pre>@interface UIWebView (CurrentURLInfo)\n- (NSURL*) locationURL;\n@end<br>\n@implementation UIWebView (CurrentURLInfo)\n- (NSURL*) locationURL;\n{\n\tNSString *rawLocationString = [self stringByEvaluatingJavaScriptFromString:@\"location.href;\"];\n\tif(!rawLocationString)\n\t\treturn nil;\n\t\/\/URLWithString: needs percent escapes added or it will fail with, eg. a file:\/\/ URL with spaces or any URL with unicode.\n\tlocationString = [locationString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];\n\treturn [NSURL URLWithString:locationString]\n}\n@end<\/pre>\n<p>With the <code> CurrentURLInfo <\/code> category, you can do <code>aWebView.locationURL<\/code> to get the URL of the page a <code>WebView<\/code> is showing.<\/p>\n<p><small><br \/>\nOne last note, the <\/p>\n<pre>if(!rawLocationString)\n\treturn nil;<\/pre>\n<p>special-case was only necessary, because  <a href=\"http:\/\/openradar.appspot.com\/6810626\"> <code>[NSURL URLWithString:nil]<\/code> throws an exception (rdar:\/\/6810626<\/a>). But Apple has decided that this is correct behavior.<\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>UPDATED 2009-04-30: WARNING: this method will not always give the correct result. +[NSURL URLWithString:] requires it&#8217;s argument to have unicode characters %-escaped UTF8. But stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding will convert # to %23, so http:\/\/example.com\/index.html#s1 would become http:\/\/example.com\/index.html%23s1. Unfortunately, the two URLs are not equivalent. The un-%-escaped one refers to section #s1 in the file index.html, and the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,203,3,5,4,13],"tags":[394,393,391,392],"class_list":["post-298","post","type-post","status-publish","format-standard","hentry","category-cocoa","category-iphone","category-macosx","category-objective-c","category-programming","category-sample-code","tag-javascript","tag-multilingual","tag-uiwebview","tag-webview"],"_links":{"self":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/298","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/comments?post=298"}],"version-history":[{"count":0,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/298\/revisions"}],"wp:attachment":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/media?parent=298"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/categories?post=298"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/tags?post=298"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}