find duration and latency of a native iOS mobile application - ios

I am trying to find out the duration and if it is possible the latency of a network call to an iOS native application. I already found the instruments tool and tried out different templates without success :(
To be more specific i want to get the duration of a call that is send over a glassfish server which runs on my local machine. The call sends a json object.
I hope you guys can help me?
Thanks

I think you can use NSURLConnectionDelegate method here, if you are using NSURLConnection to send the request to your server.
When you set up the request, you can use
CFAbsoluteTime before = CFAbsoluteTimeGetCurrent();
to get the exact time when you initiated the request.
Use Delegate method
connection:didReceiveResponse:
and inside it
CFAbsoluteTime after= CFAbsoluteTimeGetCurrent();
difference between after and before will give the exact duration.
Also use, connectionDidFinishLoading:
if you want to get the time when you have completely loaded the JSON response.

Related

Load data from server quickly iOS

I am working on a shopping app where I use web services to fetch data i.e. product list etc. But it takes too much time to load and thus makes my app really slow.
Is there any solution to this problem?
below is the code I've tried to get Product List.
NSURL * Url=[NSURL URLWithString:#"URL/api/product"];
NSData * Data=[NSData dataWithContentsOfURL:Url];
NSString *str=[[NSString alloc]initWithData:Data encoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[strinng dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
cannot put JSON response because it's too much.
There is no RIGHT or WRONG way way for this. But there are some points which we can consider for fast data loading. I can mention these points and there can be many other points as well:
Use AFNetworking (for objective c) or Alamofire (for swift), for calling web services and getting response.
Don't do too much things in viewDidLoad. Try to do as less as operations.
You can call web service in viewDidLoad or in viewWillAppear(it will get called every time you visit screen)
After getting response update UI on main thread. Refer this post.
If you want to show images from URL's, load it asynchronously. You can use third party library like SDWebImage Or else use extensions provided in AFNetworking and Alamofire
If you want to show list of products in list, use Load More functionality. for this purpose your API's should be smart enough which are implemented using pagination.
Use UITableView or UICollectionView for showing reusable components.
Till now I can highlight these points. If I found anything else, I will update my answer.
It will be better if you show what you did for that, but according to your requirement i will suggest you,
Use AFNetworking to communicate with server, it is little bit faster.
if you send request to server in new ViewController, make sure you are going to send request in viewWillAppear.
Try to avoid get too much data at the same time.
Try to use Asynchronous request means that it will not wait. You use Asynchronous means that it will not wait. means the thread that initiated that operation will wait for the task to finish before continuing.
Just use NSURLSession. It is good API from Apple. Just remember to use dispatch grand central get mainQueue in the completion block to update any UI.
Start loading the data from API when the App Launches (AppDelegate)and store the response data in a model. This way the time lag would be reduced. Also you can try saving the response into CoreData and when the view is loaded you can refresh the data.
Hope this helps.
Nothing can be done on your side to speed up the process when the data you receive is in abundant.
You should split your APIs, probably, one API will give you the list
of products.
Make an API in way to send only request number of products and the
number of products should be based on your phone screen resolution
and number of products that can be shown there. For example, it
could be 4 on iPhone 4 whereas 6 on iPhone 6. On scrolling call that API again to receive another 4 or 6 products.
On clicking a particular product, use another API to get its
contents.

Does iOS SDK keeps the connection alive between Cloud Code Function calls?

I'm implementing an autocomplete functionallity in a mobile app. I plan to have an autocomplete function on Parse Cloud Code but I'm afraid of the latency/delay that could bring up.
Specifically I would like to know how is calling parse Cloud Functions compared to do calls to a regular webserver over a WebSocket connection.
NOTE: I see the iOS SDK call to Parse functions uses NSURLSession which will leverage KeepAlive by default. What I don't know if the server copes up with that.
Cloud functions can be done both sync and async however they are very stingy about how long the connection stays open. In other-words you'd have to separate api calls. So, your answer is no.
Also, I might mention this from their guide on iOS cloud code calls
There is a limit of 8 concurrent httpRequests per Cloud Code request, and additional requests will be queued up.
This means that even if you somehow forced the connection to stay open like a WebSocket...you couldn't have more than 8 people using that view/cloud function at a time or everyone else wouldn't be able to access the function.
However, Ive dealt with this myself and you have a few options....
1)Make your own SocketIO server that make rest requests to parses cloud code functions. Theres even a iOS SDK from SocketIO now. So this is a pretty easy option.
2)Accept that youll have a pretty high API call rate and keep making it.
3)Do what I did and Call all the objects you need at the beginning and have iOS perform the autocomplete on the fly. Heres a helpful search on cocoa controls that should give you a head start to get it handled check it out here. Any one of these would save you hours of time of trying to sort through and repopulate yourself. If you have a lot of objects you need to get. Remember if you are returning more than 100 results(the default return amount) set query.limit = 1000(max return limit).

Fire and forget URL download for iOS

Problem
I'm currently grabbing weather forecast information with [NSData dataWithContentsOfURL: url]. The problem with this is that if there are errors during the URL fetch, I just get back a nil.
An alternative to the method [NSData dataWithContentsOfURL:options:error:] will provide error info to me, but what my calling function wants is the data, not a possible error that it must diagnose and deal with.
Requirements
What I'd like is a single function that a client can call to grab a URL that "absolutely will not stop" until the URL has been loaded.
I don't want the function's clients to need to think about:
Timeouts.
Internet connections being unavailable or not.
The device being locked or the app moving in to the background.
The actual site in question being down.
Other sources of error.
Other design objectives
The function should treat the device and remote site nicely – it should not swamp it with requests resends that will certainly fail, for example.
The caller should be able to abort the attempt if it desires, so it'll want to have a handle to the request allowing it to kill it off.
The function should be asynchronous, taking a block to handle the result when it eventually arrives.
For extra marks a method for the calling function to be sent error diagnostics would be nice. Again, I think a block would work nicely for this. The needn't do anything about the error, because the function isn't going to give up, but it can use it to provide useful feedback to a user. For example, to allay their concerns, or prompt them to take remedial action (turn networking back on, for example).
Possible interface
So the a client call to the function might go like this:
_currentGrabber = [TenaciousURLGrabber
grabberForURL: myURL
withCompletionAndDiagnosticsHandler:
^(NSData* finalData, ErrorObject *error){
if(data)
{
// Update my UI using data.
}
else
{
// Update my UI to show `[error localisedError];`
}
}];
If the client gets bored or decides that the fetch isn't worth it any more, it can do:
[_currentGrabber invalidate];
Implementation thoughts.
It'd be great if this pretty much already exists. Otherwise, I'm interested in suggestions on implementing this functionality.
I should probably be making use of NSURLSession instead of the older NSURLConnection. The possibility of background (out of process) downloads looks useful? Any tips beyond this?
The function should use SCNetworkReachability as demonstrated in the Reachability sample application following failure to determine when its worth a retry attempt.

How can I run a method in an exception handler?

I have an exception handler that runs when my code crashes, but I also need to send a msg to the server (parse.com) when this happens to let the server know the player has stopped playing,
void onUncaughtException(NSException *exception)
{
NSLog(#"uncaught exception: %#", exception.description);
[self playerLoggedOut];
}
The playerloggedOut line gives the error of undeclared identifier self.
How can I run the playerLoggedOut method when the exception happens?
How can I run the playerLoggedOut method when the exception happens?
You're not going to be able to start some lengthy process like establishing a network connection and sending a message. Your best strategy might be to save the information and send it when the app starts up again so that the server can update its records or whatever. Alternatively, have the client check in with the server every t seconds; if the server doesn't hear from the client within some interval like 2t, it assumes that the client has stopped functioning.
First of all: self is unknown, because you are not in a method, but a function. Functions do not run in an object context, therefore do not know self.
As mentioned before by Caleb, you should have a watch dog on server-side that automatically logs a player out, if the server gets no messages from the client for a while (in terms of seconds). To prevent from being logged out automatically, when the user is deactive (but still playing), you can implement a heart beat on the client using an instance of NSTimer.
As others have stated, don't try to do expensive things like talk to the Parse server in your exception handler.
In regards to what you are actually trying to achieve, you might want to re-think your architecture.
In the sometimes-connected world of mobile devices you will have your connection come and go. Instead of a boolean flag of IsLoggedIn, consider a UTC Date Time of LastUserActivity, and use a rule that says they are considered logged in if that last activity is in the last 5 minutes, or whatever is suitable.
If all access to Parse is done via Cloud Code then you could easily add a function call that sets the LastUserActivity to each method, then you can also avoid issues with time sync since you'll always be using the server's clock.
If you want to get a list of all online users, you can then just query for where LastUserActivity is greater than 5 minutes ago (or whatever limit you set).

withContentsofURL possible to declare a timeout limit?

I have an app with dynamic data and the update method uses arrayWithContentsofURL and dictionaryWithContentsofURL to get the plists from a server in order to update my database.
My problem:
When there is no or not correctly working internet connection on the device this request simply tries to get the data for about a minute before it stops trying and continues execution.
Is there a way to maybe set a timeout for this function?
PS: I know this is probably the worst way to do this and I would be happy if someone could point me in the right direction :) I'm quite new to iOS programming so please be patient.
In my opinion it's best to use an NSMutableURLRequest with it.
Which has a - (void)setTimeoutInterval method. From the documentation:
The timeout interval, in seconds. If during a connection attempt the
request remains idle for longer than the timeout interval, the request
is considered to have timed out. The default timeout interval is 60
seconds.
Suggest you use an NSURLRequest to send the Request object. Its delegate functions will return you the plist.
You could take this example, about half way on that page it downloads a json object very much the same way as you could fetch a plist.

Resources