is It possible to refactor code little bit ?
saroar opened this issue · 7 comments
can we add some func for each request
now you have this
return performRequest(route: APIRouter.login(email: email, password: password))
}
static func userArticles(userID: Int) -> Future<[Article]> {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: APIRouter.articles(userId: userID), decoder: jsonDecoder)
}
static func getArticle(articleID: Int) -> Future<Article> {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: APIRouter.article(id: articleID), decoder: jsonDecoder)
}
so each model we have to create this typ of func but if you can create something like this with Generic
func get<T>{...}
func post<T>{...}
func put<T>{...}
func delete<T>{...}
func performRequest {...}
here some example code
https://gist.github.com/saroar/fc5fbd0c2ac4901904ab01ad3ac20048
i am trying to do something like this
static func get<T>(ID: String, route: APIRouter) -> Future<T> {
let jsonDecoder = JSONDecoder()
// jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: route, decoder: jsonDecoder)
}
``` but getting error
`Cannot convert return expression of type 'Future<_>' to return type 'Future<T>'`
To make the code compile you need to add the Decodable
constraint to T
like that:
static func get<T:Decodable>(ID: String, route: APIRouter) -> Future<T> {
return performRequest(route: route, decoder: JSONDecoder())
}
so is it a good idea? @AladinWay need your advice thanks and what you think?
@saroar It depends on your use case, there is always a room for improvement. But I think that the networking layer approach of the tutorial already encapsulate the method of the request in the router so I don't see the benefits of having separate methods to perform the request. This does not mean that it's not a good idea, but for my uses cases I didn't need to have another layer of abstraction.
so is it good practice for creating func like below for each model?
static func login(email: String, password: String) -> Future<User> {
return performRequest(route: APIRouter.login(email: email, password: password))
}
static func userArticles(userID: Int) -> Future<[Article]> {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: APIRouter.articles(userId: userID), decoder: jsonDecoder)
}
static func getArticle(articleID: Int) -> Future<Article> {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(.articleDateFormatter)
return performRequest(route: APIRouter.article(id: articleID), decoder: jsonDecoder)
}
where we can use this for anykind of model
func post<T>{...}
func put<T>{...}
func delete<T>{...}``` without duplication or create any new func
i think i cant use like this
static func post<D:Decodable>(route: APIRouter) -> Future<D> {
return performRequest(route: route)
}
func createHevent() {
APIClient.post(route: APIRouter.person(
id: nil, firstName: "babal", lastName: "balba", phoneNumbers: nil)).execute(onSuccess: { response in
print("respoonse", response)
}) { error in
print("error", error)
}
}
error is getting this error
Extra argument 'onSuccess' in call`
Looks like that execute
function doesn’t want your onSuccess
argument. Check the method definition for execute