The iOS app I'm writing displays an HTML page, and I would like to add a search feature where the user can search for instances of a keyword and highlight them.
What's the best way to do this?
NSString *filePath = PATH_OF_HTML_FILE;
NSError *err = nil;
NSString *pageHTML = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&err];
if(err)
{
pageHTML = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:&err];
}
if([searchTxtField.text length])
{
NSRange range1 = [pageHTML rangeOfString:searchTxtField.text options:NSCaseInsensitiveSearch];
if(range1.location != NSNotFound)
{
NSString *highlightedString = [pageHTML substringWithRange:range1];
pageHTML = [pageHTML stringByReplacingOccurrencesOfString:highlightedString withString:[NSString stringWithFormat:#"<span style=\"background-color:yellow; color:red;\">%#</span>",highlightedString] options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pageHTML length]) ];
[webView loadHTMLString:pageHTML baseURL:[NSURL fileURLWithPath:filePath]];
}
}
Related
This is my NSString :
NSString timeString = #"<h5 style="direction:ltr"><span data-version-created-date="20180326T120530.000+0000" class="releasedDate">26-Mar-2018 12:05:30</span></h5>";
I want to retrieve only "26-Mar-2018 12:05:30" which is in the span tag.
How do i do that in Objective C?
Please note : The given HTML is in NSString format.
Try this
- (NSString *)stringByStrippingHTML : (NSString*) s {
NSRange r;
while ((r = [s rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:#""];
return s;
}
This will work by stripping out bracketed (<>) expressions. Slashes have been added () to timeString to make it proper NSString*. The stripping is repeated four times, bt should probably be looped with condition.
NSString * timeString = #"<h5 style=\"direction:ltr\"><span data-version-created-date=\"20180326T120530.000+0000\" class=\"releasedDate\">26-Mar-2018 12:05:30</span></h5>";
NSRange openRange = [timeString rangeOfString:#"<"];
NSRange closeRange = [timeString rangeOfString:#">"];
NSRange enclosedRange = NSMakeRange(openRange.location, closeRange.location-openRange.location+1);
timeString = [timeString stringByReplacingCharactersInRange:enclosedRange withString:#""];
openRange = [timeString rangeOfString:#"<"];
closeRange = [timeString rangeOfString:#">"];
enclosedRange = NSMakeRange(openRange.location, closeRange.location-openRange.location+1);
timeString = [timeString stringByReplacingCharactersInRange:enclosedRange withString:#""];
openRange = [timeString rangeOfString:#"<"];
closeRange = [timeString rangeOfString:#">"];
enclosedRange = NSMakeRange(openRange.location, closeRange.location-openRange.location+1);
timeString = [timeString stringByReplacingCharactersInRange:enclosedRange withString:#""];
openRange = [timeString rangeOfString:#"<"];
closeRange = [timeString rangeOfString:#">"];
enclosedRange = NSMakeRange(openRange.location, closeRange.location-openRange.location+1);
timeString = [timeString stringByReplacingCharactersInRange:enclosedRange withString:#""];
NSLog(#"timeString = %#", timeString);
This worked with me
NSString *timeString = #"<h5 style=\"direction:ltr\"><span data-version-created-date=\"20180326T120530.000+0000\" class=\"releasedDate\">26-Mar-2018 12:05:30</span></h5>";
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#">\\d.+\\d<"
options:NSRegularExpressionCaseInsensitive
error:NULL];
[regex enumerateMatchesInString:timeString options:0 range:NSMakeRange(0, [timeString length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
// your code to handle matches here
NSString *subString = [timeString substringWithRange:match.range];
NSLog(#"%#",[subString substringWithRange:NSMakeRange(1, subString.length - 2)]);
}];
If you want to make sure you get the date between the span tags, it would be best to be more explicit than either stripping out all the HTML tags and assuming the only thing left is the date, or assuming there is only one span tag in the whole HTML text. It may work for now, but that will likely break in the future if the HTML ever changes.
NSString * timeString = #"<h5 style=\"direction:ltr\"><span data-version-created-date=\"20180326T120530.000+0000\" class=\"releasedDate\">26-Mar-2018 12:05:30</span><span class=\"someOtherClass\">garbageData</span></h5>";
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"<span.*class=\"releasedDate\"[^>]*>(.*)</span.*>"
options:NSRegularExpressionCaseInsensitive
error:nil];
NSTextCheckingResult *textCheckingResult = [regex firstMatchInString:timeString options:0 range:NSMakeRange(0, timeString.length)];
NSString *releaseDateString = [timeString substringWithRange:[textCheckingResult rangeAtIndex:1]];
if( ! [releaseDateString isEqualToString:#""] )
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MMM-yyyy' 'HH:mm:ss"];
NSDate *releaseDate = [dateFormatter dateFromString:releaseDateString];
NSLog( #"%# - %#", releaseDateString, releaseDate );
}
Note that this works even if there are other spans in the HTML text. It specifically pulls out the one with a class "releasedDate".
I have a UIWebView in my viewcontroller, and when I tried to open an epub file it shows correctly but every epub thereafter shows the same cover page (first page) and its contents are different.
Why is this happeneing? Is there cache inside the codes?
In chapter class
- (void) loadChapterWithWindowSize:(CGRect)theWindowSize fontPercentSize:(int) theFontPercentSize
{
// [[NSURLCache sharedURLCache] removeAllCachedResponses];
fontPercentSize = theFontPercentSize;
windowSize =theWindowSize;
// NSLog(#"webviewSize: %f * %f, fontPercentSize: %d", theWindowSize.size.width, theWindowSize.size.height,theFontPercentSize);
UIWebView* webView = [[UIWebView alloc] initWithFrame:theWindowSize];
[webView setDelegate:self];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:spinePath]];
//CODE FOR IGNORING CACHE
//NSURLRequest* urlRequest ;
//urlRequest=[NSURLRequest requestWithURL:[NSURL fileURLWithPath:spinePath] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10000];
//[webView loadRequest:urlRequest];
NSLog(#"%#",spinePath);//html pahe path
[[UIApplication sharedApplication] openURL:[NSURL fileURLWithPath:spinePath]];
};
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
[webView release];
}
- (void) webViewDidFinishLoad:(UIWebView*)webView
{
[webView stringByEvaluatingJavaScriptFromString:#"document.open();document.close()"];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
sharedManager=[Mymanager sharedManager];
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
// NSLog(#"w:%f h:%f", webView.bounds.size.width, webView.bounds.size.height);
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')",fontPercentSize];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
int totalWidth = [[webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.scrollWidth"] intValue];
pageCount = (int)((float)totalWidth/webView.bounds.size.width);
//NSLog(#"Chapter %d: %# -> %d pages", chapterIndex, title, pageCount);
[webView dealloc];
[delegate chapterDidFinishLoad:self];
}
in my viewocntroller class
- (void) chapterDidFinishLoad:(Chapter *)chapter{
i=i+1;
NSLog(#"iteration%d",i);
NSLog(#"%d",[loadedEpub.spineArray count]);
loadingProgressBar=loadingProgressBar+1;
sharedManager=[Mymanager sharedManager];
NSLog(#"%d",sharedManager.coverPageloadCount);
//sharedManager.coverPageloadCount++;
totalPagesCount+=chapter.pageCount;
sharedManager.TotalPageNumber=totalPagesCount;
if(chapter.chapterIndex + 1 < [loadedEpub.spineArray count]){
[[loadedEpub.spineArray objectAtIndex:chapter.chapterIndex+1] setDelegate:self];
[[loadedEpub.spineArray objectAtIndex:chapter.chapterIndex+1] loadChapterWithWindowSize:webView.bounds fontPercentSize:currentTextSize];
[currentPageLabel setText:[NSString stringWithFormat:#"?/%d", totalPagesCount]];
}
else {
[currentPageLabel setText:[NSString stringWithFormat:#"%d/%d",[self getGlobalPageCount], totalPagesCount]];
[pageSlider setValue:(float)100*(float)[self getGlobalPageCount]/(float)totalPagesCount animated:YES];
paginating = NO;
//NSLog(#"Pagination Ended!");
}
- (void)webViewDidFinishLoad:(UIWebView *)thewebView{
// [self TextureModes];
NSUserDefaults *menuUserDefaults = [NSUserDefaults standardUserDefaults];
if([menuUserDefaults boolForKey:#"btnM1"]){
[webView setOpaque:NO];
[webView setBackgroundColor:[UIColor whiteColor]];
NSString *jsString2 = [[NSString alloc] initWithFormat:#"document.getElementsByTagName('body')[0].style.webkitTextFillColor= 'black'"];
[webView stringByEvaluatingJavaScriptFromString:jsString2];
}
else{
NSUserDefaults *userDefaults2 = [NSUserDefaults standardUserDefaults];
[userDefaults2 setBool:NO forKey:#"btnM1"];
[userDefaults2 synchronize];
[webView setOpaque:NO];
[webView setBackgroundColor:[UIColor blackColor]];
NSString *jsString = [[NSString alloc] initWithFormat:#"document.getElementsByTagName('body')[0].style.webkitTextFillColor= 'white'"];
[webView stringByEvaluatingJavaScriptFromString:jsString];
}
if(sharedManager.textureFlag==1)
{
webView.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"darkWoodP.png"]];
}else if(sharedManager.textureFlag==2)
{
webView.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"paperP.png"]];
}
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')", currentTextSize];
NSString *setHighlightColorRule = [NSString stringWithFormat:#"addCSSRule('highlight', 'background-color: yellow;')"];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
[webView stringByEvaluatingJavaScriptFromString:setHighlightColorRule];
NSString *padding = #"document.body.style.padding='30px 30px 30px 30px';";
NSString *paddingtop = #"document.body.style.padding-top='85px';";
NSString *paddingbottom = #"document.body.style.margin-bottom='85px';";
[webView stringByEvaluatingJavaScriptFromString:padding];
[webView stringByEvaluatingJavaScriptFromString:paddingtop];
[webView stringByEvaluatingJavaScriptFromString:paddingbottom];
if(currentSearchResult!=nil){
// NSLog(#"Highlighting %#", currentSearchResult.originatingQuery);
[webView highlightAllOccurencesOfString:currentSearchResult.originatingQuery];
}
totalWidth = [[webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.scrollWidth"] intValue];
// NSLog(#"%d %f",totalWidth,webView.bounds.size.width);
pagesInCurrentSpineCount = (int)((float)totalWidth/webView.bounds.size.width);
[self gotoPageInCurrentSpine:currentPageInSpineIndex];
}
Try an experiment: instead of reloading the web view, release it and replace it with a new one (properly niling and setting delegates). If the new web view shows the same content it must be the files. If that fixes things you have now one way to fix it.
I'm looking for way to redirect user from our app to google map app to show route between two location. currently apple map is supporting route in united state only but i want to publish my app for other regions.
before few days apple launches google map app for ios, i want to redirect my user inside it.
right now i'm using following code to redirect user in apple maps :
NSString * myLocString = [NSString stringWithFormat:#"40.737893,-73.990173"];
NSString * destString = [NSString stringWithFormat:#"40.733893,-73.993173"];
NSString* queryString = [NSString stringWithFormat:#"saddr=%#&daddr=%#",myLocString,destString];
NSString* searchQuery = nil;
searchQuery = [queryString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* urlString = [NSString stringWithFormat:#"http://maps.apple.com/maps?%#",searchQuery];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
Simple way to achieve this :
BOOL openurlflag=[[UIApplication sharedApplication] canOpenURL:
[NSURL URLWithString:#"comgooglemaps://"]];
if (openurlflag==0)// open apple maps {
NSString * myLocString = [NSString stringWithFormat:#"40.737893,-73.990173"];
NSString * destString = [NSString stringWithFormat:#"40.733893,-73.993173"];
NSString* queryString = [NSString stringWithFormat:#"saddr=%#&daddr=%#",myLocString,destString];
NSString* searchQuery = nil;
searchQuery = [queryString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* urlString = [NSString stringWithFormat:#"http://maps.apple.com/maps?%#",searchQuery];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
} else if (openurlflag==1) // open google maps {
NSString * myLocString = [NSString stringWithFormat:#"40.737893,-73.990173"];
NSString * destString = [NSString stringWithFormat:#"40.733893,-73.993173"];
NSString* queryString = [NSString stringWithFormat:#"saddr=%#&daddr=%#&directionsmode=transit",myLocString,destString];
NSString* searchQuery = nil;
searchQuery = [queryString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* urlString = [NSString stringWithFormat:#"comgooglemaps://?%#",searchQuery];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]]; }
finally i got one link where you can do it by changing URLScheme.
https://developers.google.com/maps/documentation/ios/urlscheme
I'm trying to reuse DTAttributedTextCell with clickable link. I could get hold of the attributedstring but I'm not sure how i can get the frame for the text such that I can create a DTLinkButton.
Here's the sample code from the Demoapp:
- (void)configureCell:(DTAttributedTextCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *snippet = [_snippets objectAtIndex:indexPath.row];
NSString *title = [snippet objectForKey:#"Title"];
NSString *description = [snippet objectForKey:#"Description"];
NSString *html = [NSString stringWithFormat:#"<h3>%#</h3><p>%#</font>Test</p>", title, description];
[cell setHTMLString:html];
cell.attributedTextContextView.shouldDrawImages = YES;
}
Any pointers will be awesome.
I am having a problem with sending csv attachments via MFMailComposeViewController.
Sometimes they come through just fine, but for other users they don't come through as attachments, but rather as text inline in the email (with <br/> instead of line returns.) It's very strange. Anybody know what I'm doing wrong?
Here is a snippet of my code:
MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init];
mailComposeViewController.mailComposeDelegate = self;
NSString *csv = #"foo,bar,blah,hello";
NSData *csvData = [csv dataUsingEncoding:NSUTF8StringEncoding];
[mailComposeViewController addAttachmentData:csvData mimeType:#"text/csv" fileName:#"testing.csv"];
[mailComposeViewController setSubject:#"testing sending csv attachment"];
[mailComposeViewController setMessageBody:#"csv file should be attached" isHTML:NO];
[self presentModalViewController:mailComposeViewController animated:YES];
-(IBAction)btnPressed:(id)sender {
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
NSString *Path = [docDir stringByAppendingString:#"/CSVFile.csv"];
NSData *csvData = [NSData dataWithContentsOfFile:Path];
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"For csv file..."];
[controller setMessageBody:#"...csv file is hear.." isHTML:NO];
[controller addAttachmentData:csvData mimeType:#"text/csv" fileName:#"CSVFile.csv"];
[self presentModalViewController:controller animated:YES];
[controller release];
}
Hi I put sample code for Creating CSV file and attach it with mail but make sure you have to add MessageUI.Framework and import its related header "MessageUI/MessageUI.h"
"MessageUI/MFMailComposeViewController.h" and deligate "MFMailComposeViewControllerDelegate"...I hope this wl useful for others
- (void)viewDidLoad {
arrCsv=[[NSArray alloc]initWithObjects:#"Hello",#"Hi",#"traun",#"fine",nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/try.csv", documentsDirectory];
[[arrCsv componentsJoinedByString:#","] writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
-(ibAction)btnMail {
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
NSString *Path = [docDir stringByAppendingString:#"/CSVFile.csv"];
NSData *csvData = [NSData dataWithContentsOfFile:Path];
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"For csv file..."];
[controller setMessageBody:#"...csv file is hear.." isHTML:NO];
[controller addAttachmentData:csvData mimeType:#"text/csv" fileName:#"CSVFile.csv"];
[self presentModalViewController:controller animated:YES];
[controller release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{ message.hidden = NO;
switch (result)
{
case MFMailComposeResultCancelled:
message.text = #"Result: canceled";
break;
case MFMailComposeResultSaved:
message.text = #"Result: saved";
break;
case MFMailComposeResultSent:
message.text = #"Result: sent";
break;
case MFMailComposeResultFailed:
message.text = #"Result: failed";
break;
default:
message.text = #"Result: not sent";
break;
}
[self dismissModalViewControllerAnimated:YES];
}
set the mime type as "application/octet-stream" and that should do the trick to remove inline attachments (I still named the extension of my file i.e. pdf)
I believe the second parameter to setMessageBody:isHTML: must be YES for attachments to not show up inline.
Even if you set isHTML param to YES, your message body can be sent as plain/text if the message body can be represented as such. And attachments in plain/text messages are not always recognized correctly by some email clients (Outlook).
In my case adding a link in the message body helped. Formatting text as bold with HTML tags works too. Tricky!
Tested on iPod 1G 3.1.3.
This may not be the case here, but one thing to watch out for is that:
[NSString dataUsingEncoding:]
returns a valid but empty NSData object if the conversion to the specified encoding is not possible. Better to use the full version:
[NSString dataUsingEncoding: s allowLossyConversion: YES]
Or check the length of the returned data. It appears that zero-length data attachments are trimmed somewhere in the mail process.