Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 04-10-2009, 02:02 PM   #1 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 16
Wizfinger is on a distinguished road
Angry File weirdness: Files written to disk do not appear in [NSFileManager defaultManager]

I am experiencing a really strange problem with saving files to disk and then reading them again.

First, I decode an animated .GIF image and store the frames in an NSArray of NSData objects. This works fine.

When I create a UIImage with one of these NSData objects, the image appears garbled even though the GIF image data is okay. Apparently it is not clear to the system that the NSData contains GIF image data.

To work around this, I decided to write the NSData objects to files on the disk with a .gif extension in the file name. When I then load them into UIImages using [UIImage imagenamed:@"..."] everything is okay and the images are displayed correctly.

Unfortunately the UIImages need some internal converting because they take a while to display, even though they are only 16 kb in size. No problem, I'll just load them in a separately detached thread, so the image loading will not stall the user interface:

Code:
[NSThread detachNewThreadSelector:@selector(writeFrames) toTarget:self withObject:nil];
I write the files using:

Code:
[[NSFileManager defaultManager] createFileAtPath :file contents:nil attributes:nil];
NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:file];
fcntl([outFile fileDescriptor], F_NOCACHE, 1);

// Truncate the output file since it may contain data
[outFile truncateFileAtOffset:0];

// Write data to outFile
[outFile writeData:GIF_framesData];

// close the file
[outFile synchronizeFile];
[outFile closeFile];
(I am using the NSFilehandle with no caching because I first thought I had a caching problem.)

After writing the files the system cannot find any files at all:

Code:
[[NSFileManager defaultManager] directoryContentsAtPath:path]
...will return no files whatsoever, even though they really are present on the disk and the path is correct. I know this, because of the following:

This happens ONLY when running the app stand-alone on the iPhone. In the simulator, it works fine. Also on the iPhone using the debugger from within XCode, it works fine.

Everything always seems to run fine until I disconnect the iPhone and run the app on it with no XCode attached. Then the filemanager returns zero files.

When running the file handling in the main thread, instead of a separate thread, everything also works fine, except that the user interface stalls when loading the GIF files (which is unwanted).

If anyone knows:

- how to display NSData objects containing GIF image data without saving them to disk first
- how to store files and then immediately read them again without the filemanager losing them

I'd be very, very happy. I am basically at my wit's end.

Thanks!
Martin
Wizfinger is offline   Reply With Quote
Old 04-10-2009, 02:16 PM   #2 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
meowmix23F is on a distinguished road
Default

Quote:
Originally Posted by Wizfinger View Post
I am experiencing a really strange problem with saving files to disk and then reading them again.

First, I decode an animated .GIF image and store the frames in an NSArray of NSData objects. This works fine.

When I create a UIImage with one of these NSData objects, the image appears garbled even though the GIF image data is okay. Apparently it is not clear to the system that the NSData contains GIF image data.

To work around this, I decided to write the NSData objects to files on the disk with a .gif extension in the file name. When I then load them into UIImages using [UIImage imagenamed:@"..."] everything is okay and the images are displayed correctly.

Unfortunately the UIImages need some internal converting because they take a while to display, even though they are only 16 kb in size. No problem, I'll just load them in a separately detached thread, so the image loading will not stall the user interface:

Code:
[NSThread detachNewThreadSelector:@selector(writeFrames) toTarget:self withObject:nil];
I write the files using:

Code:
[[NSFileManager defaultManager] createFileAtPath :file contents:nil attributes:nil];
NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:file];
fcntl([outFile fileDescriptor], F_NOCACHE, 1);

// Truncate the output file since it may contain data
[outFile truncateFileAtOffset:0];

// Write data to outFile
[outFile writeData:GIF_framesData];

// close the file
[outFile synchronizeFile];
[outFile closeFile];
(I am using the NSFilehandle with no caching because I first thought I had a caching problem.)

After writing the files the system cannot find any files at all:

Code:
[[NSFileManager defaultManager] directoryContentsAtPath:path]
...will return no files whatsoever, even though they really are present on the disk and the path is correct. I know this, because of the following:

This happens ONLY when running the app stand-alone on the iPhone. In the simulator, it works fine. Also on the iPhone using the debugger from within XCode, it works fine.

Everything always seems to run fine until I disconnect the iPhone and run the app on it with no XCode attached. Then the filemanager returns zero files.

When running the file handling in the main thread, instead of a separate thread, everything also works fine, except that the user interface stalls when loading the GIF files (which is unwanted).

If anyone knows:

- how to display NSData objects containing GIF image data without saving them to disk first
- how to store files and then immediately read them again without the filemanager losing them

I'd be very, very happy. I am basically at my wit's end.

Thanks!
Martin
Make sure you are writing to your DOCUMENTS directory, which you have read+write access to. Otherwise you won't get any files. Alternatively, try using
[[NSFileManager defaultManager] directoryContentsAtPath:@"somepath"];
to see if the directory has a certain file (just do a for() loop. That method returns an array)
meowmix23F is offline   Reply With Quote
Old 04-13-2009, 10:51 AM   #3 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 16
Wizfinger is on a distinguished road
Default

Thanks for the reply!

I was writing to the /tmp directory. But your reply made me have another look at the code.

I found that at some point, the tmp directory was being deleted. Not just the contents, but also the directory itself.

Fixed this, and now everything works fine. (Both /Documents and /tmp)

This however still leaves the question: how to display NSData objects containing GIF image data without saving them to disk first?
Wizfinger is offline   Reply With Quote
Old 04-14-2009, 09:02 AM   #4 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 24
Posts: 3,983
smithdale87 is on a distinguished road
Send a message via AIM to smithdale87
Default

Quote:
how to display NSData objects containing GIF image data without saving them to disk first?
Off the top of my head, I believe that UIImage has an initWithData: method. That's probably your best bet.
smithdale87 is offline   Reply With Quote
Old 04-14-2009, 09:29 AM   #5 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 24
Posts: 3,983
smithdale87 is on a distinguished road
Send a message via AIM to smithdale87
Default

[removed double post]
smithdale87 is offline   Reply With Quote
Old 04-14-2009, 11:08 AM   #6 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 16
Wizfinger is on a distinguished road
Default

Quote:
Originally Posted by smithdale87 View Post
Off the top of my head, I believe that UIImage has an initWithData: method. That's probably your best bet.
That's correct but it does not recognize the GIF data as such, so the image appears garbled with wrong colors etc. (Perhaps it assumes PNG data?)

Unfortunately the type of data cannot be specified using initWithData:.

The ridiculous thing is that NSData writeToFile: using a ".gif" extension in the filename correctly displays the files in the Finder (and Preview, and Photoshop), and after loading them again using NSData initWithContentsOfFile: the data will display a perfect picture when using it in a UIImage.

My guess is that the NSData object has some parameter or setting that is set by the initWithContentsOfFile: method, that tells the system it is GIF image data. Unfortunately I cannot find anything about this in the header files or documentation.
Wizfinger is offline   Reply With Quote
Reply

Bookmarks

Tags
nsfilehandle, nsfilemanager

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 331
7 members and 324 guests
blueorb, guusleijsten, jbro, Kryckter, LEARN2MAKE, n00b, SLIC
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,113
Posts: 402,880
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 08:57 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0