我無法使用在 youtube 上找到的代碼抓取影像 HTML 鏈接(https://www.youtube.com/watch?v=0jTyKu9DGm8&list=PLYjXqILgs9uPwYlmSrIkNj2O3dwPCcoBK&index=2)。該代碼在操場上運行良好,但我在 Xcode 專案中的實作存在問題。(更像:我不確定如何將它實施到我的專案中:))
當我在 Playground 上運行此代碼時,它會完全按照我需要輸出的方式提取我需要的鏈接。
import Foundation
let url = URL(string: "https://guide.michelin.com/th/en/bangkok-
region/bangkok/restaurant/somtum-khun-kan")
let task = URLSession.shared.dataTask(with: url!) { (data, resp, error) in
guard let data = data else {
print("data was nil")
return
}
guard let htmlString = String(data: data, encoding: String.Encoding.utf8) else {
print("can not cast data into string")
return
}
let leftSideOfTheString = """
image":"
"""
let rightSideOfTheString = """
","@type
"""
guard let leftRange = htmlString.range(of: leftSideOfTheString) else {
print("can not find left range of string")
return
}
guard let rightRange = htmlString.range(of: rightSideOfTheString) else {
print("can not find right range of string")
return
}
let rangeOfValue = leftRange.upperBound..<rightRange.lowerBound
print(htmlString[rangeOfValue])
}
task.resume()
然后,我將完全相同的代碼放入包含代碼作為引數和方法的結構中,如下所示:
struct ImageLink {
let url = URL(string: "https://guide.michelin.com/th/en/bangkok-region/bangkok/restaurant/somtum-khun-kan")
func getImageLink() {
let task = URLSession.shared.dataTask(with: url!) { (data, resp, error) in
guard let data = data else {
print("data was nil")
return
}
guard let htmlString = String(data: data, encoding: String.Encoding.utf8) else {
print("can not cast data into string")
return
}
let leftSideOfTheString = """
image":"
"""
let rightSideOfTheString = """
","@type
"""
guard let leftRange = htmlString.range(of: leftSideOfTheString) else {
print("can not find left range of string")
return
}
guard let rightRange = htmlString.range(of: rightSideOfTheString) else {
print("can not find right range of string")
return
}
let rangeOfValue = leftRange.upperBound..<rightRange.lowerBound
print(htmlString[rangeOfValue])
}
task.resume()
}
}
最后,為了檢查代碼是否會給我正確的鏈接,我在視圖中創建了一個實體,并制作了一個按鈕,列印getImageLink()函式,如下所示。您將在注釋掉的代碼中看到我嘗試通過硬編碼其鏈接和插入函式呼叫來顯示影像。前者按預期作業,后者沒有作業。
import SwiftUI
struct WebPictures: View {
var imageLink = ImageLink()
var body: some View {
VStack {
//AsyncImage(url: URL(string: "\(imageLink.getImageLink())"))
//AsyncImage(url: URL(string: "https://axwwgrkdco.cloudimg.io/v7/__gmpics__/c8735576e7d24c09b45a4f5d56f739ba?width=1000"))
Button {
print(imageLink.getImageLink())
} label: {
Text("Print Html")
}
}
}
}
當我單擊按鈕列印鏈接時,我收到以下訊息:
()
2022-05-16 17:21:30.030264 0800 MichelinRestaurants[35477:925525] [boringssl]
boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
https://axwwgrkdco.cloudimg.io/v7/__gmpics__/c8735576e7d24c09b45a4f5d56f739ba?width=1000
如果我第二次單擊該按鈕,則只會列印該按鈕:
()
https://axwwgrkdco.cloudimg.io/v7/__gmpics__/c8735576e7d24c09b45a4f5d56f739ba?width=1000
如果有人知道如何在這里幫助我,將不勝感激!
uj5u.com熱心網友回復:
這失敗了,因為您沒有等到您的 func 拉出鏈接。您在這里處于異步背景關系中。一種可能的解決方案:
//Make a class in instead of a struct and inherit from ObservableObject
class ImageLink: ObservableObject {
let url = URL(string: "https://guide.michelin.com/th/en/bangkok-region/bangkok/restaurant/somtum-khun-kan")
//Create a published var for your view to get notified when the value changes
@Published var imageUrlString: String = ""
func getImageLink() {
let task = URLSession.shared.dataTask(with: url!) { (data, resp, error) in
guard let data = data else {
print("data was nil")
return
}
guard let htmlString = String(data: data, encoding: String.Encoding.utf8) else {
print("can not cast data into string")
return
}
let leftSideOfTheString = """
image":"
"""
let rightSideOfTheString = """
","@type
"""
guard let leftRange = htmlString.range(of: leftSideOfTheString) else {
print("can not find left range of string")
return
}
guard let rightRange = htmlString.range(of: rightSideOfTheString) else {
print("can not find right range of string")
return
}
let rangeOfValue = leftRange.upperBound..<rightRange.lowerBound
print(htmlString[rangeOfValue])
//Assign the scrapped link to the var
imageUrlString = htmlString[rangeOfValue]
}
task.resume()
}
}
和觀點:
struct WebPictures: View {
//Observe changes from your imagelink class
@StateObject var imageLink = ImageLink()
var body: some View {
VStack {
AsyncImage(url: URL(string: imageLink.imageUrlString)) // assign imageurl to asyncimage
//AsyncImage(url: URL(string: "https://axwwgrkdco.cloudimg.io/v7/__gmpics__/c8735576e7d24c09b45a4f5d56f739ba?width=1000"))
Button {
imageLink.getImageLink()
} label: {
Text("Print Html")
}
}
}
}
更新:
為了在視圖出現時獲取鏈接,這樣呼叫它:
VStack {
AsyncImage(url: URL(string: imageLink.imageUrlString))
}
.onAppear{
if imageLink.imageUrlString.isEmpty{
imageLink.getImageLink()
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/476591.html
標籤:迅速
上一篇:SwiftUI中的年份陣列
