I am writing an application for a 2g device and I am receiving memory errors. The errors are created by saving a large file to the device while searching sql libraries and displaying popups (picker view mostly).
I know this is a bit vague but I was wondering if there was a way to pause user interaction while letting the device complete processing it's data. I have tried using sleep(), and [NSThread sleepForTimeInterval: 0.5], but this all pauses the application also.
Preferably this would be called in didReceiveMemoryWarning to let the app catch up processing data while blocking user interaction.
Thanks
One option is to add an invisible (i.e. transparent) view on top of all the others. Ideally, you reduce its alpha value to make it sort of gray out the underlying user interface and display a spinner or something like that to indicate that the device is working.
Related
My application triggers the iPhone Dialer and goes to background via the App Delegate.
Somewhere in the AppDelegate.m file this is called:
- (void) applicationDidEnterBackground: (UIApplication *) application
{
[self terminate];
}
When I am finished with my external app (Dialer) the application is launched again but most of the GUI parts are unresponsive.
Does it ring a bell? How could I debug this issue? Let me know if you need more info.
To be more helpful. The application is an address book that each entry is dialable and when click the iOS app is called. During the call I want to be able to open my app to browse information
I am assuming that your main issue here is that you do not consider the effects of being suspended. Please see this question: iOS 4 resume from background
Then consider reading up on an apps state cycle, which you can find here
Among the things of importance found in this article are:
To help reduce your app’s memory footprint, the system automatically purges some data allocated on behalf of your app when your app moves to the background.
The system purges the backing store for all Core Animation layers. This effort does not remove your app’s layer objects from memory, nor does it change the current layer properties. It simply prevents the contents of those layers from appearing onscreen, which given that the app is in the background should not happen anyway.
It removes any system references to cached images. (If your app does not have a strong reference to the images, they are subsequently removed from memory.)
It removes strong references to some other system-managed data caches
In other words, the state of your application might not be the one you had when you were put in the background. The entirety of this process is too large to elaborate here, and should instead be researched through the documentation provided by Apple, which I have linked to above.
You get applicationdidEnterBackground when you go into the background, but when that happens, you're trying to quit your app completely? Better than doing that there's a info.plist key that will tell the OS not to enter the background "application does not run in back ground." That will terminate your app much more gracefully.
In one of my apps when returning from background I get a non consistent behavior:
Sometimes I get the default.png and sometimes I get a snapshot of the last screen which the app was in.
In both cases it takes the UI a good second or two to respond again.
Therefore I would rather show the default.png rather then "unresponsive UI"
Is there a way to make the app display the default.png always until the app becomes active again?
Currently the "stupid" way to do it I thought about is by displaying some Modal view with the default.png and removing it on return to foreground.
Few Clarification:
I am doing this to avoid unresponsive UI.
I am using the default.png as it looks like loading and gives a better experience then unresponsive UI
The app has to run in background.
(And to whoever asked - no it is not closed when I sometimes return and see the default.png and not the last UI state - App loading from the start has a very different path and I'm sure of that)
Thanks in advance.
This is not a correct behavior and you may experiencing a bug. Basically as long as your app is in the background, when you launch it, you should not see the default.png, unless you remove it from background (double click on home button and delete that app).
For future people interested in this you can use the fact the last view in the app is used to be displayed when the app loads back.
You can display a VC as your moving to background which will represent some loading - hence achieving the desired behavior.
I've already seen a few other apps using the same behavior in cases operations are ran when coming back into the app.
Most probably, you are taking too long (performing too many calculations) in methods such as applicationWillEnterForeground:, applicationDidBecomeActive:, etc. As a simple test, try commenting out the code in these methods and see if the problem occurs again.
Simply set in your Info.plist the property "Application doesn't run in background" to YES. The app will never go in background and when the home button is pressed it will be simply terminated. So you're back to the pre-iOS4 behavior.
Note that when you see now the default image at start-up it is simply because your app has been terminated while it was in background. This is normal especially for apps that take a lot of memory and then don't free it enough before going in the background (I think the threshold for the OS is about 18MB but I'm not sure)
Im trying to find the best way to avoid having tiny UI lockups after certain events in my app. For example here are two cases where i have come across mini-lockups:
I have a button that when pressed loads a local mp3 file (around 20-30mb) using AVAudioPlayer, calls the prepareToPlay method and then plays the audio file. The issue is that the button has the showsTouchWhenHighlighted flag set to yes and after pressing it it stays highlighted until the audio file begins playing which could take 1-3 secs.
Another similar example is using a navbar button to sort and reload the table data. There is a very short but noticeable lockup where the button remains highlighted until the table has reloaded.
Can anyone suggest a good approach to minimizing/eliminating these mini lockups? I didnt really come across any code to achieve this in any of the books/tutorials i read that dealt with tableviews and avaudioplayer. Should i be launching these actions on different threads?
thx
For number 1, your best bet is to load the item on a background thread and inform the user that you're doing so (either via a loading HUD or some other indicator). The simplest way of doing this will be to use - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;. If you're running iOS 4.0 + you may want to look into executing block callbacks and see if they will work for you.
For number 2, perform the sorting on the background thread or change your sorting method (consider using a sorted data structure rather than resorting after inserts?). reloadData should occur only on the main thread.
I'm an iPhone noob myself, but it sounds like your code is stuck doing synchronous actions, which will guarantee that your UI gets locked up until the action is done executing.
Although I don't have an explicit answer, look for asynchronous options to perform these actions as they will not lockup your UI. These are usually achieved through using threads or deferred objects. From my experience so far w/ Objective-C, most actions your program neds to take can be achieved through async actions.
I have a camera application that uses my custom overlay on the UIImagePickerController object.
I am calling the takePicture method to take a picture when the user presses a button on my overlay view. Something like:
[imagePicker takePicture];
[self showProcessingIndicator];
The processing indicator is the usual spinning wheel that shows that a picture is being taken. I notice that often the camera does not take a picture immediately after the takePicture method is called, and the processing indicator is showing.
It seems that the camera tries to adjust its focus (if it is out of focus) and then takes a picture. This is probably the right thing to do. However, I have also noticed delay in taking a picture even when the camera is focused correctly and does not change its focus. This does not happen every time, and its hard to say when exactly it happens.
My question is: is there a way to force the camera to take a picture instantly, ignoring everything else? Also, is it possible that subsequent processing (showing the indicator view, for example) is causing the camera to respond slower on occasion?
Thanks!
I have also seen this and came to the conclusion that taking a picture is a reasonably resource-hungry operation in terms of talking to the camera device, allocating/moving memory, etc. While you can tune your application to not soak up any resources while this piece is running, you can't tell MobileMail, MobileiTunes, etc, to not check for email, etc, at that precise moment.
Is there any particular iOS version or device that this happens on more than others? Taking a picture on my iPhone 3G with iOS 4.0.x took up to 30 seconds, but is much improved on iPhone 4.
The activity indicator will soak up some resources, so this may be a candidate for removal and maybe just use sound instead. Test to be sure.
Recently I've been looking to create some way of showing a user that something is being loaded. I'm sure anyone with an iPhone has seen this is apps before but what is the best way of doing it?
I started using UIProgressHUD, however it was pointed out to me that you shouldn't really use private (undocumented) API's.
I then I moved onto this which is a custom version called MBProgressHUD, however in my experience with this is wouldn't show the loading part when trying to call it not from a button and I found it very buggy (It wasn't very hard to crash the example code given by just clicking away).
I then went on to find this by James Brannan from his book, however I'm not quite sure why he claims this is the "proper way" of doing it when I've seen many apps in the past with what looks like the UIProgressHUD.
Does anyone have any ideas?
EDIT: This is pretty good...
Thanks
There is no one "best" way. Another way to do this is to simply put a UIView atop your main view's subviews, mark its userInteraction property and grey it out when needed. You could even add a UIActivityIndicator as a subview of this "foreground" UIView, starting its animation when needed. When your loading has finished, hide/stop the activity indicator and clear the foreground view's color.
If you are talking about loading over a network, one good thing to start with is to enable the status bar network activity indicator:
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
Note that you have to set it to NO when you are done! That should only be used to indicate network activity.
That's a bit subtle though, it's a great idea to have some kind of progress indicator IF you can tell exactly how long something is going to take - downloads where you know the size and count incoming bytes, or uploads where you also monitor bytes outgoing and know the total size.
If your call length is very small or the size is not really known (web service call is a great example) then some kind of overlay with a UIActivityIndicator can be very relaxing (you can also make a custom variant with a set of images added to a UIImage view to animate). The key is, that if possible it should not block the user from doing other things if possible.
Also if you have multiple things going on, you might want to add messages describing what state you are in (like, "adjusting image", "uploading image", etc).