Home > Blockchain >  Returning Array from Function (Swift)
Returning Array from Function (Swift)

Time:12-01

This is my first question so please, be gentle!

I've been debugging my code and searching stackexchange.com for a while, and as best as I can tell, my problem has to do with return an array from a function. I can assure you that this is not a homework question, and I've tried going through Stackoverflow for solutions, and I'm at my wits end!

The ActiveModelResponseList is used to display a list of acceptable responses to the user, arranged in a List form:

struct ActiveModelResponseList: View {  
    var activeModel: ActiveModel  
    var body: some View {  
        List(activeModel.validResponses()) {  /* XCode error: "Cannot convert value of type  
                                                             '[ValidResponse]' to expected  
                                                             argument type 'Range<Int>'" */  
  
            HStack {  /* XCode error: "Contextual closure type '() -> TupleView<(Text, Text, Spacer)>'
                                      expects 0 arguments, but 1 was used in closure body" */  
                Text($0.response)  
                Text($0.narrative)  
                Spacer()  
            }.padding(10)  
        }  
    }  
}  

I have tried a number of different ways to restructure the above body, and it's specifically that activeModel.validResponses() that causes the errors. If I delete it and populate the list with hard coded values, it works just fine.

That function, activeModel.validResponses() comes from the ActiveModel class, as follows:

class ActiveModel {
    var baseModel: ModelData
    private var responses: [Int]
    private var activeElement: Int
    
    // Although forThisElement is unused in the base function, ActiveModel still has  
    // such an element, used for other purposes  
  
    public func validResponses() -> [ValidResponse] {
        return (baseModel.validResponses(forThisElement: activeElement))
    }  
}

This, in turn, comes from a base class, ModelData. Note that forThisElement is not actually required for this function, but is included to maintain polymorphism (i.e. other models will use it). As you can see, ModelData.validResponses returns a [ValidResponse]

class ModelData: Hashable, Codable, Identifiable {  
    var id: Int  
    var valid_response: [String]  
    var valid_response_narrative: [String]  
  
    public func validResponses(forThisElement: Int) -> [ValidResponse] {  
        // forThisElement is currently an unused input variable,  
        // but is required for compatibility with other classes

        var thisResult: [ValidResponse] = []  

        for thisResponse in 0..<valid_response.count {  
            thisResult[thisResponse].id = thisResponse  
            thisResult[thisResponse].response = valid_response[thisResponse]  
            thisResult[thisResponse].narrative = valid_response_narrative[thisResponse]  
        }  
        return thisResult  
    }  
}

The ValidResponse is just an ordinary struct, defined as follows:

struct ValidResponse: Identifiable, Hashable {
    var id: Int = 0  
    var response: String = "0"  
    var narrative: String = "Default"  
}  

The preview is being generated for an iPod touch (7th generation), I'm using Xcode Version 13.1 (13A1030d), and am compiling using MacOS 12.0.1, on a mid-2015 MacBook Pro.

I found the following answers on stackexchange, but I feel none the wiser after having read them (and, as these answers are quite dated, I wonder if they're still relevant):

Can anyone provide any guidance?

CodePudding user response:

The first error message is nonsense. Fix the second and it will disappear.

The title of your question is unrelated to your actual problem, which is that you're trying to use a positional parameter from an outer closure. That doesn't work; they can't propagate that way. Every new closure scope gets its own set of positional parameters, and HStack.init doesn't use any, as the error tells you.

Fix: name the argument.

List(activeModel.validResponses()) { response in
  HStack {
    Text(response.response)
    Text(response.narrative)

CodePudding user response:

@Jessy, to clarify, I tried making the following change, but it too didn't work:

struct ActiveModelResponseList: View {
    var activeModel: ActiveModel
    var validResponses: [ValidResponse] = []
    var body: some View {
        let someResp = activeModel.validResponses()
        List {
            Text("\(someResp.count)")
        }
    }
}

But, alas, it still doesn't work! It crashes on that let line.

  • Related