samtay...@googlemail.com

unread,

Jun 9, 2009, 5:45:45 PM6/9/09

to Three20

The application I am working on populates UIImages from server pushed
data objects... I don't have an URL or a local address for an image...
just images created from server messages. There is no way around this
due to the nature of the program.

I've been looking through the Three20 code and I'm having trouble
figuring out how to make the changes required so that I can supply
UIImages from the Photo Source as opposed to just Urls. It's
beginning to look like quite a large job which will affect a large
number of classes. If anyone has any advice or pointers about where
to start I would appreciate it very much!

Cheers,
Sam

klazuka

unread,

Jun 9, 2009, 9:10:06 PM6/9/09

to Three20

Well, here's a quick hack without modifying any Three20 source code.
There may be a better way, but this is the first thing that came to my
mind.

In your TTPhotoSource implementation, store each of your UIImages in
the TTURLCache under a unique, fake url.
Then in your TTPhoto implementation, set the url to that same fake
url. Vend these TTPhotos. When the TTImageView goes to load the photo,
it will first lookup the url in the cache. Since we arranged for that
image to be in the cache registered under that url, it will
synchronously display the UIImage without trying to download anything.

// cache the UIImages and store the TTPhoto in the items instance
variable
// this code assumes that you have a directory called "images" in your
app bundle
// and that there are 7 jpegs, with filenames from "1.jpg" up to
"7.jpg"
items = [[NSMutableArray alloc] init];
for (int i = 1; i < 8; i++) {
NSString *path = [NSString stringWithFormat:@"images/%d.jpg", i];
UIImage *img = [UIImage imageNamed:path];
NSString *url = [NSString stringWithFormat:@"foo://%@", path];
[[TTURLCache sharedCache] storeImage:img forURL:url];
Photo *photo = [[[Photo alloc] init] autorelease];
photo.url = url;
[items addObject:photo];
}

NOTE: you also need to disable the maxPixelCount on the TTURLCache so
that everything is kept in memory.
[[TTURLCache sharedCache] setMaxPixelCount:0]; // unlimited

NOTE: UIImage does its own caching when you use the imageNamed: method
(as I have it above in my example), so unless you really want 2 copies
of each image in memory, you should use a different UIImage
initializer.

So this definitely works, but as I said, it's a hack because we are
abusing internal knowledge of TTImageView's implementation.

-keith

samtay...@googlemail.com

unread,

Jun 9, 2009, 9:50:38 PM6/9/09

to Three20

Wow, thanks for the detailed response.

This sounds like it might be just the trick. Doesn't matter that it's
a hack because I had intended to brutalise the internals of Three20
just to get this working, so this is much cleaner and still retain the
original functionality if needed at a later date.

Thanks again. I wouldn't have thought of abusing the cache so you've
probably saved me a lot of time. I'll post my progress in the morning

Sam

João Reis

unread,

Jun 11, 2009, 12:31:55 AM6/11/09

to Three20

I also think there should be a simple way to put a collection of
UIImages there.

thanks for the reply && Happy hacking :P

On Jun 9, 8:50 pm, "samtaylor...@googlemail.com"

Hwee-Boon Yar

unread,

Jun 11, 2009, 9:47:30 PM6/11/09

to Three20

Depending on what you are doing, another way is to dump them onto
storage and construct photo sources pointing to documents://etc.

--
Hwee-Boon

klazuka

unread,

Jun 12, 2009, 12:55:14 AM6/12/09

to Three20

> Depending on what you are doing, another way is to dump them onto
> storage and construct photo sources pointing to documents://etc.

Agreed, this is the best route to take given the current situation.
It's unfortunate that you would be forced to take such a round-about
path, but such is life!

As an aside to anyone who copies-and-pastes my code from above: please
make sure that you know what you are doing when you set maxPixelCount
to 0. This will remove any limit on TTURLCache's image cache, meaning
that your memory usage will climb and climb and climb until you
manually free the memory used by the cache. This is why I'm
recommending Hwee-Boon Yar's solution: it is much less prone to
programmer error.

-keith

mehal

unread,

Jun 30, 2009, 9:34:21 PM6/30/09

to Three20

Hey guys, please pardon my ignorance (still a dangerous noob). I've
got this all working nicely on the simulator with images in the local
Documents directory. But if I want to install the app and images onto
a test iPhone device, how do I change the pointers to find the correct
images and/or Documents directory? Do I include the images into the
app bundle?

Thanks in advance, Mike

On Jun 11, 6:55 pm, klazuka <klaz...@gmail.com> wrote:
> > Depending on what you are doing, another way is to dump them onto

> > storage and construct photo sources pointing todocuments://etc.

klazuka

unread,

Jun 30, 2009, 10:56:28 PM6/30/09

to Three20

Hi Mike,

On the iPhone device there are 2 basic places on the filesystem for
your app's data:
a) the resource bundle
b) the documents directory

The resource bundle is read-only. If you add some .pngs to your Xcode
project, they will automatically be copied over into your resource
bundle and be available on the device.

The documents directory is read-write, but you have to put the data
there yourself at runtime. One common thing that Apple does for read-
write resources (e.g. databases) in their sample code is to add the
resource to their Xcode project, include it in the target's "Copy
Bundle Resources" build phase, and then in
applicationDidFinishLaunching: copy the resource out of the resource
bundle and write it into the app's documents directory. This allows
you to bundle an initial data set with your application, but still
allow your app to extend/modify the data set.

But for your case I'm going to assume that your images are static so
you should just place them in the resource bundle. Once they are in
the resource bundle, all you need to do to generate a path is to use
any one of the following techniques:
a) [[NSBundle mainBundle] pathForResource:ofType:]
b) TTPathForBundleResource()
c) @"bundle://my_image.png" as the URL argument to a Three20 object

-keith

mehal

unread,

Jun 30, 2009, 11:17:58 PM6/30/09

to Three20

Keith,

I don't know you from a hole-in-the-wall, but I've been lurking on
this forum for several weeks now trying to learn as much as I can
about Three20. I can only say that you are a class-act. I've never
seen a forum where the owner/moderator is so helpful, knowledgeable,
courteous, and just downright friendly. I don't know what you get out
of your efforts, but it's probably not enough!

If you're ever in Boston, drop me a line and I'll bye you as many
beers (or whatever suites your taste) as you can handle !!

Thanks again, Mike

klazuka

unread,

Jul 1, 2009, 12:39:24 PM7/1/09

to Three20

Hi Mike,

I'm glad that you find my postings helpful. And just to set the record
straight, I'm not the owner/moderator (Joe Hewitt created Three20).
I'm just another programmer trying to live according to St. Francis's
Prayer.

I do have a friend in Newton, MA but he lives in NYC now. For a few
years, I would visit Boston every summer--I love the museum of fine
art--but now that we have a baby (actually, he's more of a toddler now
than a baby), we just don't travel around the US as much as before.

In the last few days I have accumulated outstanding beer offers from
programmers in both Boston and the Netherlands, so perhaps I should
consider a trip out East :-)

-keith

mehal

unread,

Jul 1, 2009, 1:16:10 PM7/1/09

to Three20

Hi Keith,

I know Joe created Three20 and kudos to him for doing so. But for us
mere mortals, the code base is so complicated that it takes a down-to-
earth guy like yourself to help us work through it. Joe is quite a
talent, but you're the guy who makes it possible for most of us to use
his handiwork.

Thanks again and I'm sure you'll get extra credit from St. Francis !

Reply all

Reply to author

Forward