StackOverflow hasn't answered iOS question. Can you?
October 16, 2012 10:51 AM   Subscribe

I am desperately seeking help with an iOS programming problem and my StackOverflow question has not been (satisfactorily) answered 14 hours in. Can someone here help? Or tell me how to renew interest in the question in a way that doesn't violate etiquette?

The question is here.

It may be that I don't understand something fundamental about bundles and builds, but I've looked at the Apple Developer documentation and I don't understand.

Basically, my understanding is that the pList files for our app should not be 'packaged' into the apps for users, because they are not the sort of pLists that contain static info to be loaded into controls like table cell. Rather, they are for writing to, and will be written to .pdf at the appropriate time when the app runs. When users run the app, the pList files they need will be created at that time. I thought that this would be best simulated during development as each developer sees a new pList file created in their Simulator folder. I am under the impression that the contents of these folders are developer-specific. Am I wrong?

Please help. If you need more info, I will be thread-sitting. Alternately, if you have advice on how to renew interest in my question on StackOverflow, or if it's ok to rephrase the question and repost it, please let me know.
posted by kitcat to Technology (25 answers total)
 
I don't have an answer for you but have you posted your question to Apple's Developer Forums?
posted by dfriedman at 11:16 AM on October 16, 2012


Your question at Stack Overflow is not very clear, at least to me. Maybe that's why you're not getting an answer.

1. It sounds like everything you're talking about is happening in the simulator, is that correct? You haven't done anything on actual devices yet? That is not clear.

2. It sounds like everything is working just fine for you, but that when your teammates try to get it to work, they get the file system error. Is that correct?

If the basic problem is item 2, you should just go through the contents of the project on disk and all the project settings in Xcode and make sure everything they have is identical to what you have. Something has to be different.

If item 2 is not the problem, then I can't understand your question well enough to hazard a guess as to what's happening.

Oh -- regarding item 1: for the purposes of this question it's just good to be clear about the situation. Beyond that, though, you should be aware that there are differences between the simulator file system and the file system on iOS devices that can lead to their own unique set of problems. I'd recommend getting out of the simulator asap. Otherwise you may get something working and then have to start your debugging all over again later.
posted by alms at 11:18 AM on October 16, 2012


Best answer: Would this be an accurate restatement of your question?

NSString *bundle = [[NSBundle mainBundle]pathForResource:@"Family" ofType:@"plist"];

is returning nil when pathForResource points to a valid resource. This code works fine on the simulator on my machine, but not on my teammate's machines. Our machines were all loaded with the same OS image. What are some possible causes of this issue? What environment/network settings and permissions should I be checking?

One other thought I had was--what happens when you run this on a fresh image? You say that all of these images are identical, but if your teammates have been working on them for a few months, things have almost certainly started changing.
posted by rhythm and booze at 11:29 AM on October 16, 2012


Response by poster: It gets better. I just did a >Reset Contents and Setting in the Simulator, and now the project on the machine I originally wrote and build the code on is throwing that same error.

alms:

1. Yes, everything is happening in the simulator. No, no testing on devices yet.

I really don't know how to reword the question, but I will try again at some point today.

2. Yes, everything WAS working fine for me, until just now.

I know that the simulator file system and the iOS device system works a bit differently, but I was under the impression that:

NSArray *pListpaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

would determine the appropriate path in a real device.

