簡體   English   中英

返回字符串並將其顯示在 NSTextField 中(SwiftUI / macOS App)

[英]Return String and display it in NSTextField (SwiftUI / macOS App)

我有以下問題:我想制作一個顯示有關太陽信息的應用程序。 我已經設法在控制台中打印日出,但這不是最終目標。 我想在 NSTextField 中顯示它。 這就是它開始出現問題的地方。

我試圖在private func getData()中添加self.sunrise1.stringValue = sunrise 顯然這不起作用,Xcode 告訴我,

NSControl.stringValue 只能在主線程中使用

所以現在我想我必須返回sunrise變量。 但是當我添加return(sunrise) Xcode 時顯示錯誤:

意外的非空返回錯誤

所以我的問題是,如何在 label stringValue中顯示sunrise的字符串sunrise1

class ViewController: NSViewController {
    
    @IBOutlet weak var sunrise1: NSTextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url = "https://api.sunrise-sunset.org/json?lat=36.7201600&lng=-4.4203400"
        getData(from: url)
        

        // Do any additional setup after loading the view.
    }
    
    private func getData(from url: String) {
        
        let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: {data, response, error in
            
            guard let data = data, error == nil else {
                print("something went wrong")
                return
            }
            
            var result: Response?
            do {
                result = try JSONDecoder().decode(Response.self, from: data)
            }
            catch {
                print("failed to convert \(error.localizedDescription)")
            }
            
            guard let json = result else {
                return
            }
            
            let sunrise = json.results.sunrise
        
            print(sunrise)
            
        })task.resume()
    }

}

struct Response: Codable {
    let results: MyResult
    let status: String
}

struct MyResult: Codable {
    let sunrise: String
    let sunset: String
    let solar_noon: String
    let day_length: String
    let civil_twilight_begin: String
    let civil_twilight_end: String
    let nautical_twilight_begin: String
    let nautical_twilight_end: String
    let astronomical_twilight_begin: String
    let astronomical_twilight_end: String
    
}

在主隊列上進行分配,例如

DispatchQueue.main.async { [weak self] in
   self?.sunrise1.stringValue = sunrise
}

實際上,最好在你的func getData中完成,所以當它完成工作時,你將更新你的 label 完成。 作為參考,我可能會提出類似的建議:

  func getData(fromUrl url: String, completion: @escaping (String) -> ()) {
    let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data, response, error in
      guard let data = data, error == nil else {
        print("something went wrong")
        return
      }
      var result: Response?
      do {
        result = try JSONDecoder().decode(Response.self, from: data)
      }
      catch {
        print("failed to convert \(error.localizedDescription)")
      }
      guard let json = result else {
        return
      }
      let sunrise = json.results.sunrise
      completion(sunrise)
    })
    task.resume()
  }

現在您可以調用您的方法,例如,viewDidLoad() 並像這樣更新您的 label:

self.getData(fromUrl: "") { sunrise in
  DispatchQueue.main.async { [weak self] in
     self?.sunrise1.stringValue = sunrise
  }
}

要獲得更多信息,您可以了解completion block/handlers 、完成功能以及為什么我們必須在主線程中更新 UI。

但是當我添加 return(sunrise) Xcode 時顯示錯誤:“意外的非無效返回錯誤”。

如果你想讓你的 func 返回一些東西,你必須在方法簽名中聲明它,例如:

func itReturnInt() -> Int {
  return 1
}

將返回 1,它是 Int,但如果您嘗試返回其他類型,則會出現編譯錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM