I wrote and use THIS CLASS to create small snapshot images of MKMapView
with a custom annotation, and set them inside an UIImageView
in a UITableViewCell
. I wrote it in such a manner, to invoke and forget, without worrying too much about memory consumption.
How it works:
I have a dictionary with relevant values of a place (name, latitude, longitude, etc) [source is FourSquare API].
I then request CellMapFactory
(see Gist) to create an image for the location and set it inside an image view from a subclassed UITableViewCell
like this:
CellMapFactory* cellMapFactory = [[CellMapFactory alloc] init];
[cellMapFactory createCellMapForPlace:[self.cellData objectForKey:@"checkin"] inImageView:mapImageView];//mapImageView is a `UIImageView`.
CellMapFactory then uses MKMapSnapshotOptions
, MKMapSnapshotter
, and a custom annotation to create this image, and set it inside the referenced image view, on successful completion.
Also, on successful completion, I manually cache the image to disk using SDWebImageManager
, so that next time a screenshot of the same location is requested, it is fetched from SDWebImage
disk cache, instead of redoing the whole process.
The Problem
The process of map creation, and setting the completed image to the image view is absolutely fine. However, when more than 1 cell in the table need to plot these different snapshots, each cell creates a new instance of CellMapFactory
, which in turn adds a new MKMapView
to the app window, for each snapshot requested. This adds insanely to the memory usage.
Desired Solution
I would like CellMapFactory
to create these snapshots serially. For instance if 20 cells in my table need 20 unique snapshots, CellMapFactory
must process them in a serial manner (queue?), and create one snapshot at a time, using the same MKMapView
. The way I see it (maybe I'm wrong), this will help in limiting the memory consumption greatly.
Here's a sample screenshot, just for the record:
Any help (and variations of the desired solution) will be greatly appreciated. Thanks.
How about creating a snapshot interface which your cells can use to request a snapshot. For when the snapshot is not available, it provides a mechanism for you to schedule the snapshot creation and register a delegate or completion block it can call back on to receive the created image.
If you do this within each cell you could provide a place holder image which will update to the proper image as they become available.
In the implementation simply queue up the requests which should allow you to do them one at a time. As they complete, cache and fire the completion delegate/block. Not sure how much you can run in the background for this task? Potentially you could run a number of threads which would let you control how many MKMapViews are used and thus balance memory with performance.