How to implement text searching inside UIWebView?

Updated tutorial for this can be found here : http://zaldzbugz.posterous.com/how-to-search-a-string-inside-uiwebview

This links provides a more detailed information to implement this with a good example.

See you there!

About these ads
    • Qburst
    • June 18th, 2010

    Does it work for a uiweview which loads a pdf

  1. HI QBurst,

    Im afraid not. This is only considering that what you are loading in the UIWebview was an HTML.

    If you want, you can convert your PDf files to HTML then you can proceed working with highlighting.

    I created an app in which i used an ePub ebook format but i extracted an html source first right before doing anything and viewing pages inside UIWebview.

    Regards,
    ZaldzBugz

      • Carmelo
      • September 10th, 2010

      Hi zaldzbugz,

      can you send me code for convert pdf files to html with xcode tool?

      carmelogallo.home [at] gmail.com

      i must search with iphone into pdf file.

      Thanks in advance!

  2. hi I was luck to find your topic in yahoo
    your Topics is excellent
    I obtain a lot in your blog really thanks very much
    btw the theme of you blog is really splendid
    where can find it

    • Thank you bet365. By the way, this theme is already available in WordPress admin. You can use it anytime there.

      ZaldzBugz

    • Truedon
    • March 5th, 2011

    I can’t seem to get this to work. It keeps coming back w/ result=0 and nothing get’s highlighted (even when i’ve made sure that the text is there. I’m not sure what i’m doing wrong.

    • Hi Truedon, Thank you for your comment.

      Hope this may help.

      1. ) Make sure that youre javascript code is working correctly. Note that javescript is case sensitive.
      2.) Make sure that the javascript method names are called correctly.

      [NSString stringWithFormat:@"uiWebview_HighlightAllOccurencesOfString('%@')",str]

      ZaldzBugz

        • Truedon
        • March 6th, 2011

        Hey, thanks for the quick reply. I’ve checked all of that and all seems ok. Here is what I have. ViewController.h file with the following:

        #import
        #import “search.h”
        @interface highlightViewController : UIViewController {
        IBOutlet UIWebView *webView;
        }
        @end
        ————-
        My ViewController.m file looks like this:

        #import “highlightViewController.h”
        #import “search.h”
        @implementation highlightViewController
        - (void)viewDidLoad {
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@”test” ofType:@”htm”]isDirectory:NO]]];
        NSString *str = @”evidence”
        [webView highlightAllOccurencesOfString:@"str"];

        [super viewDidLoad];
        }
        @end
        ————
        I then created the category for the UIWebView class as directed above. I called it search.h, here are contents:

        #import
        @interface UIWebView (search)
        - (NSInteger)highlightAllOccurencesOfString:(NSString*)str;
        - (void)removeAllHighlights;
        @end
        ———————-
        search.m file looks like this:

        #import “search.h”
        @implementation UIWebView (search)

        - (NSInteger)highlightAllOccurencesOfString:(NSString*)str
        {
        NSString *path = [[NSBundle mainBundle] pathForResource:@”SearchWebView” ofType:@”js”];
        NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        [self stringByEvaluatingJavaScriptFromString:jsCode];
        NSLog(@”JSCODE=%@”,jsCode);

        NSString *startSearch = [NSString stringWithFormat:@"MyApp_HighlightAllOccurencesOfString('%@')",str];
        [self stringByEvaluatingJavaScriptFromString:startSearch];
        NSString *result = [self stringByEvaluatingJavaScriptFromString:@"MyApp_SearchResultCount"];
        return [result integerValue];
        }

        - (void)removeAllHighlights
        {
        [self stringByEvaluatingJavaScriptFromString:@"MyApp_RemoveAllHighlights()"];
        }
        @end
        —————-
        HTML file loads w/ webview, I can see that javascript does load (using NSLog) but it does not highlight work. It’s almost as IF the function call never gets executed. I’ve traced it and see that it does get executed but doesn’t do anything. What am I doing wrong?? It’s killing me. Pls help.

        Thanks,

        -Truedon

  3. Hi Truedon,

    Ive checked youre code above and i think this might be the problem.

    1.) NSString *str = @”evidence” (the “” signs you used here when i copy pasted are invalid, use the double quotes used by objective-c-> “string”);

    2.) [webView highlightAllOccurencesOfString:@"str"]; (Youre trying to find a string “str” here not the string “evidence”).

    If you want to find a string “evidence”, it should look like this below.

    NSString *str = @”evidence”;
    [webView highlightAllOccurencesOfString:str];

    -ZaldzBugz

    • ajaykumar pasumarthi
    • March 21st, 2011

    hi,i am trying to search text from the pdf file after rendering in iphone through drawLayer.i seen your post post which is great and worth but can you help me to find text location where the search term exactly.

    • Naveen Thunga
    • May 9th, 2011

    Hi zaldzbugz,

    I am having problem while executing this code. It is failing in this condition…
    uiWebview_HighlightAllOccurencesOfStringForElement(element,keyword)
    {
    if(element)// here it is failing for me…
    {

    }

    Pls help me out.

    Thanks in advance.

    • Naveen Thunga
    • May 9th, 2011

    Just check my code:

    //SearchWebView.h

    #import

    @interface UIWebView (SearchWebView)

    - (NSInteger)highlightAllOccurencesOfString:(NSString*)str;
    - (void)removeAllHighlights;

    @end

    //SearchWebView.m

    - (NSInteger)highlightAllOccurencesOfString:(NSString*)str
    {
    NSString *path = [[NSBundle mainBundle] pathForResource:@”WebSearch” ofType:@”js”];
    NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    [self stringByEvaluatingJavaScriptFromString:jsCode];

    NSString *startSearch = [NSString stringWithFormat:@"uiWebview_HighlightAllOccurencesOfString('%@')",str];
    [self stringByEvaluatingJavaScriptFromString:startSearch];

    NSString *result = [self stringByEvaluatingJavaScriptFromString:@"uiWebview_SearchResultCount"];
    return [result integerValue];
    }

    - (void)removeAllHighlights
    {
    [self stringByEvaluatingJavaScriptFromString:@"uiWebview_RemoveAllHighlights()"];
    }

    Main Controller :

    [mAnnotationWebView highlightAllOccurencesOfString:@"to"];

    • Naveen Thunga
    • May 10th, 2011

    Hi zaldzbugz,

    Thanks dude. I got solution for my problem. Actually i am calling [myWebView highlightAllOccurencesOfString:@"keyword"];
    method even before UIWebview is still loading. So for me document.body is coming as nil.

    Thanks for code. I appreciate it.

    • sagar
    • May 10th, 2011

    hi i’m also facing same problem.Do you know how to debug the javascript code.

    Regards
    sagar

  4. I’m a noob at iOS programming. I’m trying to use your code. I’m having two problems:

    1. Lots of “Test1ViewController” may not respond to “-stringByEvaluatingJavaScriptFromString:’ warnings.

    2. When I run the search on my web view, the app goes dark and terminates.

    What have I done wrong?

    - JSB

    • naSh
    • June 18th, 2011

    Hi and Thanks for this great help! But my UIWebViewSearch.js seems to have a lot of errors when I copied and pasted as you wrote and then imported to Xcode. Xcode expects several characters etc. Can you upload the UIWebViewSearch.js document? BTW, I do not have experience in Java. And that is why i do not know what I am doing when I created the js file with TextEdit. Please Help because I have been looking for this for a long time. Also, regrading the methods, it says: ViewController may not respond to -stringByEvaluationJavaScript FromString. Thanks in Advance.

    • naSh
    • June 18th, 2011

    Ok, I was importing the document. I think that is why I got the errors. THe problem now is that in the main View Controller, where I declared the WebView, after I put [WebView highlightAllOccurencesOfString:@"keyword"]; within the ViewDidLoad Method, it says that UIWebView may not respond to highlightAllOcurrencesOfString and after I try to run it, it says,. [UIWebView highlightAllOccurencesOfString:]: unrecognized selector sent to instance 0x4b43bb0
    2011-06-18 11:17:28.401 WebView[2456:207] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[UIWebView highlightAllOccurencesOfString:]: unrecognized selector sent to instance 0x4b43bb0′

    Thanks in advance

  5. HI Nash,

    highlightAllOccurencesOfString: is a function under a class of type UIWebView so you need to declare it in the interface file .h.

    Thats why youre having problems with this code: [WebView highlightAllOccurencesOfString:@"keyword"]; because maybe youre WebView don’t have a class reference which in that class this “highlightAllOccurencesOfString:” was declared and implemented.

    What you need to do:

    1.) Have a javascript like the scode above.
    2.) Create a class of type UIWebview (@Interface WebView : UIWebView) and put all the methods above.
    3.) If you use interface builder to link your WebView, link youre WebView to the class you just created.

    That would solve the problem.

    Regards,
    ZaldzBugz

      • naSh
      • June 18th, 2011

      Thanks for your quick response! I now fixed it and it does not show me warnings. However, although the html loads, it does not highlight the keyword I add. What am I doing wrong?

      Best!

      • naSh
      • June 18th, 2011

      BTW, when I debug it, the result is nil, since it says about my keyword that “Variable is not a CFString”, then result = nil. How do I fix this? THanks again!

  6. have you tried already to linkn your UIWebView variable to the class you just created? Or is the UIWebView you just created have been an IBOutlet link to your interface builder?

      • naSh
      • June 20th, 2011

      Hi zaldzbugz

      Indeed my WebView is linked as the class WebView I created and is also linked in the IB to the IBOutlet. My code is written as you wrote:
      VIEW CONTROLLER H.

      #import
      #import “WebView.h”

      @class WebView;

      @interface SearchWebViewViewController : UIViewController {

      IBOutlet WebView *webView;
      }
      @end

      VIEWCONTROLLER M.

      #import “SearchWebViewViewController.h”

      @implementation SearchWebViewViewController

      - (void)dealloc
      {
      [super dealloc];
      }

      - (void)didReceiveMemoryWarning
      {
      // Releases the view if it doesn’t have a superview.
      [super didReceiveMemoryWarning];

      // Release any cached data, images, etc that aren’t in use.
      }

      #pragma mark – View lifecycle

      // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
      - (void)viewDidLoad
      {
      [super viewDidLoad];

      [webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]
      pathForResource:@”Document” ofType:@”html”]isDirectory:NO]]];

      [webView highlightAllOccurencesOfString:@"nonsense"];

      }

      - (void)viewDidUnload
      {
      [super viewDidUnload];
      // Release any retained subviews of the main view.
      // e.g. self.myOutlet = nil;
      }

      - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
      {
      // Return YES for supported orientations
      return (interfaceOrientation == UIInterfaceOrientationPortrait);
      }

      @end

      WEBVIEW H.

      #import

      @interface WebView : UIWebView {

      }

      - (NSInteger)highlightAllOccurencesOfString:(NSString*)str;
      - (void)removeAllHighlights;

      @end

      WEBVIEW M.

      #import “WebView.h”

      @implementation WebView

      - (NSInteger)highlightAllOccurencesOfString:(NSString*)str
      {
      NSString *path = [[NSBundle mainBundle] pathForResource:@”UIWebViewSearch” ofType:@”js”];
      NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
      [self stringByEvaluatingJavaScriptFromString:jsCode];

      NSString *startSearch = [NSString stringWithFormat:@"uiWebview_HighlightAllOccurencesOfString('%@')",str];
      [self stringByEvaluatingJavaScriptFromString:startSearch];

      NSString *result = [self stringByEvaluatingJavaScriptFromString:@"uiWebview_SearchResultCount"];
      return [result integerValue];
      }

      - (void)removeAllHighlights
      {
      [self stringByEvaluatingJavaScriptFromString:@"uiWebview_RemoveAllHighlights()"];
      }

      @end

      HTML

      p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
      p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}

      This is an Html Document

      And it only has nonsense on it

      I want to find different words

      Let’s see if it works

      UIWEBVIEWSEARCH.JS

      var uiWebview_SearchResultCount = 0;

      /*!
      @method uiWebview_HighlightAllOccurencesOfStringForElement
      @abstract // helper function, recursively searches in elements and their child nodes
      @discussion // helper function, recursively searches in elements and their child nodes

      element – HTML elements
      keyword – string to search
      */

      function uiWebview_HighlightAllOccurencesOfStringForElement(element,keyword) {

      if (element) {
      if (element.nodeType == 3) { // Text node
      while (true) {
      //if (counter < 1) {
      var value = element.nodeValue; // Search for keyword in text node
      var idx = value.toLowerCase().indexOf(keyword);

      if (idx =0; i–) {
      uiWebview_HighlightAllOccurencesOfStringForElement(element.childNodes[i],keyword);
      }
      }
      }
      }
      }

      // the main entry point to start the search
      function uiWebview_HighlightAllOccurencesOfString(keyword) {
      uiWebview_RemoveAllHighlights();
      uiWebview_HighlightAllOccurencesOfStringForElement(document.body, keyword.toLowerCase());
      }

      // helper function, recursively removes the highlights in elements and their childs
      function uiWebview_RemoveAllHighlightsForElement(element) {
      if (element) {
      if (element.nodeType == 1) {
      if (element.getAttribute(“class”) == “ActiveReaderHighlight”) {
      var text = element.removeChild(element.firstChild);
      element.parentNode.insertBefore(text,element);
      element.parentNode.removeChild(element);
      return true;
      } else {
      var normalize = false;
      for (var i=element.childNodes.length-1; i>=0; i–) {
      if (uiWebview_RemoveAllHighlightsForElement(element.childNodes[i])) {
      normalize = true;
      }
      }
      if (normalize) {
      element.normalize();
      }
      }
      }
      }
      return false;
      }

      // the main entry point to remove the highlights
      function uiWebview_RemoveAllHighlights() {
      uiWebview_SearchResultCount = 0;
      uiWebview_RemoveAllHighlightsForElement(document.body);
      }

      Hope all this helps to find what I am missing since it seems everyone else in this forum got it right and wrote the same : (

  7. I see,

    You created a class WebView.h/.m and you make it as a type of your variable (IBOutlet WebView *webView;). Try to use IBOutlet with the default UIWebView object like this (IBOutet UIWebView *webView) and in your interface builder Inspector module, have this link reference and there is an option in interface builder to directly link your UIWebView component to the class you just created namely “WebView”..

      • naSh
      • June 20th, 2011

      I just did that, but it now says UIWebView may not respond to highlightAllOccurencesOfString. BTW, I forgot to tell you that there is another warning that says: ]warning: no rule to process file ‘$(PROJECT_DIR)/SearchWebView/UIWebViewSearch.js’ of type sourcecode.javascript for architecture i386. Is it important?
      And finally, after debugging it keeps saying that Variable is not a CFString and result is nil.

      • nash
      • June 22nd, 2011

      Can you send me a sample code to my email? nashmusic@me.com. Now it finds the keyword buy I do not see nothing highlighted. Please Help

    • beryllium
    • July 13th, 2011

    You have error on remove functionality.

    At first you set span class name to “uiWebviewHighlight”
    span.setAttribute(“class”,”uiWebviewHighlight”);

    but after you check this classname for “ActiveReaderHighlight”..

    Write instead this if (element.getAttribute(“class”) == “uiWebviewHighlight”) and all will works fine :-)

  8. @beryllum: thank you for pointing that out. Updated the source code above.

    Regards,
    ZaldzBugz

  9. thank you for this post!i’m a newbie and i’m not so able to put in place!please can you attach to this post a zip with a simple code for sampe?!!thank you!!

    • zhezhun
    • September 6th, 2011

    Hi

    Thanks for your posting.
    I am sure that your code successfully runs on iphone.

    But I have one question.
    When the keyword that I want to find in webview has a tag in itself, the js code can’t find the keyword.

    for example , I want to find a keyword “That is RAYWENDERLICH.” in the webview.

    But the keyword is really “That is RAYWENDERLICH“.

    in this case, the js code can’t find this keyword.
    Thanks for any help.

  10. hi! how i can put info from UITextField to [theWebView highlightAllOccurencesOfString:@"here"];

    Thanks for any help.

  11. Hi Guys,

    Thank you for your comments.

    @Nikita: You need to have an object referencing you UITextField so that you can pass your textField’s info to your webview.

    Or you can use any of the UITextFields Delegate methods and within those delegate method you will call your webview to execute your js script since these delegate methods has parameters that is a reference to your UITextField.

    @zezhun: I will try my best to find ways to solve your problem.

    Anyways, I will be re-posting this tutorial to my other blog and update everything with best example and details.

    http://zaldzbugz.posterous.com

    Regards,
    ZaldzBugz

  12. Guys, I updated this tutorial with a more clearer details with examples to my other blog. See link below.

    http://zaldzbugz.posterous.com/how-to-search-a-string-inside-uiwebview

    • sagar
    • May 1st, 2012

    Is it possible in pdf also?

    • Unfortunately, it’s not possible in PDF files. For PDF files, you need to use QuartzCore framework.

    • vasu
    • March 22nd, 2013

    Does it work for a uiweview which loads a Xhtml?

    • Johnc957
    • June 8th, 2014

    If you are going for best contents like myself, just pay a quick visit this web page everyday since it offers feature contents, thanks gcbbabdabkeb

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: