I've been working on a SwiftUI project that generates UIs based on Server responses using JSON
In order to do that I have created a FormBuilder Now I want to show various types of custom fields like TextField, DateField, TextArea all fields have
text, title, etc as common properties but will have different Validating procedures
in order to program this,
I have used a protocol name "FormField", "SectionView" struct to load fields, some structs as Fields comforting to FormField and "FieldView" struct to load different Fields.
In the FieldView protocol I'm getting following error when I try to show various Views based on the type I get via json
I Have commented the line that shows the error in FieldView class
Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
Can anyone help me to find a work around with this Any help will be so much appreciated !
FormField Protocol
protocol FormField : View {
var id : String! { get set }
var title : String? { get set }
var placeholder : String? { get set }
var text : String? { get set }
var validation : String? { get set }
var keyboardType : String? { get set }
init(json : JSON)
func validate()
func showError()
func isValid() -> Bool
}
FieldView struct
Have commented the line that shows the error
struct FieldView: View {
private let TEXT = "text"
private let TEXTAREA = "textarea"
private let RADIO = "radio"
// could have more type
let id = UUID().uuidString
private var type : String!
private let fieldJson : JSON
init(json : JSON) {
self.type = json["type"].stringValue
self.fieldJson = json
}
var body: some View {
field
}
private var field : some FormField{
// Errors Comes from above Line
if type == TEXT {
FormTextField(json: fieldJson)
}
if type == TEXTAREA {
FormTextArea(json: fieldJson)
}
if type == RADIO {
FormRadio(json: fieldJson)
}
}
func validate() {
field.validate()
}
func showError() {
field.showError()
}
func isValid() -> Bool{
return field.isValid()
}
}
FormTextField struct
struct FormTextField: FormField {
var id : String!
var title : String?
var placeholder : String?
@State var text : String?
var validation : String?
var keyboardType : String?
init(json: JSON) {
self.id = json["id"].string
self.title = json["name"].string
self.placeholder = json["placeholder"].string
self.text = json["text"].string
self.validation = json["validation"].string
self.keyboardType = json["keyboardType"].string
}
var body: some View {
Text("Text Field: \(title!)")
.font(.headline)
.padding()
.background(Color.red)
}
func validate() {
if title!.isEmpty {
print("FormTextField Error")
}
}
func showError() {
}
func isValid() -> Bool{
return title!.isEmpty && text!.isEmpty
}
}
FormTextArea struct
struct FormTextArea: FormField {
var id : String!
var title : String?
var placeholder : String?
@State var text : String?
var validation : String?
var keyboardType : String?
init(json: JSON) {
self.id = json["id"].string
self.title = json["name"].string
self.placeholder = json["placeholder"].string
self.text = json["text"].string
self.validation = json["validation"].string
self.keyboardType = json["keyboardType"].string
}
var body: some View {
Text("Text Area: \(title!)")
.font(.headline)
.padding()
.background(Color.red)
}
func validate() {
print("Form Text Area")
}
func showError() {
}
func isValid() -> Bool{
return title!.isEmpty
}
}
FormRadio and other Fields also as same as this
Following SectionView struct was used to add fields inside of a VStack
SectionView struct
struct SectionView: View {
var id = UUID().uuidString
public var title : String?
public var fields = [FieldView]()
init(json : JSON) {
self.title = json["sectionName"].string
fields = (json["fields"].array ?? []).map({return FieldView.init(json: $0)})
}
var body: some View {
VStack{
Text(title ?? "Section")
.font(.title)
ForEach(fields,id:\.id){field in
field
}
}
.padding()
}
}