【问题标题】:Using parameters on async call in swift在 swift 中使用异步调用参数
【发布时间】:2018-10-01 05:27:48
【问题描述】:

我正在使用完成处理程序进行异步调用,该处理程序通过查询为我获取数据。这些查询可能因用户操作而异。

我的数据调用如下所示;

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

我的 ViewController 是这样的;

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 语句。

或者我需要在我的 ViewController 中包含我的所有查询吗?我认为这是不正确的,因为它似乎应该在我的模型中。

【问题讨论】:

  • 就我个人而言,我认为你应该让这个工作正常进行,不要再担心“正确的方法,以便它们与 MVC 模型相对应”,无论这意味着什么。

标签: ios swift tvos contentful


【解决方案1】:

最后,我使用了一个稍微修改的网络层和一个路由器,其中查询存储在一个公共枚举中,然后我可以在我的 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
        }
    }
}

以及获取数据的 NetworkManager 结构体;

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

【讨论】:

    【解决方案2】:

    这有点主观。我认为您希望将查询的构造放在您的 DataManager 而不是您的视图控制器中是正确的。

    一种方法是简化请求接口,让视图控制器只需要传递一个简单的请求,比如:

    struct QueryParams {
        let limit: Int?
        let country: String?
    }
    

    然后您需要更改您的 DataManager 查询函数来代替它:

    func requestVideoData(query: QueryParams, completion: @escaping (([VideoModel]?, UInt?, Error?) -> Void))
    

    同样,这是主观的,因此您必须确定权衡取舍。简化界面限制了它的灵活性,但它也简化了视图控制器必须知道的内容。

    【讨论】:

      猜你喜欢
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2022-08-20
      • 1970-01-01
      相关资源
      最近更新 更多