我有一个与完成处理程序的异步调用,该处理程序通过查询为我获取数据。这些查询可能因用户操作而异。
我的数据调用如下所示;
class DataManager {
func requestVideoData(query: QueryOn<VideoModel>, completion: @escaping (([VideoModel]?, UInt?, Error?) -> Void)) {
client.fetchMappedEntries(matching: query) { (result: Result<MappedArrayResponse<FRVideoModel>>) in
completion(videos, arrayLenght, nil)
}
}
}
我的视图控制器看起来像这样;
DataManager().requestVideoData(query: /*One of the queries below*/) { videos, arrayLength, error in
//Use the data fetched based on the query that has been entered
}
我的查询如下所示;
let latestVideosQuery = QueryOn<FRVideoModel>().limit(to: 50)
try! latestVideosQuery.order(by: Ordering(sys: .createdAt, inReverse: true))
而这个;
let countryQuery = QueryOn<FRVideoModel>()
.where(valueAtKeyPath: "fields.country.sys.contentType.sys.id", .equals("country"))
.where(valueAtKeyPath: "fields.country.fields.countryTitle", .includes(["France"]))
.limit(to: 50)
但我不完全确定如何以正确的方式实现这些查询,以便它们与 MVC 模型相对应。
我正在考虑在DataManager类中使用一个switch语句,并将一个值传递给ViewController上的查询参数,这将导致对fetchMappedEntries((的正确调用。唯一的问题是我仍然需要根据我在 VC 中的查询执行正确的函数,所以我也需要在那里有一个 switch 语句。
还是我需要将所有查询都包含在我的视图控制器中?我认为这是不正确的,因为它似乎应该在我的模型中。
这有点主观。我认为您希望将查询的构造放在您的DataManager
而不是视图控制器中是正确的。
一种方法是将请求接口静音,这样视图控制器只需要传递一个简单的请求,比如:
struct QueryParams {
let limit: Int?
let country: String?
}
然后,您需要更改DataManager
查询函数以改为采用以下内容:
func requestVideoData(query: QueryParams, completion: @escaping (([VideoModel]?, UInt?, Error?) -> Void))
同样,这是主观的,因此您必须确定权衡。简化界面限制了它的灵活性,但它也简化了视图控制器必须知道的内容。
我采用了一个稍微修改的网络层和一个路由器,其中查询存储在公共枚举中,然后我可以在ViewController中的函数中使用它。看起来像这样;
public enum Api {
case latestVideos(limit: UInt)
case countryVideos(countries: [String], limit: UInt)
}
extension Api:Query {
var query: QueryOn<VideoModel> {
switch self {
case .latestVideos(let limit):
let latestVideosQuery = QueryOn<VideoModel>().limit(to: limit)
try! latestVideosQuery.order(by: Ordering(sys: .createdAt, inReverse: true))
return latestVideosQuery
case .countryVideos(let countries, let limit):
let countryQuery = QueryOn<VideoModel>()
.where(valueAtKeyPath: "fields.country.sys.contentType.sys.id", .equals("country"))
.where(valueAtKeyPath: "fields.country.fields.countryTitle", .includes(countries))
.limit(to: limit)
return countryQuery
}
}
}
以及用于获取数据的网络管理器结构;
struct NetworkManager {
private let router = Router<Api>()
func fetchLatestVideos(limit: UInt, completion: @escaping(_ videos: [VideoModel]?, _ arrayLength: UInt?,_ error: Error?) -> Void) {
router.requestVideoData(.latestVideos(limit: limit)) { (videos, arrayLength, error) in
if error != nil {
completion(nil, nil, error)
} else {
completion(videos, arrayLength, nil)
}
}
}
}