Reputation: 308
I have following extension for NSAttributedString:
extension NSAttributedString {
func toHtmlString() -> String {
let documentAttributes: [NSAttributedString.DocumentAttributeKey : Any] = [NSAttributedString.DocumentAttributeKey.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue]
do {
let htmlData = try self.data(from: NSMakeRange(0, self.length), documentAttributes: documentAttributes)
if let htmlString = String(data:htmlData, encoding:String.Encoding.utf8) {
print(htmlString)
return htmlString
}
} catch {}
return ""
}
func toData() -> Data {
if #available(iOS 11.0, *) {
let data = try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
if data != nil {
return data!
}
}
return NSKeyedArchiver.archivedData(withRootObject: self)
}
static func fromData(_ data: Data) -> NSAttributedString? {
if #available(iOS 11.0, *) {
let attribute = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSAttributedString.self, from: data)
if attribute != nil {
return attribute!
}
}
return NSKeyedUnarchiver.unarchiveObject(with: data) as? NSAttributedString
}
}
The toData()
and fromData(_)
are saving/restoring NSAttributedString as Data to the file.
The toHtmlString()
is just for testing.
It works very well before iOS 13, but after upgrade to iOS 13. Some font-families not long be able to archive/unarchive it as Data (Somehow lost those font-families in Data)
let data = textViewContent.attributedText.toData()
if let a = NSAttributedString.fromData(data) {
print("----------------\n\(a.toHtmlString())\n--------------------------\n")
print("++++++++++++++++\n\(textViewContent.attributedText.toHtmlString())\n+++++++++++++++++++++++++")
}
The above print log as following:
----------------
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Times New Roman'; color: #747474}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px '.AppleSystemUIFont'; color: #747474; min-height: 19.1px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px '.AppleSystemUIFont'; color: #747474}
span.s1 {font-family: 'Times New Roman'; font-weight: normal; font-style: normal; font-size: 16.00px}
span.s2 {font-family: '.SFUI-Light'; font-weight: normal; font-style: normal; font-size: 16.00px}
span.s3 {font-family: '.SFUI-Semibold'; font-weight: bold; font-style: normal; font-size: 16.00px}
</style>
</head>
<body>
<p class="p1"><span class="s1">这样可以接受我自己选一套</span></p>
<p class="p2"><span class="s2"></span><br></p>
<p class="p1"><span class="s1">是否还在家</span></p>
<p class="p2"><span class="s2"></span><br></p>
<p class="p3"><span class="s2">Thank the developer app<span class="Apple-converted-space"> </span></span></p>
<p class="p2"><span class="s2"></span><br></p>
<p class="p3"><span class="s3">I guess we can just go<span class="Apple-converted-space"> </span></span></p>
</body>
</html>
--------------------------
+++++++++++++++++++++++++++
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px '.AppleSimplifiedChineseFont'; color: #747474}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px '.AppleSystemUIFont'; color: #747474; min-height: 19.1px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px '.AppleSystemUIFont'; color: #747474}
span.s1 {font-family: '.PingFangSC-Medium'; font-weight: bold; font-style: normal; font-size: 16.00px}
span.s2 {font-family: '.SFUI-Light'; font-weight: normal; font-style: normal; font-size: 16.00px}
span.s3 {font-family: '.PingFangSC-Light'; font-weight: normal; font-style: normal; font-size: 16.00px}
span.s4 {font-family: '.SFUI-Semibold'; font-weight: bold; font-style: normal; font-size: 16.00px}
</style>
</head>
<body>
<p class="p1"><span class="s1">这样可以接受我自己选一套</span></p>
<p class="p2"><span class="s2"></span><br></p>
<p class="p1"><span class="s3">是否还在家</span></p>
<p class="p2"><span class="s2"></span><br></p>
<p class="p3"><span class="s2">Thank the developer app<span class="Apple-converted-space"> </span></span></p>
<p class="p2"><span class="s2"></span><br></p>
<p class="p3"><span class="s4">I guess we can just go<span class="Apple-converted-space"> </span></span></p>
</body>
</html>
+++++++++++++++++++++++++++++++++++++
After NSAttributedString archived to data and then unarchived from Data, only SFUI-Light
and SFUI-Semibold
font family exist, Lost PingFangSC-Medium
and PingFangSC-Light
font families. And a new font Times New Roman
has been added by the system.
But PingFangSC-Medium
and PingFangSC-Light
do exist on UITextView's attributedString. (See the log above in the ++++
quote)
//The new font added by the system
span.s1 {font-family: 'Times New Roman'; font-weight: normal; font-style: normal; font-size: 16.00px}
//Those fonts lost after archived and unarchived
span.s1 {font-family: '.PingFangSC-Medium'; font-weight: bold; font-style: normal; font-size: 16.00px}
span.s3 {font-family: '.PingFangSC-Light'; font-weight: normal; font-style: normal; font-size: 16.00px}
The issue only exist on iOS 13 released version (not beta version, iOS 13.1.2 to be specific).
Works fine before iOS 12 and iOS 12
Upvotes: 2
Views: 1027
Reputation: 21
Yes, the problem is with iOS 13: it doesn't recognize the class name!
Before using NSKeyedUnarchiver unarchiveObjectWithFile, call this function Swift 4:
NSKeyedUnarchiver.setClass(ClassName.self, forClassName: "ProjectName.ClassName")
Upvotes: 2