在 swift 中的异步调用上使用参数



我有一个与完成处理程序的异步调用,该处理程序通过查询为我获取数据。这些查询可能因用户操作而异。

我的数据调用如下所示;

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)
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新