Я работаю над приложением, которое будет извлекать сообщения из WordPress и позволит пользователю просматривать каждое сообщение отдельно, подробно. WordPress API возвращает содержимое сообщения, которое является HTML-кодом сообщения. (Примечание: теги img ссылаются на URL-адрес WordPress загруженного изображения)
Изначально я использовал WebView и загружал извлеченный контент прямо в него. Это сработало отлично; однако изображения, казалось, загружались в основной поток, поскольку это вызывало задержку и иногда приводило к зависанию пользовательского интерфейса до завершения загрузки изображения. Мне предложили проверить библиотеку Aztec Editor из WordPress; Однако я не мог понять, как его использовать (не мог найти много документации).
Мой текущий маршрут - анализ содержимого HTML и создание списка словарей (ключи типа [изображение или текст] и содержимое). После анализа я создаю сообщение, динамически добавляя представления «Метки» и «Изображения» (что позволяет загружать изображения в фоновом режиме). Хотя это кажется чрезмерно сложным и, вероятно, неправильным маршрутом, он работает хорошо (хотя он будет открыт для любых других решений!). В настоящее время моей единственной проблемой является задержка преобразования строки HTML в NSAttributedText. Перед добавлением текстового содержимого в словарь я преобразую его из строки в NSAttributedString. Я заметил задержку в несколько секунд, и процессор симулятора в течение нескольких секунд поднялся до 50-60%, а затем упал. Есть ли в любом случае я мог бы сделать это преобразование в фоновом потоке (ы) и отображать анимацию загрузки в течение этого времени?
Пожалуйста, дайте мне знать, если у вас есть идеи или предложения для лучшего решения. Большое спасибо!
Код:
let postCache = NSCache<NSString, AnyObject>()
var yPos = CGFloat(20)
let screenWidth = UIScreen.main.bounds.width
...
func parsePost() -> [[String:Any]]? {
if let postFromCache = postCache.object(forKey: postToView.id as NSString) as? [[String:Any]] {
return postFromCache
} else {
var content = [[String:Any]]()
do {
let doc: Document = try SwiftSoup.parse(postToView.postContent)
if let elements = try doc.body()?.children() {
for elem in elements {
if(elem.hasText()) {
do {
let html = try elem.html()
if let validHtmlString = html.htmlToAttributedString {
content.append(["text" : validHtmlString])
}
}
} else {
let imageElements = try elem.getElementsByTag("img")
if(imageElements.size() > 0) {
for image in imageElements {
var imageDictionary = [String:Any]()
let width = (image.getAttributes()?.get(key: "width"))!
let height = (image.getAttributes()?.get(key: "height"))!
let ratio = CGFloat(Float(height)!/Float(width)!)
imageDictionary["ratio"] = ratio
imageDictionary["image"] = (image.getAttributes()?.get(key: "src"))!
content.append(imageDictionary)
}
}
}
}
}
} catch {
print("error")
}
if(content.count > 0) {
postCache.setObject(content as AnyObject, forKey: postToView.id as NSString)
}
return content
}
}
func buildUi(content: [[String:Any]]) {
for dict in content {
if let attributedText = dict["text"] as? NSAttributedString {
let labelToAdd = UILabel()
labelToAdd.attributedText = attributedText
labelToAdd.numberOfLines = 0
labelToAdd.frame = CGRect(x:0, y:yPos, width: 200, height: 0)
labelToAdd.sizeToFit()
yPos += labelToAdd.frame.height + 5
self.scrollView.addSubview(labelToAdd)
} else if let imageName = dict["image"] as? String {
let ratio = dict["ratio"] as! CGFloat
let imageToAdd = UIImageView()
let url = URL(string: imageName)
Nuke.loadImage(with: url!, into: imageToAdd)
imageToAdd.frame = CGRect(x:0, y:yPos, width: screenWidth, height: screenWidth*ratio)
yPos += imageToAdd.frame.height + 5
self.scrollView.addSubview(imageToAdd)
}
}
self.scrollView.contentSize = CGSize(width: self.scrollView.contentSize.width, height: yPos)
}
extension String {
var htmlToAttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return NSAttributedString() }
do {
return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
return NSAttributedString()
}
}
var htmlToString: String {
return htmlToAttributedString?.string ?? ""
}
}
(Простите за не очень чистый код! Я просто хочу убедиться, что смогу достичь желаемого результата, прежде чем начать рефакторинг. Еще раз спасибо!)