Thanks for your input. I will keep trying (test on device. check each developer's contents and settings. learn more about file system).
posted by kitcat at 11:30 AM on October 16, 2012


Best answer: Unfortunately you don't have enough reputation points to open a bounty, which is the normal way of attracting attention to a question. You need at least 75 points to do it.
posted by yerfatma at 11:32 AM on October 16, 2012


Response by poster: rhythm and booze:

Hmm. I will try on a different image.

A question: is fair to call pathForResource a valid resource if the file doesn't exist there yet?
posted by kitcat at 11:33 AM on October 16, 2012


A question: is fair to call pathForResource a valid resource if the file doesn't exist there yet?

That is a good question. I am not familiar with iOS programming, just C and general file system annoyances. Does it state anywhere in the documentation that pathForResource will return something/create a file for you if there is no file there? If not, I would assume that that's where your problem lies.

Try creating an empty file at the path you're pointing to; do you still get the same error?
posted by rhythm and booze at 11:38 AM on October 16, 2012


Best answer: -[NSBundle pathForResource:ofType:] looks for an existing file. If one doesn't exist, it returns nil. That means that you can't use that method to get a path, then create a new file at that path.

Even if that did work, it would return a path inside your app bundle, which you are not supposed to modify at runtime. (Can't recall if iOS prevents a write from happening, or not.) So it's the wrong way to go.

Instead, create the path inside the documents directory. Call NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES), get the first result from the array, then use -[NSString stringByAppendingPathComponent:] with your file name. This is a very common pattern -- a search for those methods should turn up lots of examples.

Once you've constructed that path, you can create a file there, just as you are doing now.
posted by xil at 11:41 AM on October 16, 2012


Response by poster: Forgive me, xil, but I believe this is exactly what I have done.

rhythm and booze:

Hmm, didn't get the error when I created an empty file at the path. It didn't write my data this time, but I can deal with that...

I am utterly confused, but I'll take some time with this now and go look into everyone's suggestions. I am deeply, deeply grateful. This (school) project for a real client has a strict deadline.
posted by kitcat at 11:54 AM on October 16, 2012


Response by poster: xil - I think it sound like I'm brushing you off, which is not the case. This is extremely useful to me:

Even if that did work, it would return a path inside your app bundle, which you are not supposed to modify at runtime. (Can't recall if iOS prevents a write from happening, or not.) So it's the wrong way to go.
posted by kitcat at 11:56 AM on October 16, 2012


Response by poster: Would it help to know that the path it was saving to (when it worked) was:

@"/Users/cmacmillan3/Library/Application Support/iPhone Simulator/5.1/Applications/CE345E4B-CBC3-45F7-85F9-6F2C2525538D/Documents/Family.plist"
posted by kitcat at 12:49 PM on October 16, 2012


Best answer: Sorry, I should have read your question more carefully.

Your problem has nothing to do with writing the new file, so ignore everything related to that.

You want (1) your app project to include a plist file, (2) to include that file in your built app's bundle, (3) to read that file at runtime.

Make sure that your project includes the Family.plist file. Most important, in your target's Build Phases, make sure the Family.plist is in the "Copy Bundle Resources" phase.

To see this stuff: in the left-side sidebar in Xcode, click the topmost item (the project), then in the main part of the window, find the section labeled Targets and click your app target (there is probably only one). You should see a bar at the top with an item named "Build Phases"--click it and expand the "Copy Bundle Resources" section. If Family.plist isn't in there, click the + button and select it.

Also make sure that you are spelling the file name exactly the same in the code, including any capitalization.

You might try doing this in a new Xcode project to make sure you understand all the steps.

1. In Xcode, choose the menu: File, New, Project...
2. Choose "Empty Application", name your app, and choose where to store it
3. File, New, File...
4. Choose iOS, Resource, Property List. Name it Family. When you enter the name, there will be a list of targets; make sure the target for your app is checked (it will be, by default).
5. In your app delegate, in -application:didFinishLaunchingWithOptions:, add code to find and read the file, before the return statement.
posted by xil at 1:37 PM on October 16, 2012


Response by poster: xil: tldr; still not working. It's not copying the bundle resources, or something.

My Family.plist is, is, is in "Copy Bundle Resources." I have run things a million times, cleaned, reset Simulator, and checked. It's always there.

It is spelled correctly in the proper case (also checked a million times :) ).

The plist is created correctly (guess how many times I created and deleted and recreated), is in a group called Resources under Supporting Files. The target, when I add the file, is correct.

(Regarding the app delegate bit, I moved the code there from the ViewController it lived in before. Nothing changes, it just crashed upon loading instead of at the point I had the code previously).

No matter what I do, after NSString *bundle = [[NSBundle mainBundle]pathForResource:@"Family" ofType:@"plist"]; the bundle string is nil.

----------------------------------------------------------------------------------------------
I now understand why this worked for a while and then stopped. Not understanding what I was doing, I originally HAD a Family.plist in my project under the Supporting Files group. I thought my data would write to there. To my surprise, it wrote to /Users/cmacmillan3/Library/Application Support/iPhone Simulator/5.1/Applications/CE345E4B-CBC3-45F7-85F9-6F2C2525538D/Documents/Family.plist". Hey! I thought. I guess I don't need that plist in my project - and promptly deleted it.

Pushed changes, everyone got changes, nothing worked for anyone but me because the file was already created in my Documents directory. But NOW, even after creating the plist file in the project again (as I explained above), it still can't find the bloody thing. Still stuck. Sorry.
posted by kitcat at 2:27 PM on October 16, 2012


Response by poster: I had a new answer in StackOverflow suggesting I confirm that the local filepath exists.

To confirm the 'pListpath', I copied the path from the debugging console and, from my home directory in terminal, I used

cd Library/Application Support/iPhone Simulator/5.1/Applications/4DBE18C2-B22B-4CA9-B3A2-EC42711CEC3F/Documents.

It can't find that path! If I use the tab method to autocomplete the directory names for me, it does find the path, but with the strange format:

Library/Application\ Support/iPhone\ Simulator/5.1/Applications/4DBE18C2-B22B-4CA9-B3A2-EC42711CEC3F/Documents/

Is this a clue?
posted by kitcat at 3:12 PM on October 16, 2012


Response by poster: Nevermind. Bash doesn't like spaces and puts those escape characters in. I even tried hard coding the path with the escape characters into to code, to no avail.
posted by kitcat at 3:27 PM on October 16, 2012


Best answer: My suspicion is that your coworkers / other machine are not properly loading the xcode file, or the simulator is not copying in the new files. This has happened to me a million times. Resetting on your machine will not help, you need to clean + build and reset on their simulator.

The tell will be open the .app on a machine that isn't working right, and see if the plist is in there. it should be in Library/Application\ Support/iPhone\ Simulator/5.1/Applications/4DBE18C2-B22B-4CA9-B3A2-EC42711CEC3F/whatever.app you can open it by right clicking and choosing 'show package contents'.

A second approach to the 'things not copying to bundle' issue is just adding a copy shell script build phase. This stack overflow has some direction on the environment vars you need to use for that.

oh, also on a fresh install of your app, that documents directory is always empty.
posted by jonbro at 3:32 PM on October 16, 2012


Things to check:

- In ~/Library/Application Support/iPhone Simulator/5.1/Applications/UUID/YourApp.app, is the file Family.plist present?
- Is [NSBundle mainBundle] nil?
- Is [[NSBundle mainBundle] bundlePath] the same app directory?
posted by xil at 4:20 PM on October 16, 2012


Response by poster: Sorry, everyone refers to yourApp.app, but I don't have such a beast. Just UUID/Documents. Is that a problem? Is it hidden?
posted by kitcat at 4:28 PM on October 16, 2012


Not an iOS programmer and just in case I'm not stating the obvious: "YourApp.app" is probably a placeholder name and you're supposed to replace "YourApp" with the name of your program. In other words, see if Family.plist is present your app's folder when being simulated.
posted by ethidda at 4:35 PM on October 16, 2012


Yeah, you must have a .app somewhere on your system if it is in the simulator. Track that down. It is possible that your simulator directory is somewhere unexpected, or you are using a different sdk then you think you are using.
posted by jonbro at 4:41 PM on October 16, 2012


Response by poster: Looking for file. Hoping syntax was correct for bash search:

find / -type f -name '*.app'

produces nothing, but notably?:

find: /Users/xcode/Desktop: Permission denied
find: /Users/xcode/Documents: Permission denied
find: /Users/xcode/Downloads: Permission denied
find: /Users/xcode/Library: Permission denied
find: /Users/xcode/Movies: Permission denied
find: /Users/xcode/Music: Permission denied
find: /Users/xcode/Pictures: Permission denied
posted by kitcat at 5:08 PM on October 16, 2012


what the heck? do you have xcode installed as a separate user? do you have sudo access? can you check in /Users/xcode/Library/Application Support/ to see if that is where the simulator is running from?
posted by jonbro at 5:32 PM on October 16, 2012


Response by poster: Found file. I'm an idiot. On the computer I was using before, it didn't show a file extension, yadda yadda.


So, I'm on the home computer now. Last night, nothing worked. It's working now!!!!!. Hooray!!!!I am only afraid that I will go to school tomorrow, get on the computer there, and encounter myriad problems again, but here is what I did to make it work:

1. Delete existing Family.plist from Documents folder.
2. Reset Simulator
3. Clean, Build project
4. Create new Family.plist in app project (Supporting Files group).
5. Confirm in Build Phases that its in Copy Bundle Resources
6. Confirm that Family.plist shows in .app Package Contents
6. Run in Simulator and pray....
7. Experience NO crash!!!!!!!!!!
8. Check file in Documents folder
9. See that data has successfully been written!!!!!!!!!!!!!

Honest to god, I could swear I did these things over and over today on the other machine. I'm going to merge with other teammmates' work, push to repository and pull down tomorrow on that machine. Then follow these steps again.

I need a drink before I thank you all.
posted by kitcat at 5:44 PM on October 16, 2012 [2 favorites]


Response by poster: jonbro:
Umm, yeah, xCode is installed as a user. I don't get that, but I don't get macs either. If that wasn't perfectly clear before.
posted by kitcat at 5:49 PM on October 16, 2012


Response by poster: Thank you everyone. This was really kind of an embarrassing gong show and at some points a wild goose chase (the machines weren't the problem, unless tomorrow proves otherwise). Now I can go back to the StackOverflow question and fix it so that it's helpful to others.

I really appreciate the way mefites follow through to help others out instead of handing out half-hearted answers and walking away. Thank you for doing that. Every day lost on this project is a big deal, we don't have iOS-savvy people at our school to help, and it's a can't fail kind of thing, so it means a lot to me.
posted by kitcat at 7:41 PM on October 16, 2012 [1 favorite]


« Older Stupid Usability Question! Duplicating Navigation...   |   How to find 24 hour nursing care for a parent? Newer »
This thread is closed to new comments.