iOS 应用程序在本地搜索中受到限制

Posted

技术标签:

【中文标题】iOS 应用程序在本地搜索中受到限制【英文标题】:iOS app getting throttled from local searches 【发布时间】:2014-05-06 21:46:51 【问题描述】:

我正在一个搜索地址的应用程序中实现自动完成(每个添加的新字符一次搜索),并且我不断收到MKErrorDomain error 3,即MKErrorLoadingThrottled。这个错误,根据Apple dev,发生在

数据未加载,因为数据限制生效。这 如果应用程序通过 很短的时间。

我确切知道正在发出多少请求,搜索查询中的每个新字符都有一个请求(就像您期望自动完成功能一样)。当然,我是一个快速打字员,但仅仅 10 或 15 个请求就能够达到极限似乎很荒谬。查看以下两个源参考,我不明白为什么我一直受到限制。

根据Apple dev:

每个应用程序或开发者 ID 没有请求限制,所以写得很好 正确运行的应用程序应该没有问题。然而, 节流可能发生在编写不佳的应用程序中,该应用程序会创建一个极其 大量的请求。

詹姆斯霍华德said at a WWDC:

我想谈的另一件事是使用限制 API。 所以,我很高兴地宣布没有应用程序或开发人员 标识符范围的使用限制。 所以,如果你有一个拥有大量用户的应用程序并且你想做很多事情 请求数,没关系。

它会起作用的。

而我们所拥有的节流实际上只是第一道防线 防御有缺陷的应用程序。 因此,如果您将路线请求或本地搜索请求放在 无限循环,你有一个错误,最终你会得到 节流。

但是如果你做一些合理的事情,你会说哦,我就去做 响应用户输入的方向,你知道你可以做一些 因为我们向他们展示了那个例子。

就像我们针对一个用户输入发出两个方向请求一样, 没关系。 但是,如果每次用户点击 屏幕,那么您将受到限制。 但是,只要保持合理,你就会没事的。

对为什么会发生这种情况有任何想法吗??

【问题讨论】:

我不希望自动完成功能会这样工作。我希望有一个初始请求,然后根据进一步的输入在内存中过滤这些结果。 从您的问题中不清楚您在做什么。您是在搜索还是在进行地理编码(即将位置转换为地址,或根据地址查找位置)。 @quellish 我提到的第一件事是它搜索地址。另外,请参阅问题的标题。 MKLocalSearch 用于搜索兴趣点。企业等。地理编码正在寻找地址,或将地址转换为位置。您对“搜索地址”的描述似乎描述了地理编码而不是本地搜索。 @quellish 我不知道。我正在使用 MKLocalSearch 并删除具有企业 ID 的那些,以便仅获取地址。无论如何,我最终还是使用了 Google Places。谢谢。 【参考方案1】:

自动完成需要特殊的 API。 MapKit 不提供这样的接口。仅仅向普通搜索 API 发出几十个请求就会导致巨大的负载。

你基本上有两种选择:

    使用 Google 地方信息。他们有一个专门的Places Autocompletion API。 GitHub 上甚至还有一个完整的 ios 库。

    减少请求的数量,例如仅在用户暂停输入 300 毫秒并且仅在没有更早的请求未完成的情况下才发送请求。但这仍然不能保证 Apple 不会限制您的请求。

【讨论】:

选项 2 在我看来是合乎逻辑的,无论如何都是必须的。 最终使用了一个名为 SPGooglePlacesAutocomplete 的 Objective-C 包装器到 Google Places。效果很好! 选项 2 仍然会导致节流,至少在我的模拟器上是这样。 Mapkit 现在有developer.apple.com/documentation/mapkit/mklocalsearchcompleter iOS 9.3。很确定这是在这篇原始帖子之后介绍的【参考方案2】:

MKLocalSearch 主要用于在地图范围内查找兴趣点(企业等)。 CLGeocoder 用于结构化地址和位置查找。

CLGeocoder documentation 指定 CLGeocoder 请求 速率受限,并且文档提供了如何成为一个好公民的指导。

需要特别注意的是指南中的第一项:“对于任何用户操作,最多发送一个请求”。这也应该应用于MKLocalSearch - 如果您同时有多个请求在进行中,您很可能会受到限制。

这实际上很容易实现:在发送新的MKLocalSearchRequest 之前,取消所有待处理的请求。这对于像您描述的那样实现自动完成很有意义:如果用户正在输入第 4 个字符,您可能不需要对第 3 个字符的请求或响应。​​

【讨论】:

CLGeocoder 与 MKLocalSearch 相比也有不同的结果【参考方案3】:

在 Time Profiler Instrument 中运行您的应用,查看在您键入时对该方法进行了多少次调用。

【讨论】:

【参考方案4】:

我刚刚在 Swift 上编写了 Helper,以帮助使用 Apple MapKit API 提出建议。当用户停止输入请求时,它是呼叫搜索请求。 https://github.com/ArniDexian/GeocodeHelper

用法很简单:

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) 
    GeocodeHelper.shared.decode(searchText.trimmed(), completion:  [weak self](places) -> () in
        self?.dataSource.locations = places
        self?.tableView.reloadData()
        return
        )

【讨论】:

以上是关于iOS 应用程序在本地搜索中受到限制的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS UISearchBar 中限制搜索(基于打字速度)?

如何在 iOS 应用中更快地搜索本地数据?

在啥情况下,网络爬虫可能会受到 CPU 限制而不是 IO 限制?

本地连接受到限制或者无法连接,改过IP地址后,还是上不去网

iOS 会限制预定的本地推送通知吗?

iOS 本地通知限制是每天吗?