iOS 13 NSAttributedString NSKeyedArchiver.archivedData丢失的属性

问题描述 投票:1回答:1

我对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
    }
}

[toData()fromData(_)正在将NSAttributedString作为数据保存/恢复到文件。

toHtmlString()仅用于测试。

[它在iOS 13之前运行良好,但是在升级到iOS 13之后,有些字体家族不久就不能将其存档/取消存档为Data(以某种方式丢失了Data中的那些字体家族)

let data = textViewContent.attributedText.toData()
if let a = NSAttributedString.fromData(data) {
    print("----------------\n\(a.toHtmlString())\n--------------------------\n")
    print("++++++++++++++++\n\(textViewContent.attributedText.toHtmlString())\n+++++++++++++++++++++++++")
}

以上打印日志如下:

----------------
<!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>

+++++++++++++++++++++++++++++++++++++

将NSAttributedString存档到数据中然后从数据中取消存档后,仅存在SFUI-LightSFUI-Semibold字体系列,丢失了PingFangSC-MediumPingFangSC-Light字体系列。并且系统已经添加了新字体Times New Roman

但是PingFangSC-MediumPingFangSC-Light确实存在于UITextView的attributedString上。 (请参见上面的++++引用中的日志)

//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}

此问题仅在iOS 13发行版(不是beta版,具体来说是iOS 13.1.2)上存在。

[在iOS 12和iOS 12之前可以正常工作

ios swift nsattributedstring ios13 nskeyedarchiver
1个回答
-1
投票

是的,问题出在iOS 13上:它无法识别类名!在使用NSKeyedUnarchiver unarchiveObjectWithFile之前,请调用此函数Swift 4

NSKeyedUnarchiver.setClass(ClassName.self, forClassName: "ProjectName.ClassName")
© www.soinside.com 2019 - 2024. All rights reserved.