Reputation: 31
i don't know how to fix this error "Unable to infer complex closure return type; add explicit type to disambiguate". I tried already everythink (what i can ) and doesn't work
import SwiftUI
struct ContentView: View {
@State var content: String = "start"
var body: some View {
VStack { // Unable to infer complex closure return type; add explicit type to disambiguate
self.content = try! String(contentsOf: URL(string: "http://zyglarski.pl/swift-http-docs/tinder_list.php")!)
var contentData = self.content.data(using: .utf8)
var jsDec = JSONDecoder()
var responce = try! jsDec.decode(Candidates.self, from: contentData!)
Text(responce)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Candidates: Codable {
let candidates:[Candidate]
}
struct Candidate: Codable {
let filename: String
let name: String
let age: String
let distance: String
let match: String
}
Help, please
Upvotes: 2
Views: 2663
Reputation: 3446
As an addition for Chris' answer:
Let's look a bit at closures. A "normal" closure, we can see for instance with .map { ... }
with arrays, which applies a function on each element of the list, and returns a new list with the results, like this:
let myArray = [1, 2, 3, 4, 5]
let tenTimes = myArray.map { (element) -> (Int) in
return element * 10
}
// tenTimes is [10, 20, 30, 40, 50]
(element) -> (Int) in
means: we get a parameter and call it element
so we can use it inside the closure, and the closure's return type is Int
.
Often, we use a shorthand version for the second line of that little piece of code:
let tenTimes = myArray.map { element in
Swift can infer the return type in this case.
But since (I believe) Swift 5.1, there is a new rule: when the contents of the function/variable/closure is only one line of code, we don't need to explicitly write the word return
. So in the case above, we could also say:
tenTimes = myArray.map { element in
element * 10
}
Almost every {}
you see in SwiftUI means that you are using a closure. That last rule about the return
keyword is applied very often in SwiftUI.
But there is something else: the closures in SwiftUI are special @ViewBuilder closures. Therefore, you can put multiple Views inside another View, it's like having a function with multiple return
s in it. But when you use other code, like a let
statement, things get messed up. SwiftUI doesn't understand what you want.
Sometimes you can help it a little by using explicit return
, but often the error just moves to another place. There is a chance that, after a lot of puzzling, you would get it working, but I can assure you, it won't be beautiful code. Therefore, I would choose Chris' solution.
Edit 2021: I was naïve about "functions with multiple return statements". Something more complex is going on. This video explains what exactly: https://developer.apple.com/videos/play/wwdc2021/10253/
This may also give clarification about why putting other statements in those special closures does not work.
If you want to read more about closures, here is a link to the official documentation: https://docs.swift.org/swift-book/LanguageGuide/Closures.html. Very interesting, but a lot of information!
Upvotes: 6
Reputation: 8091
please please read a swiftui beginner tutorial, because you made a lot of beginner mistakes.
and for quick help check this out:
struct ContentView: View {
@State var content: String = "start"
@State var responce : String = ""
@State var candidates : Candidates = Candidates(candidates: [])
var body: some View {
VStack { // Unable to infer complex closure return type; add explicit type to disambiguate
Text(responce)
.onAppear() {
self.content = try! String(contentsOf: URL(string: "http://zyglarski.pl/swift-http-docs/tinder_list.php")!)
var contentData = self.content.data(using: .utf8)
var jsDec = JSONDecoder()
self.candidates = try! jsDec.decode(Candidates.self, from: contentData!)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Candidates: Codable {
let candidates:[Candidate]
}
struct Candidate: Codable{
let filename: String
let name: String
let age: String
let distance: String
let match: String
}
Upvotes: -1