When should we delete the cache data in an iPhone apps? - iphone

We often cache image and data to improve our iPhone app's performance. But what strategy do you use to manage the cache data, such as delete or update it?
I saved the images to TMP folder, but don't know when should I trigger to "checking out of date cache data and delete it": when the iPhone apps starts, or quits, or in idle time?

You should delete the cache when the iPhone invokes your "didReceiveMemoryWarning" function.

When the application launches or quits, the user is usually expecting responsiveness. Choose a minimum amount of real time, like 24 hours, and a minimum amount of idle time, like a minute. If the user has been idle for a minute and it is more than 24 hours from the last cache purge, then clean the cache. If you are keeping track of how much data is cached, then you could factor that in as well. If it has been more than 24 hours and/or there is more than a megabyte in the cache.
If you are sure the application is being quit normally, as opposed to being quit to answer a call or launch another application, then that might also be a good time.
If your application does something that the user has to wait for anyway, but that would not be affected by purging the cache, then that might also be a good time. For example, fetching some data from a server.

Appreciate for your responses.
I agree that checking for delete the cache at the start or quit time will reduce the program's performance. Moreover, quit time is also used for saving the program's state.
The idea to check for idle time in 1 min is quite ok, but I have to build mechanism to check idle for every 15 s during the application time. I don't think it's easy and good for performance.
At last, I decide to perform "check and delete cache" after I retrieve new Items (data + image). I will check for items (data +image) that doesn't need to be displayed anymore and delete it. I think it makes sense that the feature who saves the cache, will deletes the cache also.
Certainly, I will do this in another thread to avoid frozen the interface.
Is this good? Pls give me your opinions.

I personally dosn't like if cache is cleaned when i open a application or idle longer then about 1 minute. The idea cleaning if age of the cache is about 24hours is good.
My personal recommandation is to build stack of cache files. And then checking for the cache file creation/modification time or last cache file access. So clean in background (don't let become your app feel slow cause you're doing such tasks when starting or stopping an app) maybe in a thread (does iphone sdk support that? dont know :)) and check for "is cache file older then 24hrs? if yes > recache or delete file

Related

IPhone Image Caching

I want to save images fetched from a url into the NSTempDirectory(). If I store more than 100 images the application gets slow and sometimes quits. How many images can be stored in NSTempDirectory()? Would deleting the files continuously after it reaches 50 or more images be a good solution? Is there any other alternative to store images without affecting the application performance?
Clawoo is right. Check your memory management and do one more thing.
You can add your code for deleting data from temp directory inside this function: didReceiveMemoryWarning.
This function is called whenever you receive memory warning error.
If the application becomes sluggish the problem lies in your memory management implementation. Make sure you release all your objects, especially the ones that you use to download the images (NSURLConnections, NSData, UIImage, etc).
Writing all those images to disk (whether it's a temp directory or not doesn't really matter) should NOT impact your application's performance in the long term, let alone outright kill it. The application is being shut down because it most probably runs out of memory.

Data driven view iOS app

