How to get estimated time of arrival to multipe destinations on iOS? - ios

I have an App that has the locations of 10 different places.
Given your current location, the app should return the estimated arrival time for those 10 locations.
However, Apple has said that
Note: Directions requests made using the MKDirections API are server-based and require a network connection.
There are no request limits per app or developer ID, so well-written apps that operate correctly should experience no problems. However, throttling may occur in a poorly written app that creates an extremely large number of requests.
The problem is that they make no definition on what a well written app is. Is 10 requests bad? Is 20 requests an extremely large number?
Has any one done an app like this before to provide some guidance? If Apple does begin throttling the requests, then people will blame my app and not Apple. Some advice please..

Hi investigate class MKRoute this class contains all information you need.
This object contains
expectedTravelTime
Also you should consider LoadingThrottled
The data was not loaded because data throttling is in effect. This
error can occur if an app makes frequent requests for data over a
short period of time.
For prevent your request from bing throttled, reduce number of requests.
Try to use Completion Handlers to know if you request is finished and only after send another request or cancel previous. From my experience try to handle this request just as regular network request just be sure you are not spamming unnecessary requested to the Apple API. But this is not 100% guarantee that Apple won't throttle your requests.

Related

FCM device groups vs topics

I'm developing an iOS app that sends notifications to individual groups of users. Number of users per group will most likely be in the order of 1-7, but can exceed that and while the app generally doesn't set a limit, I hardly see it exceeding 20.
Currently I've set it up with the topics approach and it works like it should. I understand this approach is optimized for throughput rather than latency, as opposed to device groups.
Nearing completion of my app, I'm considering to change to device groups. However, I don't see many advantages, especially considering the substantial complexity that comes along with it.
Notifications at the moment is fast enough. As long as delivery time doesn't suddenly increase by a lot, it's perfectly fine at the moment.
How secure are topics compared with device groups?
The app does allow the user to use more than one device, but I don't see that happening often - realistically quite seldom. However if that were to happen, device groups would handle it better. Still, I think it's an acceptable compromise to stick with topics.
For device groups to work, I have to create a new collection server-side to manage device registration tokens and their updates, pairing with my existing data structure and implementing several http requests. I also need to query for the notification_key every time I want to send a notification, instead of sending it to the more obvious id I now use for topics.
I've read through other questions on SO, but wanted to get some fresh thoughts on this. My opinion is to stay with topics unless convinced otherwise
I'm using both of these delivery methods and yes, topics are far easier to manage but that comes at a cost of security. If your groups are public in nature then you should be fine with topics. If they're meant to handle more sensitive/private information you should probably go with device groups / individual tokens. Reason being, topics are more public facing and anyone can listen in on them, even devices not on your app.

Lowering total requests per month on parse server Swift

I am currently building an app that will run on parse server on back4app. I wanted to know if there are any tips for lowering requests. I feel like my current app setup is not taking advantage of any methods to lower requests.
For example: when i call a cloud code function is that one request even if the cloud code function has multiple queries in it? Can I use cloud code to lower requests some how?
another example : If I use parse local data store rather than constantly getting data from server can that lower requests or does it not really because you would still need to update changes later on. Or do all the changes get sent at once and count as one request.
Sorry I am very new to looking at how requests and back end pricing is measured in general. I want to make sure I can be as efficient as possible in order to get my app out without going over budget.
Take a look in this link here:
http://docs.parseplatform.org/ios/guide/#performance
Most part of the tips there are useful both for performance and number of requests.
About your questions:
1) Cloud code - each call to a cloud code function counts as a single request, no matter how many queries you do
2) Client side cache - for sure it will reduce the total amount of requests you do in the server

iOS 8 Mapkit and Location - Are there any restriction to number of requests per day?

As the title says, apple doesn't provide any explicit answer to that question. I don't want to use google api because of it's request's limitation and I wonder if MapKit in iOS 8 got any? (so far there were no such limitations, but with each release of iOS things may change).
If there's no such limits, what are the drawbacks of using MapKit in iOS8 release? Are there any cases when Google Maps API become more helpful?
Thanks in advance
https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/LocationAwarenessPG/ProvidingDirections/ProvidingDirections.html
Look for the part - Getting General-Purpose Directions Information
"There are no request limits per app or developer ID, so well-written apps that operate correctly should experience no problems. However, throttling may occur in a poorly written app that creates an extremely large number of requests"
The only limitation I'm familiar with is the reverse geocoding of coordinates via CLGeocoder which says:
Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail. When the maximum rate is exceeded, the geocoder passes an error object with the value kCLErrorNetwork to your completion handler.
Unfortunately, I've never seen this limitation quantified.
Personally, I always assumed this was a caveat to prevent people from writing code that tried to abuse the API, using it to programmatically mine the geocode database by repeatedly reverse geocoding every point on a grid, or what have you. I've never run up against this limitation in standard user interaction with a map.
As far as I know there is no limitation in Apple Maps requests. And the advantage with google maps Api is better map data.

iOS app getting throttled from local searches

