I tried to put a print statement while debugging in a SwiftUI View.
print("landmark: \(landmark)")
In the following body:
var body: some View {
NavigationView {
List {
Toggle(isOn: $userData.showFavoritesOnly) {
Text("Favorite only")
}
ForEach(landmarkData) { landmark in
print("landmark: \(landmark)")
if !self.userData.showFavoritesOnly || landmark.isFavorite {
NavigationButton(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
And the compiler errors out:
What is the proper way to print to console in SwiftUI?
I made Landmark conform to CustomStringConvertible:
struct Landmark: Hashable, Codable, Identifiable, CustomStringConvertible {
var description: String { name+"\(id)" }
var id: Int
var name: String
.....
I still get the "String is not convertible to any" error. Should it work now?
You can easily add a print statement anywhere in a function builder by simply storing its return value in a wildcard, effectively ignoring it:
let _ = print("hi!")
No setup or other verbosity needed!
print()
doesn't?The way SwiftUI's @ViewBuilder
(and result builders in general) is that they consume any values in a closure that aren't used otherwise (e.g. if you just have 42
on its own line). The print
function returns Void
(nothing), which the builder would have to build into a view, so it fails. By instead assigning it to a variable (in this case _
, basically a variable that you can never access), the Void
is never offered to the view builder in the first place.
You could argue the builder should simply accept and ignore Void
values, but the idea is that your builder closures should not have side effects (I'd remove print
statements after finishing debugging too)—you should not rely on these closures being called at certain times.