How to resolve a type mismatch

I am trying to get this simple function below working. I've tried sever of things to get this right and just can't come up with anything that works. I also tried asking on the Apple Developers forum but no resolution there. Can anyone tell me how to resolve this or a better way to code this? When I try to assign rowsFetched I get a type mismatched? rowsFetched ("type NSArray") custlist ("type Customers") and obviously not a match, but they both are swift arrays... can fool swift type matching!
Thanks
I have the following function:

func getAllCustomers() -> NSArray {
var rowsFetched: NSArray
do {
try dbQueue.read { db in

  •      let custlist = try Customers.fetchAll(db)*
    

* ```
       rowsFetched = custlist* ---->>> gets a type mismatch
      }
   }

} catch {
print("(error)")
}
return(rowsFetched)
}

After trying a few more things I can see this would be very difficult to answer from the code above. So, maybe this will help:

import Foundation
import GRDB

struct Customers {
    var id: Int64?
    var CustNumber: String?
    var CustName: String?
    var CustAddr: String?
    var CustCity: String?
    var CustState: String?
    var CustZip: String?
    var CustMobile: String?
    var CustEmail: String?
    var CustNotes: String?
    var CustAdded: Date?
   }

extension Customers: Codable, FetchableRecord, MutablePersistableRecord {

    mutating func didInsert(with rowID: Int64, for column: String?) {
        id = rowID
    }
}
extension Customers {

        private enum Columns {
            static let id = Column(CodingKeys.id)
            static let CustName = Column(CodingKeys.CustName)
            static let CustAddr = Column(CodingKeys.CustAddr)
            static let CustCity = Column(CodingKeys.CustCity)
            static let CustZip = Column(CodingKeys.CustZip)
            static let CustMobile = Column(CodingKeys.CustMobile)
            static let CustEmail = Column(CodingKeys.CustEmail)
            static let CustNotes = Column(CodingKeys.CustNotes)
            static let CustAdded = Column(CodingKeys.CustAdded)
        }

//    static func drafts() -> QueryInterfaceRequest<Customers> {
 //        return Customers.filter(Columns.isDraft == true)
 //       }

    }

Let me state assumptions before I make any conclusions (at the bottom)

Assumption 1:

The below code fails:

func getAllCustomers() -> NSArray {
    var rowsFetched: NSArray
    do {
        try dbQueue.read { db in
            let customersList = try Customers.fetchAll(db)
            rowsFetched = customersList
        }
    }
    catch {
        print("\(error)")
    }
}

Assumption 2:

You are using this method: GRDB.swift/DatabaseValueConvertible.swift at b9bb5147099c4bfa75e296668fa4f234af9075a5 · groue/GRDB.swift · GitHub

Conclusion:

If my assumptions are correct, then you issue is that customers is not of NSArray but [Customers] from the type signature in the GRDB function. So you would either need to change rowsFetched to type [Customers] or cast Customers.fetchAll(db) like so

rowsFetched = customersList as NSArray

Thanks for the reply. Yes your assumptions are correct.. I changed it to the following:

func getAllCustomers() -> Customers {
var rowsFetched = try Customers.?????? --- Don't know what goes here
do {
try dbQueue.read { db in
let custlist = try Customers.fetchAll(db)
rowsFetched = custlist

        }
        
        //          let oneDraft = try Project.drafts().fetchOne(db)
        //          let tenDrafts = try Project.drafts().limit(10).fetchAll(db)
        //          let draftsCount = try Project.drafts().fetchCount(db)
    }
} catch {
    print("\(error)")
}
return(rowsFetched)

This gets rid of the type mismatch but I don't know what to put for question marks above. This appears to be on the right track...

I think you still want Customers.fetchAll(db) but you will want to cast is using as NSArray. For example

struct User {
    let name: String
    let email: String

    static func allUsers() -> [User] {
        return [
            User(name: "Abc Def", email: "abc.def@example.com"),
            User(name: "Ghi Jkl", email: "ghi.jkl@example.com"),
            User(name: "Mno Pqr", email: "mno.pqr@example.com")
        ]
    }
}

let usersList = User.allUsers() // 1
let usersNSArray = User.allUsers() as NSArray // 2

The for 1, usersList has type [User] and usersNSArray has type NSArray.

So in your case (using inference and type-safety)

var rowsFetched: [Customers]
// other code
rowsFetched = try Customers.fetchAll(db)

or

var rowsFetched: NSArray
// other code
rowsFetched = (try Customers.fetchAll(db)) as NSArray

Atfelix makes perfect sense. With a little tweaking I got it going. I added an custInit like your allUsers function and used it to initialize rowsFetched.

Thanks for the help. :grinning: