convert NSAttributedstring (with NSTextAttachment having image) to html in ios obj c - html

I know how to convert the common NSAttributedString (which has no image) into HTML. I set the Images as NSTextAttachment to NSAttributedString. How could I convert the whole attributed string into HTML?
UIImage *image = [UIImage imageNamed:#"Test.png"];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = image;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:htmlString];
NSAttributedString *attstringImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedString appendAttributedString:attstringImage];
NSAttributedString *titleContent = (NSAttributedString *)attributedString;
NSDictionary *documentAttributes = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [titleContent dataFromRange:NSMakeRange(0, titleContent.length) documentAttributes:documentAttributes error:NULL];
NSString *html = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
Please suggest me with quick answer

Related

Can't get data on detailviewcontroller with Hpple parsing

I am a beginner in Obj-C and I try to make an app with this raywenderlich tutorial.
I parse html page with Title of articles (mininglife.ru) , also I getting an urls of each articles and keep it in an NSMutableArray for using it in my DetailviewController.
But when I try to pull urls off and put it in NSUrl nothing happens. I've tried a lot of ways, Can you help me with it and try to explain if I do something wrong. Thank you.
-(void)loadArticles{
Articlelist *urlOfArticle = [_objects objectAtIndex:self]; // from previous parsing
NSURL *articleUrl = [NSURL URLWithString:urlOfArticle.url];// I think this string is wrong, or?
NSData *htmlUrlsData = [NSData dataWithContentsOfURL:articleUrl];
TFHpple *articleParser = [TFHpple hppleWithHTMLData:htmlUrlsData];
NSString *articleNameXpath = #"/html/body/div[1]/div/div[1]/main/article/h1";
// NSString *articleContentXpath = #"//div[#class'entry-content']//p";
NSArray *articleNameNodes = [articleParser searchWithXPathQuery:articleNameXpath];
// NSArray *articleContentNodes = [articleParser searchWithXPathQuery:articleContentXpath];
NSMutableArray *newArticleArray = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in articleNameNodes) {
Article *newArticleName = [[Article alloc] init];
[newArticleArray addObject:newArticleName];
newArticleName.name = [[element firstChild] content];
}
_articleName = newArticleArray;
[self.tableView reloadData];
}
Change interface to this
#interface MasterViewController () {
NSMutableArray *_articles;
}
#end
Add this to MasterViewController
- (void)loadArticles
{
NSURL *articlesUrl = [NSURL URLWithString:#"http://mininglife.ru"];
NSData *articlesHtmlData = [NSData dataWithContentsOfURL:articlesUrl];
TFHpple *articlesParser = [TFHpple hppleWithHTMLData:articlesHtmlData];
NSString *articlesXpathQueryString = #"/html/body/div[1]/div/div[1]/main/article/h1";
NSArray *articlesNodes = [articlesParser searchWithXPathQuery:articlesXpathQueryString];
NSMutableArray *newArticles = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in articlesNodes) {
Article *article = [[Article alloc] init];
[newArticles addObject:article];
article.title = [[element firstChild] content];
article.url = [element objectForKey:#"href"];
}
_articles = newArticles;
[self.tableView reloadData];
}
Change DetailviewController.h's interface to
#class Article;
#interface DetailViewController : UIViewController
#property (strong, nonatomic) Article *article;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
Change DetailViewController.m to
#import "DetailViewController.h"
#import "Article.h"
#import "TFHpple.h"
#implementation DetailViewController
#synthesize detailDescriptionLabel = _detailDescriptionLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadArticle];
}
- (void)loadArticle
{
NSURL *articleUrl = [NSURL URLWithString:self.article.url];
NSData *articleHtmlData = [NSData dataWithContentsOfURL:articleUrl];
TFHpple *articleParser = [TFHpple hppleWithHTMLData:articleHtmlData];
NSString *articleXpathQueryString = #"//div[#class'entry-content']//p";
NSArray *articleNodes = [articleParser searchWithXPathQuery:articleXpathQueryString];
NSMutableArray *newArticleContents = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in articleNodes) {
[newArticleContents addObject:[[element firstChild] content]];
}
NSLog(#"%#", newArticleContents);
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Detail", #"Detail");
}
return self;
}
#end
Don't forget to change all call to loadTutorials to loadArticles in MasterViewController. PS: This example only prints the articles content to the console
Your xPath might be wrong as well

How to save bold font using html in objective c?

