Нет простого способа сделать это, но вы можете использовать магию NSAttributedString
, чтобы сделать этот процесс максимально безболезненным (следует предупредить, что этот метод также удалит все теги HTML):
let encodedString = "The Weeknd <em>‘King Of The Fall’</em>"
// encodedString should = a[0]["title"] in your case
guard let data = htmlEncodedString.data(using: .utf8) else {
return nil
}
let options: [String: Any] = [
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue
]
guard let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else {
return nil
}
let decodedString = attributedString.string // The Weeknd ‘King Of The Fall’
Не забудьте инициализировать NSAttributedString только из основного потока. Он использует некоторую магию WebKit под этим, поэтому это требование.
Вы можете создать собственное расширение String
для увеличения повторного использования:
extension String {
init?(htmlEncodedString: String) {
guard let data = htmlEncodedString.data(using: .utf8) else {
return nil
}
let options: [String: Any] = [
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue
]
guard let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else {
return nil
}
self.init(attributedString.string)
}
}
let encodedString = "The Weeknd <em>‘King Of The Fall’</em>"
let decodedString = String(htmlEncodedString: encodedString)
Может ли кто-нибудь проверить или оспорить мою наивную гипотезу?
blockquote>Необъяснимый, он будет работать без
[DataContract]
, потому что происходит то, что сериализатор просто отказывается от использования атрибутов и сериализовать его только по именам свойств. Они идентичны вашему атрибуту, поэтому вы этого не замечаете. Вы должны быть в состоянии убедиться, что, передав[DataMember]
, который пришел без правильного[DataContract]
другогоName
текста, сериализатор все равно будет использовать имя свойства и игнорировать атрибут. Эти атрибуты работают как пара. Установите оба или вернитесь к «нет».public class ClassInner { // This is ignored because no [DataContract] was found [DataMember(Name = "nonexistentProperty")] // This will still be set unobfuscated because the property name matches public string stringProperty2 { get; set; } }
Поэтому, когда вы запутываете его, имена свойств меняются. Без
[DataContract]
для начала сериализатор обратится к атрибутам и найдет только случайные комбинации букв, которые он не может сопоставить с входными данными. Следовательно, вы получитеnull
.