【问题标题】:Swift how can I make this function async to get rid of my application warningSwift 我怎样才能使这个函数异步以摆脱我的应用程序警告
【发布时间】:2023-01-13 01:01:43
【问题描述】:
我正在使用 SwiftUI 4.0 并拥有 SwiftSoup 包。当我尝试加载网站时,我现在收到此消息(发生在任何网站上)
https://www.cnn.com 的同步 URL 加载不应发生在
此应用程序的主线程,因为它可能会导致 UI 无响应。
请切换到异步网络 API,例如 URLSession。
它专门发生在代码的这一部分
if let html = try? String(contentsOf: myURL, encoding: .utf8) {
有没有人对如何解决这个问题有建议。这是我正在使用的功能
import Foundation
import SwiftUI
import Combine
import SwiftSoup
func NewLinkRequest(_ LinkUrl: String) ->(LinkUrl: String ,LinkTitle: String ,LinkImage: String)
{
var newTitle = ""
let urlm = URL(string: LinkUrl)
guard let myURL = urlm else {
return ("","Failed to get url", "")
}
if let html = try? String(contentsOf: myURL, encoding: .utf8) {
do {
let doc: Document = try SwiftSoup.parseBodyFragment(html)
let headerTitle = try doc.title()
let firstImage = try doc.select("img").attr("src")
newTitle = headerTitle
return (LinkUrl,newTitle, firstImage)
} catch Exception.Error( _, let message) {
print("Message: \(message)")
} catch {
print("error")
}
return ("","", "")
} else {
return ("","Failed to get url", "")
}
}
【问题讨论】:
标签:
swift
swiftui
swiftsoup
【解决方案1】:
问题
发生此错误是因为 String(contentsOf: ) 是同步的,可能会导致您的 UI 挂起。相反,请使用如下所示的 URLSession。给定URL,以下函数将异步地给你String。
解决方案
func fetchFromURL(_ url: URL) async -> String{
let session = URLSession.shared
let (theStringAsData, _) = try await session.data(from: articleUrl)
if let returnableString = String(data: theStringAsData, encoding: .utf8)
{
return returnableAsString
} else {
return ""
}
}
代码分解:
-
let session 是您的应用程序的共享 URL Session - 此处的文档:URLSession.Shared
-
let (theStringAsData, _) 返回一个 Data 对象和一个 URLResponse - 此方法的文档在这里:https://developer.apple.com/documentation/foundation/urlsession/3767352-data
- 我们检查以确保此数据不为零,如果对
String 的类型转换有效,我们将返回新的String。否则,我们返回一个空的。
用法示例:
import SwiftSoup
Task{
let theString = fetchFromURL(URLHERE) //Put your URL here!
//We use a do/catch block here because SwiftSoup.parse can throw
do{
let document = try SwiftSoup.parse(theString) //This is now the parsed document if it worked
print(document)
} catch {
print("Failed to parse")
}
}