FeedListKit
FeedListKit is a high level framework for representing data from an Api inside a SwiftUi
List
. It automatically handles refreshing and loading more on scroll.
How to use
Create the Api
First, you need to create an api which conforms to the Api
protocol. FeedListKit automatically sends a page
parameter to your api, you need to handle paging directly in your api.
FeedListKit works great with NetworkKit:
class MyApi: Api {
static func fetchRows<T>(_ urlString: String, parameters: [String : String]?, type: T.Type) async -> [T]? where T : Model {
do {
return try await NKHttp.getObjectArray(urlString, parameters: parameters, type: type)
} catch {
return nil
}
}
static func fetchRows<T>(_ urlString: String, parameters: [String : String]?, type: T.Type, callback: @escaping ([T]?) -> ()) where T : Model {
NKHttp.getObjectArray(urlString, parameters: parameters, type: type, callback: callback)
}
}
But you can also fetch the data on your own:
class MyApi: Api {
static func fetchRows<T>(_ urlString: String, parameters: [String : String]?, type: T.Type) async -> [T]? where T : Model {
// Fetch your data and return the object array asynchronously.
// You can use URLSession or some other http library.
}
static func fetchRows<T>(_ urlString: String, parameters: [String : String]?, type: T.Type, callback: @escaping ([T]?) -> ()) where T : Model {
// Fetch your data and return the object array with callback.
// You can use URLSession or some other http library.
}
}
Create a model for your data
The model needs to conform to the Model
protocol.
struct Animal: Model {
var id: String
var name: String
}
Create a FeedNetworking
Create your first FeedNetworking
and pass your object Model
and your Api
type.
class MyAnimalFeedNetworking: FeedNetworking<Animal, MyApi> {
// The url to your api endpoint
override var apiUrl: String {
"http://mydomain.com/api/animals"
}
// Your parameters
override var httpParameters: [String : String] {
[
"myKey": myValue
]
}
}
Use FeedList
struct MyAnimals: View {
init() {
self._feedNetworking = StateObject(wrappedValue: MyAnimalFeedNetworking())
}
@StateObject private var feedNetworking: MyAnimalFeedNetworking
var body: some View {
FeedList(feedNetworking: feedNetworking, row: { animal in
Text(animal.wrappedValue.name)
}, loadingView: {
Text("Fetching animals ...")
}, noDataView: {
Text("No Animals found! :(")
})
.task {
await feedNetworking.fetch()
}
}
}