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 12-03-2010, 09:55 PM   #1 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default Copying files from Bundle to the Documents folder

I am having an issue copying things from the bundle to the Documents directory on first run. It works fine in the Simulator but doesn't work on the phone. Can anyone shed some light on my issue?

I am checking to make sure I only copy over .png files that have filenames of a certain length and contain dashes (xxxx-xx-xx.png) and that code works fine as I have tested it with NSLog messages. It is the actual copying code that seems to be faulty.

Code below:



NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDire ctory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];

NSString *documentsHomeDirectory = NSHomeDirectory();
documentsHomeDirectory = [documentsHomeDirectory stringByAppendingString:[NSString stringWithFormat:@"/My.app"]];

// Define Filemanager
NSFileManager *fm = [NSFileManager defaultManager];

// Catch any errors
NSError *dataError = nil;

// get all the files in the directory
NSArray *dataFiles = [fm contentsOfDirectoryAtPath:documentsDirectory error:&dataError];
int fileCount = [dataFiles count];


NSArray *dataFiles2 = [fm contentsOfDirectoryAtPath:documentsHomeDirectory error:&dataError];
int fileCount2;
fileCount2 = [dataFiles2 count];

if (fileCount == 0){
NSLog(@"Documents Directory is Empty");

for (int i =0; i < fileCount2; i++){
myFileName = [dataFiles2 objectAtIndex:i];

NSRange match = [myFileName rangeOfString:@".png"];
NSRange dashMatch = [myFileName rangeOfString:@"-"];

BOOL isPNG = match.location != NSNotFound;
BOOL hasDate = [myFileName length] == 14;
BOOL hasDash = dashMatch.location != NSNotFound;

if(isPNG && hasDate && hasDash){
NSString *myPath = [documentsHomeDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@",myFileName]];
NSString *myNewPath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@",myFileName]];
[fm moveItemAtPath:myPath toPath:myNewPath error:NULL];
}
}
} else {
NSLog(@"There's stuff in here!");
}

Probably something simple- any help would be appreciated.
(BTW the space in the NSDocumentDirectory was inserted by the forum software and does not appear in my code)

Thanks-

Keith
keith326 is offline   Reply With Quote
Old 12-03-2010, 10:05 PM   #2 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

First a note, use [code] [ /code] tags when posting code. It preserves indentation and makes it easier to read.

Second, what do you mean when you say it doesn't work on the device? Does it give an error/crash? If not, what happens when it is executed? I see you put a few NSLog lines there, what is the output in the console? Does it write out "Documents Directory is Empty"? Put maybe one in the for loop, there's a chance fileCount2 is zero so that's why nothing is happening. Also note that the filesystem on the device is case sensitive, and on the simulator it isn't, so the names have to match exactly.
baja_yu is offline   Reply With Quote
Old 12-03-2010, 11:21 PM   #3 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by keith326 View Post
I am having an issue copying things from the bundle to the Documents directory on first run. It works fine in the Simulator but doesn't work on the phone. Can anyone shed some light on my issue?

I am checking to make sure I only copy over .png files that have filenames of a certain length and contain dashes (xxxx-xx-xx.png) and that code works fine as I have tested it with NSLog messages. It is the actual copying code that seems to be faulty.

Code below:



NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDire ctory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];

NSString *documentsHomeDirectory = NSHomeDirectory();
documentsHomeDirectory = [documentsHomeDirectory stringByAppendingString:[NSString stringWithFormat:@"/My.app"]];

// Define Filemanager
NSFileManager *fm = [NSFileManager defaultManager];

// Catch any errors
NSError *dataError = nil;

// get all the files in the directory
NSArray *dataFiles = [fm contentsOfDirectoryAtPath:documentsDirectory error:&dataError];
int fileCount = [dataFiles count];


NSArray *dataFiles2 = [fm contentsOfDirectoryAtPath:documentsHomeDirectory error:&dataError];
int fileCount2;
fileCount2 = [dataFiles2 count];

