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
* ```
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)
// }
}
atfelix
(Adam Felix)
3
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...
atfelix
(Adam Felix)
5
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. 