I am new to objective-c/cocoa programming. I am making an application which is to constantly sync with a server and keep its view updated.
Now in a nutshell, heres what I thought of: Initiate an NSTimer to trigger every second or two, contact the server, if there is a change, update the view. Is this a good way of doing it?
I have read elsewhere that you can have a thread running in the background which monitors the changes and updates the view. I never worked with threads before and I know they can be quite troublesome and you need a good amount of experience with memory management to get most out of them.
I have one month to get this application done. What do you guys recommend? Just use an NSTimer and do it the way I though of...or learn multithreading and get it done that way (but keep in mind my time frame).
Thanks!
I think using separate thread in this case would be too much. You need to use threads when there is some task that runs for considerable amount of time and can freeze your app for some time.
In your case do this:
Create timer and call some method (say update) every N seconds.
in update send asynchronous request to server and check for any changes.
download data using NSURLConnection delegate and parse. Note: if there is probability that you can receive a huge amount of data from server and its processing can take much time (for example parsing of 2Mb of XML data) then you do need to perform that is a separate thread.
update all listeners (appropriate view controllers for example) with processed data.
continue polling using timer.
Think about requirements. The most relevant questions, IMO, are :
does your application have to get new data while running in background?
does your application need to be responsive, that is, not sluggish when it's fetching new data?
I guess the answer to the first question is probably no. If you are updating a view depending on the data, it's only required to fetch the data when the view is visible. You cannot guarantee always fetching data in background anyway, because iOS can always just kill your application. Anyway, in your application's perspective, multithreading is not relevant to this question. Because either you are updating only in foreground or also in background, your application need no more than one thread.
Multithreading is relevant rather to the second question. If your application has to remain responsive while fetching data, then you will have to run your fetching code on a detached thread. What's more important here is, the update on the user interface (like views) must happen on the main thread again.
Learning multithreading in general is something indeed, but iOS SDK provides a lot of help. Learning how to use operation queue (I guess that's the easiest to learn, but not necessarily the easiest to use) wouldn't take many days. In a month period, you can definitely finish the job.
Again, however, think clearly why you would need multithreading.

Saving painting app data to cope with interruptions on iPhone?

I'm making an iPhone bitmap painting app. I want to support about five 1024x768 layers (~15Mb of data). My problem is that I do not know what strategy to use for saving the user's document to cope with my app being interrupted.
My document file format at the moment is to save each layer as a .png file and then save a short text file that contains the layer metadata. My problem is that, if the app is interrupted by something like a phone call, I'm unlikely going to have enough time for my app to be able to save all the data to disk as saving all the .png files can take ~10 seconds. What options do I have?
I've considered adding an autosave feature that would be called every five minutes. In the worst case, the user will lose a few minutes of work if the app fails to save on interruption (which isn't ideal).
An idea I've considered is to keep track of which layers have changed since the last autosave and only update the layer files that need to be updated. This means that, when interrupted, my app might only need to save one layer in the typical case. However, the worse case is still having to save several layers.
I'm not sure what to do. On a practical note, I've noticed many popular iPhone painting apps with good reviews will lose the current document progress if interrupted with a phone call. I'm beginning to doubt there is a way to solve this particular problem and that I might just have to go with something less than ideal.
The IOS4 SDK provides support for long-running background tasks, which would be the perfect place to save your layers. From the documentation:
You can use task completion to ensure that important but potentially long-running operations do not end abruptly when the user leaves the application. For example, you might use this technique to save user data to disk or finish downloading an important file from a network server.
Any time before it is suspended, an application can call the beginBackgroundTaskWithExpirationHandler: method to ask the system for extra time to complete some long-running task in the background. If the request is granted, and if the application goes into the background while the task is in progress, the system lets the application run for an additional amount of time instead of suspending it. (The backgroundTimeRemaining property of the UIApplication object contains the amount of time the application has to run.)
I'm not sure if this is feasible (you don't state how the user interacts with the layers, or indeed if this interaction is transparent from their perspective), but as a suggestion why not simply save the "active" layer out (via a background thread) when the user switches layers, as you'd then only need to save a single layer when your app is backgrounded.

iphone - open and close sqlite database every time I use it

I am writing an iPhone app that uses SQLite. I am use to opening and closing my connections every time I use a database. However, I do not know if that is a good practice in the iPhone/SQLite environment. I want to know if I should open the database 1 time or if it is OK to open and close the database each time I use it. Please let me know.
I believe you should keep it open as long as you can, so data is cached in DRAM. Of course, you should also organize your transactions so you commit at logical points in time and maintain transactional integrity.
I would do as Matthew suggested: keep one connection opened for as long as your program is running.
Both answers seem right, but actually it depends from how often you're using it and how large is it. In case DB is large you should set larger page cache, but that leads to larger memory consumption and if access is rare - no reason for holding it up all the time (but if usage also small - large page cache won't help you also).
In case it's small - there is no reason to open/close it each time even with infrequent usage. But in average your resource consumption is higher with regular open/close. So all in all - don't reopen db each time you're using it.

How to reduce the startup time for a typical iPhone app?

To be clear, this is for a normal iPhone application, and not a game.
I've read around the web a few times some developers mentioning that they were working hard to improve/reduce the startup time of their applications, but never with any good background information on how to do so.
So the question is simple: how can you reduce the startup of iPhone applications?
Same as any other performance issue: Use Shark and/or Instruments to identify bottlenecks in your code, and then focus on how you can speed things up there. Each tool will give you a picture of how much time was spent in what parts of your code, so the general scheme would be to run the tool while you start the app and then pore over the data to see where the performance hits occur.
At app startup time, the most likely candidates for improvement will be deferring data loading until later on when it's actually needed, variously described as "on demand" or "lazy" loading. Essentially, don't load any data at app startup unless it's actually needed right away when the app loads. In practice, lots of stuff that may be needed at some point doesn't have to be immediately available when the app starts. For example, if you have a database of N records but only one is visible at a time, don't load all N into memory at app startup time. Load whatever the current record is and then load the others when you actually need them.
James Thomson did a nice blog post documenting his efforts to make PCalc launch faster.
Of particular interest is his use of image with screenshot from last app run, to pull the same trick Default.png does, while loading rest of the app.