我正在尝试调用一个我从API中提取数据的函数。该函数在var body: some View
部分之前创建,并在其中调用。函数本身或其他任何地方都没有编译器错误。在我开始使用SwiftUI之前,我对这种类型的功能没有任何疑问,并且代码几乎完全相同。这是包含JSON数据的Struct函数的代码;
var postDetailsData = postDetails.self
var commentsArray = comments.self
struct postDetails: Decodable {
let count: Int?
var results: [results]
}
struct results: Decodable {
var id: String
let author: author?
let anonym: Bool
let subscribed: Bool
let created: String
let active: Bool
let text: String
let image: String?
let comments: [comments]
}
struct author: Decodable {
let user: Int
var name: String
let avatar: String?
let banned: Bool
}
struct comments: Decodable, Identifiable {
let id: Int
let text: String
let author: authorOfComment?
}
struct authorOfComment: Decodable {
let name: String
let avatar: String?
}
//And now the actual function
let tokenData = UserDefaults.standard.object(forKey: "savedToken")
var spread = Bool()
let request = NSMutableURLRequest(url: NSURL(string: "http://localhost:8000/areas/sample/")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
func pullData(){
let headers = [
"Authorization": "token \(tokenData ?? "nope")",
"cache-control": "no-cache",
"Postman-Token": "53853353-f547-410a-b289-e3c4ced8e426"
]
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
}
guard let data = data else {return}
do{
let JSONFromServer = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(JSONFromServer)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let postDetailsDataArray = try decoder.decode(postDetails.self, from: data)
print(postDetailsDataArray.results)
for results in postDetailsDataArray.results{
DispatchQueue.main.async {
//Account Pic Post and Other Stuff In The HStack
let accountPicAndStuff = HStack {
Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/) {
ImageWithActivityIndicator(imageURL: results.author?.avatar ?? "")
.frame(width: 30, height: 30)
.clipShape(Circle())
.offset(x: -75, y: 0)
}
Text(results.author?.name ?? "Annon")
.offset(x: -75)
Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/) {
Image("BookMark").offset(x: 70)
}
Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/) {
Image("more-vertical").offset(x: 70)
}
}.offset(y: 65)
//accountPicAndStuff.offset(y: 65)
//Description code (pulls data from api)
var postTextTest = results.text
Text(results.text)
//.padding(.bottom, 0)
.offset(y: 10)
.lineLimit(4)
//Image From Post Stuff
if results.image == nil{
print("no image")
}else{
ImageWithActivityIndicator(imageURL: results.image ?? "")
.offset(y: 50)
.scaledToFit()
}
//Date and time for post
Text(results.created)
.font(.footnote)
.fontWeight(.light)
.foregroundColor(Color.gray)
.multilineTextAlignment(.leading)
.offset(x: -85, y: 50)
for comments in results.comments{
print(comments)
//Comment View Code using Lists
List(results.comments){ comments in
HStack{
ImageWithActivityIndicator(imageURL: comments.author?.avatar ?? "")
.frame(width: 100.0, height: 100.0)
}
}
}
}
}
}catch{
print("Failed to decode:", error)
}
})
dataTask.resume()
}
这就是我调用函数的方式;
struct FunAreaSmall: View {
//Code from above goes here...
var body: some View {
//Smaller UI
VStack {
pullData()
HStack {
Button(action:{}) {
Image("SkipBtn")
.offset(y: 60)
.scaledToFit()
}
Button(action: {}) {
Image("IgniteBtn")
.offset(y: 60)
.scaledToFit()
}
}
}
}
}
错误本身
'Int'不能转换为'CGFloat'
出现在HStack的第一个按钮上的.offset(y: 60)
上,我知道这不是问题,因为当我注释掉对该函数的调用时,错误消失了。我尝试了各种方法来解决此错误,但我得到的只是更多错误。我试图在Google上查找错误,但没有任何帮助。
感谢您的帮助!
答案 0 :(得分:1)
您不能仅将函数调用放在ViewBuilder
中,因为它不能解析不透明的返回类型。
根据您的需求,有几种可能的解决方案:
1)将pullData
的呼叫放在init()
中
2)在ViewBuilder
中提供明确的回报(全部)
3)调用如下所示的闭包(似乎在该用例中最合适):</ p>
struct FunAreaSmall: View {
//Code from above goes here...
var body: some View {
//Smaller UI
VStack {
HStack {
Button(action:{}) {
Image("SkipBtn")
.offset(y: 60)
.scaledToFit()
}
Button(action: {}) {
Image("IgniteBtn")
.offset(y: 60)
.scaledToFit()
}
}
}
.onAppear() {
self.pullData()
}
}
}