如何解决为什么在 Swift Widget 中不能使用 URLSession
我从我的网站创建了带有温度的小部件。 在标准程序中一切正常,但在结果的 Widget 中我看到“0”(来自 var 的信息)
import Foundation
class DataProvider {
struct CurrencyJSON: Codable {
var temp : String
}
static func getTemp() -> String {
var dig : String = "0"
print ("1")
//on url this data: {temp:3.5},this is my site,i can do anything format,may be make format: 3.5 (no json)?
URLSession.shared.dataTask(with: URL(string: "http://example.com/weather.PHP")! ) {(data,response,error) in
guard let data = data else { return }
do {
let res = try JSONDecoder().decode(CurrencyJSON.self,from: data)
dig=res.temp
print ("\(dig)")
} catch let error {
print("\(error)")
}
}.resume()
return dig
}
}
在小部件上我看到“0”(来自:var dig : String =“0”),为什么?我哪里出错了?
这里是我的结构提供者:TimelineProvider:
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(),myString: "...")
}
func getSnapshot(in context: Context,completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(),myString: "...")
completion(entry)
}
func getTimeline(in context: Context,completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
print ("1")
// Generate a timeline consisting of five entries an hour apart,starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .second,value: hourOffset * 10,to: currentDate)!
let entry = SimpleEntry(date: entryDate,myString: DataProvider.getTemp())
entries.append(entry)
}
let timeline = Timeline(entries: entries,policy: .atEnd)
completion(timeline)
}
}
解决方法
URLSession.shared.dataTask
是异步,这意味着您需要另一种方式来返回数据。
为此,您可以在 getTemp
函数中提供一个完成处理程序:
static func getTemp(completion: @escaping (String) -> Void) { // add completion,don't return anything
var dig: String = "0"
URLSession.shared.dataTask(with: URL(string: "http://example.com/weather.php")!) { data,response,error in
guard let data = data else { return }
do {
let res = try JSONDecoder().decode(CurrencyJSON.self,from: data)
dig = res.temp
print("\(dig)")
} catch {
print("\(error)")
}
completion(dig) // pass the value to the completion handler
}.resume()
// return dig // don't return here
}
如您所见,getTimeline
函数还有一个完成处理程序 - 这允许您在那里执行异步函数:
func getTimeline(in context: Context,completion: @escaping (Timeline<Entry>) -> ()) {
DataProvider.getTemp { myString in
var entries: [SimpleEntry] = []
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .second,value: hourOffset * 10,to: currentDate)!
let entry = SimpleEntry(date: entryDate,myString: myString)
entries.append(entry)
}
let timeline = Timeline(entries: entries,policy: .atEnd)
completion(timeline)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。