12

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

数据未加载,因为数据限制生效。如果应用在短时间内频繁请求数据,则可能会发生此错误。

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

根据Apple 开发人员的说法:

每个应用程序或开发人员 ID 没有请求限制,因此编写良好且运行正常的应用程序应该不会遇到任何问题。但是,在创建大量请求的编写不佳的应用程序中可能会发生限制。

正如詹姆斯霍华德在 WWDC 上所说:

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

它会工作的。

我们所拥有的节流功能实际上只是针对有漏洞的应用程序的第一道防线。因此,如果您将路线请求或本地搜索请求置于无限循环中,您就会遇到错误,最终您会受到限制。

但是如果你做了一些合理的事情,你会说哦,我会根据用户输入来做指示,你知道你可以做其中的一些,因为我们向他们展示了那个例子。

就像我们为响应一个用户输入而发出两个方向请求一样,这很好。但是,您知道,如果您每次用户点击屏幕时都执行 10,000 次,那么您将受到限制。但是,只要保持合理,你会没事的。

关于为什么会发生这种情况的任何想法?

4

4 回答 4

12

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

你基本上有两个选择:

  1. 使用 Google 地方信息。他们有一个专用的Places Autocompletion APIGitHub 上甚至还有一个完整的 iOS 库。

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

于 2014-05-10T15:43:50.180 回答
4

MKLocalSearch is primarily intended for finding points of interest (businesses, etc.) within a map's bounds. CLGeocoder is for structured address and location lookups.

The CLGeocoder documentation specifies that CLGeocoder requests are rate limited, and the documentation provides guidance on how to be a good citizen.

Of particular note is the first item in the guidelines: "Send at most one request for any user action". This should be applied to MKLocalSearch as well - if you have multiple requests in flight at the same time, you are VERY likely to get throttled.

This is actually pretty easy to implement: Before a new MKLocalSearchRequest is sent, cancel any pending requests. This makes a lot of sense for implementing autocomplete like you describe: if the user is entering the 4th character, you probably don't need the request or response for the 3rd character.

于 2014-05-13T08:49:05.103 回答
1

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

于 2014-05-10T15:36:17.537 回答
1

我刚刚在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
        })
}
于 2015-06-06T12:11:52.987 回答