I've been looking at some very great online services iPhone app, such as the Twitter app. It's very robust, I can't crash the app no matter what I do.
When I try to build one, I always get crashes whenever there's something wrong, like no internet, wrong passwords, etc. Especially I notice that my app crashes when I switch between tab bars too quickly (when one of them is waiting for a response from the Twitter server, for example). How do I elevate this issue?
Is there any tips to build apps that never crashes like Twitter for iPhone?
Crashes tend to happen because of one of two reasons:
You're referencing a deallocated object
You have exceeded the amount of memory that you are permitted to use, either due to leaks, not lazy loading, or just an overall bad design.
As far as Internet connections go, this StackOverflow question has your bases covered there.
It's hard to say why making fast tab bar switches are causing your app to crash without code.
I have written such an app (a shopping app that uses the network for everything). Here are some tips:
Implement reachability so you know when the network is there (and keep checking it)
Run all network access asynchronously so the app does not freeze, thread networking when you can.
Send and receive the smallest amount of data per request. For example, in my shopping app, I only get 50 products per search, with only the SKU, description and price. Use JSON.
Round trip - request network data - as infrequently as possible, and at most once per screen. If you can do with the data you have in memory, do so.
Lazy load images
Cancel all network connections as soon as possible. As soon as the tab changes, kill any outstanding network access.
Cache, cache, cache. Its always quicker to get data locally.
Hope this helps.
One big differentiator between great network apps and terrible network apps is handling network latency. I can't stand apps where the UI stalls or becomes jerky when data is requested from the network, or where the entire interface is frequently locked up with an activity indicator. I tend to quit and uninstall these types of apps right away. Sometimes it is not entirely obvious how to allow the user to continue interacting with the app when some data is required from the network, but the hallmark of great design is that you think about these issues ahead of time. Really, those lengthy stalling activity indicators are a big "fail!" in my book.
I'm writing a network-data-heavy app myself, and implementing a really simple URL image cache singleton class and a "lazy" subclass of UIImageView that loads images in the background using an NSOperationQueue was really pretty simple, and the app runs smooth as glass :).
Related
Our apps are live on the app store.
I wish to recognise crashes of out of memory that some users are getting.
I understand there is no way to 100% recognise an out of memory crash.
Is there any way to recognise these crashes(with a pretty large probability) by doing some logic in the applicationDidReceiveMemoryWarning? (I am not talking about finding it in xcode during development time, i am talking about code that will recognise the out of memory crash from actual users and will log something to file)
While I was looking for any service or library that give me OOM tracking, I could only find this article from Facebook engineering:
https://code.facebook.com/posts/1146930688654547/reducing-fooms-in-the-facebook-ios-app/
The idea is to deduce the reason why the app needs to be launch, checking different aspects (like if the app was at background, if there is an app/OS update,...).
Discarding all the other possible reason that can force the previous app exit, you can know if the reason is a background out of memory or a foreground out of memory.
It would be nice to have a library that implements the Facebook article procedure. But nowadays I couldn't find any, probably there is some reason that make this difficult or may be impossible to add it as an sdk.
If anyone knows any service, please share it with everyone with a comment or a new answer.
Edit:
I have discovered this github (https://github.com/jflinter/JRFMemoryNoodler) with an implementation of the Facebook post procedure. I haven't tried yet, but we will deploy it in our apps to try it.
Look out for the applicationWillTerminate message in your app delegate. This is called if you app is terminated by the system (due to e.g. low memory), but not if the user leaves the app in the usual way by pressing the home key. Note: if your app is in the background and memory runs out, your app gets killed without any messages being sent to it.
YMMV, especially with older versions of iOS, and it's worth researching to ensure that the above is accurate.
The images at this blog post are quite informative (although slightly dated).
For more info, see How to know whether app is terminated by user or iOS (after 10min background)
Firstly Analyse your application by clicking on the Product at the top menu bar of your Xcode and click on Analyse section it will show you the number of leaks on in the application and can take you to the place where leaks occurred. This is how you can find the memory leak and rectify it.
Secondly it above does not worked then see to the view controller where crash occurred and check whether you have left any object to release.
Hope this might help you to resolve your problem.
I am developing an application which does a lot of API fetching and it happens, if the internet connection is very low, say 5 kbps the app crashes in the main method.
I think it happens when a lot of requests are in the queue so the OS terminates the app.
I am using ASIHTPPRequest and asynchronous block-based requests.
How can I solve the problem?
You would need to use a Single network queue for the whole app. Apps that depend heavily on Internet connectivity should optimize the number of concurrent network operations. Unfortunately, ASIHTPPRequest framework does not do this. I would suggest you use MKNetworkKit which has been built especially keeping mobile apps in mind.
Most mobile networks (3G) don’t allow more than two concurrent HTTP
connections from a given IP address. Edge is even worse. You can’t, in
most cases, open more than one connection. This limit is considerably
high (six) on a traditional home broadband (Wifi). On any normal case,
the iDevice is mostly connected to a 3G network, which means, you are
restricted to upload only two photos in parallel. Now, it is not the
slow upload speed that hurts.
The real problem arises when you open a
view that loads thumbnails of photos (say on a different view) while
this uploading operations are running in the background. When you
don’t properly control the queue size across the app, your thumbnail
loading operations will just timeout which is not really the right way
to do it. The right way to do this is to prioritize your thumbnail
loading operation or wait till the upload is complete and the load
thumbnails. This requires you to have a single queue across the entire
app. MKNetworkKit ensures this automatically by using a single shared
queue for every instance of it. While MKNetworkKit is not a singleton
by itself, the shared queue is.
source
My team is developing an iPhone app which is very demanding in terms of memory. In order for a better user experience we are thinking of presenting a pop-up to the user upon startup stating the memory requirements and also a pop-up upon low memory.
Has anyone had a problem with such a solution, in terms of being rejected from the app store?
Thanks
It's simple, don't show any UIAlertView in a memory warning.
The user is not responsible to manage the memory for you. You need to take actions in memory pressure by releasing caches or other less important information.
iOS itself will release memory and kill other apps when it's needed.
To answer your question, I don't know if Apple reject apps for that reason, but they repeated more then once to not to do so.
IMHO, on iOS systems, specifying the memory requirements to the user is not relevant. Most smartphone users won't know the available memory and don't want to be bother by technical aspects. To be successful, your app need to be robust and that also means memory adaptive.
As far as i remember you can ask the system to give you the amount of free memory. Try to manage your memory consumption using it. There are many strategies. Common ones are to ask it periodically or ask it lazily only when you are going to load big data.
When you receive memory warning, try to reduce your memory footprint the more you can
I'm not sure anyone can say anything sensible about whether this behavior will be acceptable in the app store. I've never heard of an app trying it.
Philosophically, it seems counter to the HIG. Memory management is your job, not the user's. You could maybe give them some "usage information" on first launch asking them to close backgrounded apps when using this one, but putting a memory alert in front of the user just feels inappropriate.
Apple might not be happy with an alert, but possibly some kind of subtle ui graph showing available memory abstractly would be ok, and probably a nicer experience as the user could see how what they were doing affects memory.
I can't seem to find this anywhere, but I'm sure there must be an answer...
How many simultaneous HTTP connections can an iphone app service? In other words, if I build and run a bunch of NSURLConnections asynchronously, how many can be in flight before it starts queuing them?
Also, is there a method to check how many threads are available and/or in use programmatically?
I'm trying to write an intelligent pre-fetching engine, and these limits (if any) would be useful information.
The iPhone doesn't start queuing NSURConnections. That's totally your responsibility. The iPhone will start all your asynchronous NSURLConnections in parallel. The only thing that will stop it is your memory :) I recently implemented a connection pool (my solution was based on NSOperationQueue) just because of that. Now I can control parallel connections and my app doesn't crash when loading hundreds of avatar images.
About your second question. I actually don't know about a way to get the list of current threads. I had a look at NSThread API but no sign of an API for that..
So the reason I assumed there may be a simultaneous connection limit at the mobile OS level is because many mobile browsers enforce one. There are techniques for speeding up loading speed of the mobile version of your website by ensuring that there are as few additional content fetches as possible. Images are the main culprit, but css files, javascript files, etc all require an additional connection.
In mobile, setting up and tearing down a connection is much more expensive than a single connection with more data, and one technique for improving page load performance is embedding your CSS and javascript in the page itself.
It sounds like this limitation may not exist in the OS itself, at least on the iphone platform.
As far as an answer to this question, I found this post that discusses the practical limitations of simultaneous connections. It's not a hard limit, but I think it answers the point of the question.
Background threads consuming 100% CPU on iPhone 3GS causes latent main thread
I'm currently testing the latest iOS4 Feature to put my location aware app in the background. Well, it does work! But on the other hand it's quite hart to handle the immense power usage.
The app consumed about 50% battery power in the last four hours. It read the entire official documentation by Apple on this topic but I'm still not sure which parts of my application are still running and which functionality is suspended (beside the UI Drawing, which should be clear).
I don't use any real boilerplate code but extended libraries like ASIHTTPRequest to talk to my webservice. Tests with a friends car did you show that the Network Connectivity and and the Location Services is still running when I'm using i.e.
[locationManager startMonitoringSignificantLocationChanges];
Apples Documentation on the different application states
Background: The application is in the background and executing code
[...]
Should I write a "bare metal" functions to receive and send this location data? Should I remove all other objects for the time the application resides in the background to reduce the memory footprint? It seems there isn't any best practice yet.
Any ideas? Maybe you guys can provide me with some of your insights. Thanks.
Edit:
There's a new Instruments tool called Energy Diagnostics Instruments to record any power usage (for iPhone 3GS and later) with an attached device. Also there's another service on the device in the Settings App -> Developer -> Power Usage. It's great to test your power usage in field. The created logs can be pulled later in instruments.
Reference: WWDC 2010 Session 309 - Advanced Performance Analysis with Instruments
Sounds like your app is transmitting location data over the cellular network. Turning on the cellular radio is one of the most rapid causes of power drain, especially if the user has a weak signal connection to the cell tower.
You might want to save and package up a bunch of location data, and send the data in a quick burst as seldom as possible (twice per day, when the user stops moving for 30 minutes, only after the user gets to one of their favorite restaurants, etc.) Turning on the radio less than half as often could get you close to doubling the battery life (unless the user is doing something else with the device as well).