i try to get some text from an URL and put it out in a UITextView.
Thats my code in the ViewController:
NSString *urlString = #"http:/...";
NSError *error = nil;
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString] options:kNilOptions error:&error];
if (error)
NSLog(#"%s: dataWithContentsOfURL error: %#", __FUNCTION__, error);
else
{
NSString *result = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"%s: result = %#", __FUNCTION__, result);
// if you were updating a label with an `IBOutlet` called `resultLabel`, you'd do something like:
self.mytextview.text = result;
}
Now the simulator shows that text in my view:
Sorry, the text is german :)
Now how can I hide or delete that html, head, body etc.?
It displays like this because you are downloading the content of that PHP file which is in HTML format.
You can create a method to find & delete each HTML tag between "<" and ">"
- (NSString*)stringByRemovingHTMLtags:(NSString*)string {
NSRange range;
while ((range = [string rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
string = [string stringByReplacingCharactersInRange:range withString:#""];
return string;
}
Then set your text in the UITextView like this:
self.mytextview.text = [self stringByRemovingHTMLtags:result];
EDIT: In order to get the content of the <p> tag use this method:
- (NSString*)getPtagContentFromString:(NSString*)htmlString {
NSRange startRange = [htmlString rangeOfString:#"<p>"];
if (startRange.location != NSNotFound) {
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [htmlString length] - targetRange.location;
NSRange endRange = [htmlString rangeOfString:#"</p>" options:0 range:targetRange];
if (endRange.location != NSNotFound) {
targetRange.length = endRange.location - targetRange.location;
return [htmlString substringWithRange:targetRange];
}
}
return nil;
}
Then set your text in the UITextView like this:
self.mytextview.text = [self getPtagContentFromString:result];
You should use UIWebView and load your html text like this:
[_webView loadHTMLString:result baseURL:nil];
Related
I'm developing the chat application, where the text entered has to be detected if its URL. If so, change its color and underline it. Please have a look at below screenshot :
To change the color of the url I've used following code:
NSString *urlString = [[detetctedURL absoluteString] stringByRemovingPercentEncoding];
/* *detetctedURL is detected url from entered text using NSDataDetector
/* *for messageText http://stackoverflow.com/somefolder/any-[thing]-etc, the detectedURL is http://stackoverflow.com/somefolder/any-%5Bthing%5B-etc */
NSRange r = [messageText rangeOfString:urlString];
if (r.location != NSNotFound)
{
//colorFromHex 4285f4
[atext addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:66.0/255.0 green:133.0/255.0 blue:244.0/255.0 alpha:1.0] range:r];
[atext addAttribute:NSUnderlineStyleAttributeName value:#(NSUnderlineStyleSingle) range:r];
//set attributed text (atext) to UILabel
}
How can I format detected URLs correctly if the messageText contains the URL with both special character and percent encoding both, or only percent encoding ?
Thanks!
Update :
With the help of following code, I was able to get the required range. However, its working almost fine for most of the links, but not all like in case if there is charcters such as ']-('.
NSString *urlString = [url absoluteString];
NSRange r = [messageText rangeOfString:urlString];
BOOL foundRange = YES;
if (r.location == NSNotFound)
{
foundRange = NO;
//for umlauts or special characters
urlString = [[url absoluteString] stringByRemovingPercentEncoding];
r = [messageText rangeOfString:urlString];
if (r.location == NSNotFound)
{
//for white space in url
urlString = [urlString stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
r = [messageText rangeOfString:urlString];
if (r.location == NSNotFound)
{
urlString = [url absoluteString];
NSString *prefix = url.scheme;
if(prefix)
{
prefix = [prefix stringByAppendingString:#"://"];
urlString = [urlString stringByReplacingOccurrencesOfString:prefix withString:#""];
r = [messageText rangeOfString:urlString];
if (r.location == NSNotFound)
{
urlString = [urlString stringByRemovingPercentEncoding];
r = [messageText rangeOfString:urlString];
if (r.location == NSNotFound)
{
urlString = [urlString stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
r = [messageText rangeOfString:urlString];
if (r.location != NSNotFound){ foundRange = YES; }
}else{ foundRange = YES; }
}else{ foundRange = YES; }
}
}else{ foundRange = YES; }
}else{ foundRange = YES; }
}
if (foundRange)
{
//colorFromHex 4285f4
[atext addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:66.0/255.0 green:133.0/255.0 blue:244.0/255.0 alpha:1.0] range:r];
[atext addAttribute:NSUnderlineStyleAttributeName value:#(NSUnderlineStyleSingle) range:r];
myLabel.attributedText = atext;
}
Use NSDataDetector to find and highlight url.
NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink
error: nil];
NSArray* matches = [detector matchesInString: source
options: 0
range: NSMakeRange(0, [source length])];
You can use this to find phone numbers, address etc.
Set .dataDetectorTypes on your text view instead of trying to change the color yourself. The UITextView will take care of highlighting itself.
I am attempting to retrieve image url strings from some text, and then create an array containing all of these image url strings. I think I know how to get the image urls using NSRegularExpression, but I just don't know how to grab each individual result. I'm done find and replace before, but that just involves manipulating one giant string. Here is my code:
-(NSArray*)parseImages:(NSString*)contents {
NSArray* imageArray = [[NSArray alloc] init];
NSError* error = nil;
NSString* imageHandler = #"\(\?:\\<a\\shref=\"\)https\?:\/\/[\^\/\\s]\+\/\\S\+\\\.\(jpg|png|gif\)";
NSRegularExpression *imageGrabber = [NSRegularExpression regularExpressionWithPattern:imageHandler options:NSRegularExpressionCaseInsensitive error:&error];
if (error)
{
NSLog(#"Couldn't create regex with given string and options");
return nil;
} else {
//Code to add each individual match to imageArray
return imageArray;
}
Here's what I use for multiple matches in a regular expression:
NSArray *matchesArray = [self rangesOfString:#"{regex}" inString:aString];
for (NSValue *rangeVal in matchesArray)
{
NSRange range = [rangeVal rangeValue];
if (range.location != NSNotFound) {
// do stuff with the found range - like add to an NSMutableArray!
}
}
And the rangesOfString method:
- (NSArray *)rangesOfString:(NSString *)searchString inString:(NSString *)str {
NSMutableArray *results = [NSMutableArray array];
NSRange searchRange = NSMakeRange(0, [str length]);
NSRange range;
while ((range = [str rangeOfString:searchString options:NSRegularExpressionSearch|NSCaseInsensitiveSearch range:searchRange]).location != NSNotFound) {
[results addObject:[NSValue valueWithRange:range]];
searchRange = NSMakeRange(NSMaxRange(range), [str length] - NSMaxRange(range));
}
return results;
}
Let Apple do the heavy-lifting with NSDataDetector
NSString *text = #"jibberish http://link1.com jibberish http://link2.com jibberish";
NSError *error;
NSDataDetector *dd = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];
NSArray *matches = [dd matchesInString:text options:0 range:NSMakeRange(0, text.length)];
NSMutableArray *links = [NSMutableArray new];
for (NSTextCheckingResult *result in matches) {
[links addObject:[result URL]];
}
NSLog(#"links: %#", links);
NSLog output:
links: (
"http://link1.com",
"http://link2.com"
)
If there is a need to restrict to extension types:
Add the extensions to a set:
NSSet *extensions = [NSSet setWithArray: #[#"jpg", #"png", #"gif"]];
Add only to the array only if the extension is in the set:
NSString *ext = [[url resourceSpecifier] pathExtension];
if ([extensions containsObject:ext]) {
[links addObject:url];
}
I am working Calendar functionality for my app requirement.IF i click today date or tomorrow date or some other date need to display auspicious details in UITextview.I have been trying to format a string in my text view but I cant work it out. Im very new to xcode.I want to remove HTML Tags in my stringResonse and display in UITextview.
I am writing like this in my code:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
if(connection==urlConnection)
{
NSString *strResponse=[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"String Response is : %#",strResponse);
NSMutableString *mutString=[NSMutableString string];
NSString *s=nil;
NSString *s1=nil;
//NSArray *arr1=[strResponse componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<br>"]];
NSArray *arr2=[strResponse componentsSeparatedByString:#"\n"];
NSLog(#"array %#",arr2);
for(s in arr2)
{
s = [s stringByReplacingOccurrencesOfString: #"<br>" withString: #"\n"];
s1=[s stringByReplacingOccurrencesOfString:#"<font color>" withString:#" "];
[mutString appendString:#""];
[mutString appendString:s1];
}
text1.text=[text1.text stringByAppendingString:mutString];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
strZone=[[NSString alloc]init];
dict=[[NSDictionary alloc]init];
text1=[[UITextView alloc]initWithFrame:CGRectMake(10, 280, 300, 120)];
text1.font=[UIFont fontWithName:#"Helvetica" size:12];
text1.font=[UIFont boldSystemFontOfSize:12];
text1.backgroundColor=[UIColor whiteColor];
text1.editable=NO;
[self.view addSubview:text1];
}
This is my string Response.
S.Panchami 01.38<br>Arudra 02.01<br>V.08.54-10.39<br>D.05.02-06.52<br> <font color=red><u>Festival</u></font><br><font color=blue>Shankara Jayanthi<br></font>
But i want to display like this if user clicks date in calendar
S.Panchami 01.38
Arudra 02.01
V.08.54-10.39
D.05.02-06.52
Festival
Shankara Jayanthi
A simple solution with iOS 7:
NSString *html = #"S.Panchami 01.38<br>Arudra 02.01<br>V.08.54-10.39<br>D.05.02-06.52<br> <font color=red><u>Festival</u></font><br><font color=blue>Shankara Jayanthi<br></font>";
NSAttributedString *attr = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding]
options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute:#(NSUTF8StringEncoding)}
documentAttributes:nil
error:nil];
NSLog(#"html: %#", html);
NSLog(#"attr: %#", attr);
NSLog(#"string: %#", [attr string]);
NSString *finalString = [attr string];
If your working with ios 7 then you can apply this code
[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];
for ios lower than ios 7 use this code,
(NSString *) stringByStrippingHTML {
NSRange r;
NSString *s = [[self copy] autorelease];
while ((r = [s rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:#""];
return s;
}
This should remove all content between < >
NSString * yourString = #"<br>Arudra 02.01<br>V.08.54-10.39<br>D.05.02-06.52<br> <font color=red><u>Festival</u></font><br><font color=blue>Shankara Jayanthi<br></font>";
NSRange r;
NSMutableString * cleanString = [NSMutableString stringWithString:yourString];
while ((r = [cleanString rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
cleanString = [cleanString stringByReplacingCharactersInRange:r withString:#""];
An option to regular expression is to use NSScanner:
- (NSString *)removeHTML:(NSString *)str
{
NSMutableString *pureStr = [NSMutableString stringWithCapacity:[str length]];
NSScanner *scanner = [NSScanner scannerWithString:str];
scanner.charactersToBeSkipped = NULL;
NSString *tmp = nil;
while (![scanner isAtEnd])
{
[scanner scanUpToString:#"<" intoString:&tmp];
if (tmp != nil)
[html appendString:tmp];
[scanner scanUpToString:#">" intoString:NULL];
if (![scanner isAtEnd])
[scanner setScanLocation:[scanner scanLocation] + 1];
tmp = nil;
}
return pureStr;
}
I'd suggest you use a UIWebView. If you use a UITextView, first you will have to strip the HTML tags from it and then have to insert newline character \n for formatting purposes. It would be much easier to wrap your string response with simple HTML format such as <html><head/><body><your string response><body/></html> and display it in a UIWebView.
In objective-c (for ios) I want to achieve the same as I can in AS3:
var test:String = "Abba";
var reg:RegExp = /(a)|(b)/g;
var replacement:Function = function (...args):String
{
var $1:String = args[1];//matched 'a'
var $2:String = args[2];//matched 'b'
if($1)
{
//replace a with -
return "-";
}
if ($2)
{
//replace b with +
return "+";
}
return null;
}
var result:String = test.replace(reg, replacement);//A++-
trace(test, result);//Abba A++-
In other words I would like to have ability to identify which capturing group was matched and replace it accordingly, I'm looking for examples on enumerateMatchesInString: but can't find anything that can solve my problem.
enumerateMatchesInString: calls a block with an NSTextCheckingResult for each match,
and rangeAtIndex:idx gives the range of a captured subgroup:
NSString *string = #"Abba";
NSString *pattern = #"(a)|(b)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:0
error:NULL];
NSMutableString *newString = [string mutableCopy];
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange r1 = [result rangeAtIndex:1];
if (r1.location != NSNotFound) {
[newString replaceCharactersInRange:r1 withString:#"-"];
}
NSRange r2 = [result rangeAtIndex:2];
if (r2.location != NSNotFound) {
[newString replaceCharactersInRange:r2 withString:#"+"];
}
}];
NSLog(#"%#", newString);
// Output: A++-
If the replacement strings have not the same length as the original strings, then it
gets slightly more complicated, because you have to keep track of the length changes
in the resulting string:
NSMutableString *newString = [string mutableCopy];
__block int offset = 0;
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange r1 = [result rangeAtIndex:1];
if (r1.location != NSNotFound) {
r1.location += offset;
NSString *repl = #"---";
[newString replaceCharactersInRange:r1 withString:repl];
offset += [repl length] - r1.length;
}
NSRange r2 = [result rangeAtIndex:2];
if (r2.location != NSNotFound) {
r2.location += offset;
NSString *repl = #"++";
[newString replaceCharactersInRange:r2 withString:repl];
offset += [repl length] - r2.length;
}
}];
NSLog(#"%#", newString);
// Output: A++++---
I am trying to implement a functionality like below images in iPhone.
my requirement is, if user enters any website URL link or youtube video URL link in textview, then I want to get(fetch) that URL title, description, base URL from link, and default image. Then I'll display it as below images. I am successful with below code to fetch any url title.. but am unable to grab description, base URL from link,and default image.
NSError *error = nil;
NSString *html = [NSString stringWithContentsOfURL:_textView.text encoding:NSASCIIStringEncoding error:&error];
if(html)
{
NSLog(#"HTML %#", html);
NSRange r = [html rangeOfString:#"<title>"];
if (r.location != NSNotFound)
{
NSRange r1 = [html rangeOfString:#"</title>"];
if (r1.location != NSNotFound)
{
if (r1.location > r.location)
{
NSString *title = [html substringWithRange:NSMakeRange(NSMaxRange(r), r1.location - NSMaxRange(r))];
NSLog(#"title %#", title);
lable = [[UILabel alloc]init];
lable.frame = CGRectMake(10, 40, 280, 30);
lable.backgroundColor = [UIColor clearColor];
lable.text = title;
lable.numberOfLines=2;
lable.textColor=[UIColor redColor];
lable.font=[UIFont fontWithName:#"Times New Roman" size:14];
[youCell addSubview:lable];
}
}
}
}
if any one having any ideas plz share with me...thank in advance...
You Need To cover inputString into the URL.
NSError *error = nil;
NSURL *inputURL = [NSURL URLWithString:_textView.text];
NSString *pageSource = [NSString stringWithContentsOfURL:inputURL
encoding:NSASCIIStringEncoding
error:&error];
if(pageSource)
{
NSRange startTitle = [pageSource rangeOfString:#"<title>"];
if (startTitle.location != NSNotFound)
{
NSRange endTitle = [pageSource rangeOfString:#"</title>"];
if (endTitle.location != NSNotFound)
{
if (endTitle.location > startTitle.location)
{
NSString *pageTitle = [pageSource substringWithRange:NSMakeRange(NSMaxRange(startTitle), endTitle.location - NSMaxRange(startTitle))];
NSLog(#"Title of Page := %#", pageTitle);
}
}
}
}