if (fileCount == 0){
NSLog(@"Documents Directory is Empty");

for (int i =0; i < fileCount2; i++){
myFileName = [dataFiles2 objectAtIndex:i];

NSRange match = [myFileName rangeOfString:@".png"];
NSRange dashMatch = [myFileName rangeOfString:@"-"];

BOOL isPNG = match.location != NSNotFound;
BOOL hasDate = [myFileName length] == 14;
BOOL hasDash = dashMatch.location != NSNotFound;

if(isPNG && hasDate && hasDash){
NSString *myPath = [documentsHomeDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@",myFileName]];
NSString *myNewPath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@",myFileName]];
[fm moveItemAtPath:myPath toPath:myNewPath error:NULL];
}
}
} else {
NSLog(@"There's stuff in here!");
}

Probably something simple- any help would be appreciated.
(BTW the space in the NSDocumentDirectory was inserted by the forum software and does not appear in my code)

Thanks-

Keith
I think the problem is the way you are building the starting path to the directory in your bundle. Don't use NSHomeDirectory and append your app name to get to the bundle.

Instead, use

Code:
NSString* bundlePath = [[NSBundle mainBundle] resourcePath];
Then you can list the files in the directory with code like this:

Code:
source_files = [fileMgr contentsOfDirectoryAtPath: bundlePath error: &result];
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 12-03-2010, 11:58 PM   #4 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default

I used the code you suggested to build the path but it still isn't moving the files from the bundle to the documents directory. I know that it is entering the loop and making it through the conditionals, the only thing that doesn't seem to work is the actual code for moving the files. Are there permission issues I should be aware of?

I would think that the code for moving stuff is pretty straightforward, but I am hung up on this right now.

Thanks again for your responses.

Keith
keith326 is offline   Reply With Quote
Old 12-04-2010, 06:47 AM   #5 (permalink)
Registered Member
 
Join Date: Jun 2009
Location: Ypsilanti, Michigan
Age: 63
Posts: 1,549
RLScott is on a distinguished road
Default

Quote:
Originally Posted by keith326 View Post
I used the code you suggested to build the path but it still isn't moving the files from the bundle to the documents directory. I know that it is entering the loop and making it through the conditionals, the only thing that doesn't seem to work is the actual code for moving the files.
How do you know the files are not being copied? How did you check?
RLScott is offline   Reply With Quote
Old 12-04-2010, 11:23 AM   #6 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default

OK- Finally figured out the issue. Apparently you cannot moveItemAtPath when going from the Main Bundle to the Documents Directory- instead you have to copyItemAtPath in order for it to work.

Thanks for everyone who helped out.
keith326 is offline   Reply With Quote
Old 12-04-2010, 11:49 AM   #7 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by keith326 View Post
OK- Finally figured out the issue. Apparently you cannot moveItemAtPath when going from the Main Bundle to the Documents Directory- instead you have to copyItemAtPath in order for it to work.

Thanks for everyone who helped out.
Oh yeah.

I didn't notice that you were using moveItemAtPath.

On the iPhone the app bundle is read-only. Any attempt to change the contents of the app bundle will fail.
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 12-04-2010, 12:08 PM   #8 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default

Not a problem Duncan. You are always spot on with stuff so I'll let this one slide.

I knew it was something stupid and easy - I just wasn't getting it. So easy to overlook too, especially since the code IS correct except in this context. Thanks again for your help.
keith326 is offline   Reply With Quote
Old 12-04-2010, 12:11 PM   #9 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default

Thanks for the hint on the code tags. I was wondering why it wasn't working for me. Turns out it was an ID-10-T error on my part.
keith326 is offline   Reply With Quote
Old 12-04-2010, 02:47 PM   #10 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Jan 2010
Location: Issaquah, WA
Age: 42
Posts: 1,244
dljeffery is on a distinguished road
Default

As a minor side note, you really shouldn't be using stringByAppendingString: to form paths; that's what stringByAppendingPathComponent: is for. It's both cleaner (less code to write/read) and safer (for example, it makes sure there are no missing path separators, and no doubled up path separators).

So instead of this:

Code:
NSString *myNewPath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@",myFileName]];
do this:

Code:
NSString *myNewPath = [documentsDirectory stringByAppendingPathComponent:myFileName];
__________________
Recall It! Tag your notes. Tag your photos. Tag your thoughts. Tag your life.

Recall It! for iPad

http://www.dljeffery.com
dljeffery is offline   Reply With Quote
Old 12-04-2010, 04:40 PM   #11 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by keith326 View Post
Thanks for the hint on the code tags. I was wondering why it wasn't working for me. Turns out it was an ID-10-T error on my part.
A suggestion for the future: If you're getting unexpected results, and using a system function that uses a pointer to an NSError object, pass in a pointer instead of nil, and check the result. The error you were getting would probably have told you exactly what was going wrong.

Something like this:

Code:
NSError* result = nil;

[fm moveItemAtPath:myPath toPath:myNewPath error: &result];
if (result != nil)
  NSLog(@"moveItemAtPath:myPath returned error %@",  result);
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 12-04-2010, 11:17 PM   #12 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default

Thanks dljeffery- I have made this modification of my code as per your suggestion and I will make sure to use it from now on. One of the things about starting programming with a new language is trying to figure out how to get things to work - and sometimes the ways we stumble upon aren't as elegant or the best ways to do them. I have quite a notebook of code suggestions now and this one is one of them.

Thanks-

Keith


Quote:
Originally Posted by dljeffery View Post
As a minor side note, you really shouldn't be using stringByAppendingString: to form paths; that's what stringByAppendingPathComponent: is for. It's both cleaner (less code to write/read) and safer (for example, it makes sure there are no missing path separators, and no doubled up path separators).

So instead of this:

Code:
NSString *myNewPath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@",myFileName]];
do this:

Code:
NSString *myNewPath = [documentsDirectory stringByAppendingPathComponent:myFileName];
keith326 is offline   Reply With Quote
Old 12-04-2010, 11:18 PM   #13 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 18
keith326 is on a distinguished road
Default

Very nice Duncan. I will use this in the future as well. I have been trying to figure out how to get meaningful errors from my coding and this helps immensely.

Thanks again-

Keith


Quote:
Originally Posted by Duncan C View Post
A suggestion for the future: If you're getting unexpected results, and using a system function that uses a pointer to an NSError object, pass in a pointer instead of nil, and check the result. The error you were getting would probably have told you exactly what was going wrong.

Something like this:

Code:
NSError* result = nil;

[fm moveItemAtPath:myPath toPath:myNewPath error: &result];
if (result != nil)
  NSLog(@"moveItemAtPath:myPath returned error %@",  result);
keith326 is offline   Reply With Quote
Reply

Bookmarks

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: 364
6 members and 358 guests
chemistry, daudrizek, HemiMG, Kirkout, MarkC
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,665
Threads: 94,120
Posts: 402,898
Top Poster: BrianSlick (7,990)
Welcome to our newest member, daudrizek
Powered by vBadvanced CMPS v3.1.0

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