I am implementing autocomplete (one search per new character added) in an app that searches for addresses, and I keep getting MKErrorDomain error 3, which is MKErrorLoadingThrottled. This error, according to Apple dev, occurs when
The data was not loaded because data throttling is in effect. This
error can occur if an app makes frequent requests for data over a
short period of time.
I know exactly how many requests are being made, one for each new charachter in the search query (just like you would expect autocomplete to work). Sure, I am a fast typer, but being able to hit the limit after just 10 or 15 requests seems absurd. Looking at the following two source references, I do not understand why I keep getting throttled.
According to Apple dev:
There are no request limits per app or developer ID, so well-written
apps that operate correctly should experience no problems. However,
throttling may occur in a poorly written app that creates an extremely
large number of requests.
and as James Howard said at a WWDC:
And the other thing I want to talk about is the Usage Limits on this
API.
So, I'm happy to announce that there's no application or developer
identifier wide usage limits.
So, if you have a app that has a lot of users and you want to do a lot
of requests, that's fine.
It'll work.
And the throttling that we do have is really just a first line of
defense against buggy apps.
So, if you put directions requests or local search requests in an
infinite loop, you've got a bug, eventually you're going to get
throttled.
But if you do something reasonable, you say oh, I'm going to just do
directions in response to user input and you know you can do a few of
those because we showed them that example.
Like we did two directions request in response to one user input,
that's fine.
But, you know if you're doing 10,000 every time the user taps on the
screen, then you're going to get throttled.
But, just keep it reasonable and you'll be fine.
Any ideas to why this is happening??
Autocompletion requires a special APIs. MapKit doesn't offer such an interface. Just firing off dozens of requests to the normal search API causes a tremendous load.
You basically have two options:
Go with Google Places. They have a dedicated Places Autocompletion API. There is even a complete library for iOS on GitHub.
Reduce the number of requests, e.g. by only sending a request if the user has paused typing for 300ms and only if no earlier request is outstanding. But that's still no guarantee that Apple won't throttle your requests.
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.
Run your app in the Time Profiler Instrument an see how many calls to that method are being made when you type.
I'm just wrote Helper on Swift to help make suggests with Apple MapKit API. It's call search request when user stop typing request. https://github.com/ArniDexian/GeocodeHelper
The usage is pretty simply:
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
})
}

NSURLConnection and multiple asynchronous requests - is it messing with the data being transmitted?

I have an NSArray of links. I want to parse through them with an online article extractor API (Clear Read), and with the result given back for each article (some HTML) I throw it into an NSString.
My problem arises from the fact that, say my array has 100 URLs in it, I loop through the array shooting each item into the API and getting back some results in JSON. This is firing like 100 NSURLConnection calls at once asynchronously.
I wasn't sure if that'd be a problem, but when I give it 100 URLs (real strings, none are nil) the data that comes back often has either empty values for the JSON keys (when they shouldn't), or the data coming back is nil. There's also a bunch of duplicates.
Should I be handling multiple asynchronous connections better than I am now? If so, how?
A couple of thoughts:
If you're doing concurrent asynchronous requests and are using asynchronous NSURLConnection, then you'll want to define your own class for this download operation to make sure that every connection keeps track of its own properties. That way, everything can be encapsulated within this class where the resulting download objects can keep track of what's downloaded, what's been parsed, etc. If you're not using asynchronous NSURLConnection (e.g. you're just using dataWithContentsOfURL), it's even easier, though you lose some of the progress updates that NSURLConnection provides and/or streaming opportunities.
For best performance, you should do concurrent requests. Having said that, you should not have more than four or five concurrent requests going to any particular server. This is an iOS imposed constraint, and especially if you have a slow network connection, you risk having connections timeout otherwise.
If you're doing preliminary testing on the simulator, you may want to make sure you try out the "network link conditioner". It's part of the "Hardware IO Tools for Xcode", available at the Downloads for Apple Developers. There are issues (such as the aforementioned timeout problems if you have too many concurrent requests going to a particular server) that only manifest themselves in slow connections.
Having said that, you also want to make sure to test your solution on a device with real world network speeds. It's easy to successfully run massively parallel tasks successfully on the simulator that are too greedy for the device. Limiting the number of concurrent sessions to five will diminish this resource problem, but it should be part of your testing strategy.
I agree with JRG-Developer, that you should look into established frameworks, such as AFNetworking. Make sure to set the maxConcurrentOperationCount for the queue of the AFHTTPClient, though, if queueing 100 plus operations.
I don't know how much data your 100 requests entail, but be forewarned that the app approval process has been known to reject apps that make extraordinary networks requests on cellular networks. What constitutes excessive cellular network activity is not explicitly stated in the app review guidelines, though Avoiding iPhone App Rejection From Apple has claimed that you should ensure that you don't exceed more than 4.5mb in 5 minutes. You can use Reachability to determine what type of network you are on and perhaps warn the user if they're on cellular (if the amount of data approaches this threshold).
Have you considered using a third party framework - such as AFNetworking - and limiting the number of asynchronous calls happening at once? Perhaps this might help / solve your problem.
In particular, you might consider creating a networking manager class that creates and manages AFHTTPClient(s), which in turn manages AFHTTPRequestOperations, for each endpoint (base URL) you hit.

Resources