iOS NSAttributedString转换为HTML

24

我有一个从HTML转换而来的NSAttributed字符串,它被设置为一个UITextView

- (void)setHtml:(NSString *)html {

    NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];

    // Create the HTML string
    NSDictionary *importParams = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
    NSError *error = nil;
    self.htmlString = [[NSAttributedString alloc] initWithData:htmlData options:importParams documentAttributes:NULL error:&error];

    self.editorView.attributedText = self.htmlString;

}

我允许用户编辑他们想要的内容,然后我希望将其转换回HTML格式,因此我使用:

- (NSString *)getHTML {
    NSDictionary *exportParams = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
    NSData *htmlData = [self.editorView.attributedText dataFromRange:NSMakeRange(0, self.editorView.attributedText.length) documentAttributes:exportParams error:nil];
    return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}

它确实返回HTML,但不是我想要的方式。所有内容都被赋予了一个class属性,并且CSS被放在文档的顶部。像图片和链接这样的内容甚至没有包括在返回的HTML中,可能还有更多问题。

有没有更好的方法从NSAttributedString中获取HTML?或者,我是否可以解析NSAttributedString并编写自己的HTML?


请查看此链接:https://dev59.com/5mw15IYBdhLWcg3whMA1 - Tarek Hallak
3个回答

13

也许你可以看一下这个代码库:https://github.com/IdeasOnCanvas/Ashton

其中有两个有趣的类:

AshtonHTMLReader.h

 - (NSAttributedString *)attributedStringFromHTMLString:(NSString *)htmlString;

而作家:

AshtonHTMLWriter.h

- (NSString *)HTMLStringFromAttributedString:(NSAttributedString *)input;

生成的 HTML 不太美观,但如果您尝试在 UIWebView 中显示它,它看起来相当不错。

图片的简单想法:使用 base64 编码并将其直接放入带有正确框架的 <img> 标签中。

虽然很丑,但可以使用 => 几个月前我使用这个过程创建和编辑了一些 HTML 文件。


1
这是一个很酷的想法,但检查源代码后发现它在解析能力方面相当有限。样式将是一个问题。 - Léo Natan
实际上这不是理想的。但这个项目用于检索字体,颜色,斜体/粗体等等...另一个问题是将 base64 编码的图像直接嵌入 HTML 中会使页面加载时间变得很长! - Alban
作为问题的扩展: 我对一种在HTML中包含图像但不使用base64编码的方法很感兴趣。 如果有人有任何想法,请分享! 类似于Microsoft的.chm格式。 - Alban
这个项目非常不错!我曾经遇到一个问题,我想把UITextView的属性文本粘贴到用户可以发送给自己的电子邮件消息中。使用原始问题中的方法会导致大部分格式(字体类型和大小)丢失。有了这个项目,您只需调用mn_HTMLRepresentation,它是NSAttributedString上一个分类方法,并将其作为正文传递给MFMailComposeViewController,您就可以获得一个漂亮格式化的电子邮件,它看起来与应用程序的textview完全相同。 - rvijay007

9
这是一个复杂的问题,我将开始用简短的回答。您可以在评论中向我提问,我会根据需要扩展答案。
我们也尝试过使用属性字符串方法,但发现它并不适用于完整的HTML编辑。许多元素没有支持,要么因为转换器没有完全开发,要么因为这些元素被苹果公司认为超出了范围。解析属性字符串是不够好的,因为属性字符串已经在您尝试重新创建它时失去了大部分HTML的丰富性。
相反,我们使用一个webview,在文档正常加载后,启用body元素的contentEditable。这样做允许您以最完整的方式编辑文档,只受WebKit限制。最后,为了取回HTML,我们禁用contentEditable,并使用document.outerHTML获取整个HTML,包括用户所做的更改。
请不要轻易决定实施此方法。它是一个有点复杂的解决方案,但肯定是可行的。Webview不像Textview那样漂亮,但如果花费足够的精力来调整,它也可以很好看。
如有需要,我会进一步扩展这个答案。

1
@JesseNaugher 我在修复webview错误方面有着广泛的知识。如果您有具体问题,可以在这里提问或直接联系我。无论如何,Webview是处理复杂编辑最强大的方法,除非您希望进入CoreText(也称为Apple Pages实现)的世界。 - Léo Natan
@LeoNatan 是的,确实如此。但是,由于您必须添加一个 xmlns 命名空间,我们发现当我们获取 innerHTML 时,它会将该属性添加到所有块元素中。因此,我们不确定如何解决这个奇怪的问题。 - Nic Hubbard
@NicHubbard 你是将它添加到最顶部的 html 标签还是特定的元素中? - Léo Natan
@LeoNatan xmlns 属性位于 html 元素上。如果没有它,就不是有效的 XHTML,WebView 将显示一个大错误。 - Nic Hubbard
你如何在webview中管理光标位置?例如,如果你想将光标聚焦在<body>的开头。 - ebi
显示剩余6条评论

3

我在一个项目中需要将NSAtttributedString转换为HTML。实现这个功能的代码如下:

//self.attributed String is the attributedString 
NSDictionary *documentAttributes = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [self.attributedString dataFromRange:NSMakeRange(0, self.attributedString.length) documentAttributes:documentAttributes error:NULL];
NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
NSLog(@"%@", htmlString);

这种方法的限制已经在问题中提到,即它跳过了img标签。我测试了一下,在9.0版本中img标签被跳过了,但在iOS 10中可以正常工作。 - SHN
好的,我很高兴它适用于iOS 10。抱歉它不适用于iOS 9。 - Md. Ibrahim Hassan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接