I've typed some text in uitextview and also I've select some text and make it bold.After that I'm going to save this data into my application.Now,When I'm going to fetch that data then it will not displaying same as I've saved.
Its not save bold font.
Below is the code :
pragma mark - btnActions
-(IBAction)btnActions:(UIButton *)sender
{
[self addOrRemoveFontTraitWithName:#"Bold" andValue:UIFontDescriptorTraitBold];
}
pragma mark - Private method implementation
-(void)addOrRemoveFontTraitWithName:(NSString *)traitName andValue:(uint32_t)traitValue{
NSRange selectedRange = [txtViewNote selectedRange];
NSDictionary *currentAttributesDict = [txtViewNote.textStorage attributesAtIndex:selectedRange.location
effectiveRange:nil];
UIFont *currentFont = [currentAttributesDict objectForKey:NSFontAttributeName];
UIFontDescriptor *fontDescriptor = [currentFont fontDescriptor];
NSString *fontNameAttribute = [[fontDescriptor fontAttributes] objectForKey:UIFontDescriptorNameAttribute];
UIFontDescriptor *changedFontDescriptor;
if ([fontNameAttribute rangeOfString:traitName].location == NSNotFound) {
uint32_t existingTraitsWithNewTrait = [fontDescriptor symbolicTraits] | traitValue;
changedFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:existingTraitsWithNewTrait];
}
else{
uint32_t existingTraitsWithoutTrait = [fontDescriptor symbolicTraits] & ~traitValue;
changedFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:existingTraitsWithoutTrait];
}
UIFont *updatedFont = [UIFont fontWithDescriptor:changedFontDescriptor size:0.0];
NSDictionary *dict = #{NSFontAttributeName: updatedFont};
[txtViewNote.textStorage beginEditing];
[txtViewNote.textStorage setAttributes:dict range:selectedRange];
[txtViewNote.textStorage endEditing];
}
pragma mark - btnSave
-(IBAction)btnSave:(id)sender
{
NSURL *documentDirectoryURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *documentURL = [documentDirectoryURL URLByAppendingPathComponent:#"test.html"];
NSString *htmlCode = txtViewNote.text;
NSError* error;
if (![htmlCode writeToURL:documentURL atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
NSLog(#"Couldn't save file because: %#", error);
}
NSString* fileToUpload = [NSString stringWithContentsOfURL:documentURL encoding:NSUTF8StringEncoding error:&error];
if (!fileToUpload) {
NSLog(#"Couldn't read file because: %#", error);
}
}
can any one html me?
The problem is you are saving the plain text of the textView instead of the attributedText.
NSString *htmlCode = txtViewNote.text;
Instead you should save the attributed text like this:
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:NSHTMLTextDocumentType,NSDocumentTypeDocumentAttribute, nil];
NSData *htmlData = [[self txtViewNote].attributedText dataFromRange:NSMakeRange(0, [self txtViewNote].attributedText.length) documentAttributes:attributes error:NULL];
NSString *htmlCode = [[NSString alloc]initWithData:htmlData encoding:NSUTF8StringEncoding];
If you want to write the htmlCode to the textView, you should:
NSMutableAttributedString *tmp = [[NSMutableAttributedString alloc] initWithData:htmlData options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)} documentAttributes:nil error:nil];
[txtViewNote setAttributedText:tmp];

Swift and parsing JSON into a Dictionary - objectForKey

I have this Objective C code:
NSMutableArray *dataArray = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSLog(#"Dictionary = %#",dataArray);
NSMutableArray *venues = [[NSMutableArray alloc] init];
for (NSDictionary *venueDic in dataArray) {
MapPoint *mapPoint = [[MapPoint alloc] init];
mapPoint.name = [venueDic objectForKey:#"name"];
mapPoint.image_path = [venueDic objectForKey:#"image_path"];
[venues addObject:mapPoint];
NSLog(#"Venue Name: %#", mapPoint.name);
}
But I am struggling to translate the FOR loop. I've spent hours already looking for a solution.

XCode, iOS: Parsing HTML encoding with hpple

I have a problem with encoding when parsing web page with hpple in XCode.
- (void)loadTutorials {
NSURL *tutorialsUrl = [NSURL URLWithString:#"http://qrz.si/members/s55db/"];
NSData *tutorialsHtmlData = [NSData dataWithContentsOfURL:tutorialsUrl options:NSASCIIStringEncoding error:nil];
TFHpple *tutorialsParser = [TFHpple hppleWithHTMLData:tutorialsHtmlData];
NSString *tutorialsXpathQueryString = #"//td[#class='data']";
NSArray *tutorialsNodes = [tutorialsParsersearchWithXPathQuery:tutorialsXpathQueryString];
NSMutableArray *newTutorials = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in tutorialsNodes) {
Tutorial *tutorial = [[Tutorial alloc] init];
[newTutorials addObject:tutorial];
for (TFHppleElement *child in element.children) {
if ([child.tagName isEqualToString:#"img"]) {
// NSLog([child objectForKey:#"src"]);
} else if ([child.tagName isEqualToString:#"p"]) {
//NSLog([[child firstChild] content]);
tutorial.title = [[child firstChild] content];
}
}
}
_objects = newTutorials;
[self.tableView reloadData];
}
Page should be UTF-8 as the source points out, but I get wierd characters out.
How can I force change encoding of the data? Any help would be highly appreciated!
options:NSASCIIStringEncoding
is useless here, documentation points out that it's not the right way to go.
To set encoding, one must edit XPathQuery.m by Matt Gallagher, that I got in the same tutorial. Changes were visible, but nothing worked, as the site was clearly UTF-8 encoded.
The problems were server side and administrator offered me good old plain XML :)
You are telling NSData object that the contents of the URL you are loading is ASCII not UTF8:
NSData *tutorialsHtmlData = [NSData dataWithContentsOfURL:tutorialsUrl options:NSASCIIStringEncoding error:nil];
Which should be
NSData *tutorialsHtmlData = [NSData dataWithContentsOfURL:tutorialsUrl options:NSUTF8StringEncoding error:nil];

Generate HTML file from NSAttributedString

Recently, I come into a problem in my project. I need convert NSAttributedString to HTML file. The solution Click here doesn't work for me because want to output the HTML file only with TagName and idName and ClassName, at the same time, output the CSS style file to control how the HTML file will display.
Here is my sample code, I wish you can get my intend:
- (NSDictionary *)html
{
NSTextStorage *textStorage = [self contents];
NSArray *arr = [textStorage paragraphs];
// Initialize the CSS dictionay
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
nil];
NSEnumerator *paragraphEnumerator;
paragraphEnumerator = [arr objectEnumerator];
NSAttributedString *paragraph;
NSMutableArray *paragrapHTMLStrings = [[NSMutableArray alloc] initWithCapacity:[arr count]];
NSMutableString *cssString = [[NSMutableString alloc] initWithCapacity:0];
[cssString appendString:#"div{"];
[cssString appendString:[NSString stringWithFormat:#"-webkit-column-count:%ld;", self.columnCount]];
[cssString appendString:[NSString stringWithFormat:#"width:%fpx;", self.bounds.size.width]];
[cssString appendString:[NSString stringWithFormat:#"height:%fpx;", self.bounds.size.height]];
[cssString appendString:#"}"];
[dict setObject:cssString forKey:#"css"];
while (paragraph = [paragraphEnumerator nextObject]) {
// initialize
NSUInteger length;
NSRange effectiveRange = NSMakeRange(0, 0);
id attributeValue;
length = [paragraph length];
// get the font attributes
attributeValue = [paragraph attribute:NSFontAttributeName atIndex:NSMaxRange(effectiveRange) effectiveRange:&effectiveRange];
NSLog(#"font is %#", [attributeValue fontName]);
NSLog(#"font-size is %f", [[[attributeValue fontDescriptor] objectForKey:NSFontSizeAttribute] floatValue]);
NSMutableString *htmlString = [NSMutableString stringWithFormat:#"", [attributeValue fontName],
[[[attributeValue fontDescriptor] objectForKey:NSFontSizeAttribute] floatValue]];
[htmlString appendString:[paragraph string]];
[htmlString appendString:#""];
NSLog(#"htmlString is %#", htmlString);
[paragrapHTMLStrings addObject:htmlString];
htmlString = nil;
}
NSMutableString *htmlStringOfGraphToReturn = [NSMutableString stringWithString:#""];
NSString *stringToAdd;
NSEnumerator *stringEnumerator;
stringEnumerator = [paragrapHTMLStrings objectEnumerator];
while (stringToAdd = [stringEnumerator nextObject])
{
[htmlStringOfGraphToReturn appendString:stringToAdd];
}
[htmlStringOfGraphToReturn appendString:#""];
[dict setObject:htmlStringOfGraphToReturn forKey:#"html"];
// test part
CSSSetGenerator *generater = [[CSSSetGenerator alloc] init];
NSMutableString *string = [generater outputCSSStyleContent:self];
NSLog(#"%#", string);
return dict;
}
I got the solution from Github, There's an open project named DTCoreText. I hope this might be useful for someone.