I have created a plist file in the bundle, and I'm trying update the user's information into the plist. I know that I should copy the plist file from the bundle to the document directory, and edit it from there, but I still have a couple questions:
When I copy the plist file to the document directory, is it permanent? I mean, if I close the program and open it again, I can simply edit the plist file in the document directory, right?
If so, does it mean that I should only execute the code that copies the plist file to the document directory once the app is launched for the first time?
/main question/ Since I want a blank plist file for the user to update their data with, should I just simply create a plist file on the first launch? It'll be a lot easier without the copying around bundles and stuff.
I mean, what is the point of creating a plist file in the bundle in the first place? We will copying it into the document directory anyway, so why not just create one in code?
Yes. Writing a file is permanent, as long as you obviously don't delete/move the file somewhere else.
That is a valid option
Yes. If you need a blank file, you don't need it from the bundle. A better idea would be to create it when you need it (when there is something to write). Usually file creations are managed like so
Check if file exists
If not, create it.
Use the file.
If you need a template file (with already some stuff written in it), then a copy from the bundle is more appropriate. But even then, a lot of developers will like to do everything from code, it's not that heavy of a task, and it forces you to create/prepare the right objects and methods from the get-go.
Like Rooe N said, the NSUserDefaults IS a property list, so if you're talking about very simple data, say, like a username and a last-time-I-logged-In-date, you could store it there.
Note that NSUserDefaults are loaded all the way, every time you load the app, so you don't wanna use it as a database. But since you're going for .plist, I'll assume you've already ruled DBs out.
I'm not completely sure what you are trying to achieve, but you should think of plist as a place for global Constants not something that should be updated on runtime.
Maybe you should look at this:
NSUserDefaults
Related
In our app we have lots of photos that we need to read while using the app, we have to also orgenize them into groups/categories.
this option is to make a plist with their names, and just put them into the app and read the plist.
create folders inside the app, order them inside, and read the specific folder.
Option 2 took me days and I couldn't even make it work reliably, and it also seems not the right way to work for some reason.
Option 1, the problem is that if you have 100 files you have to edit your plist every time again for a new file you add.
Is there a way to make option 1 outside of xcode so I can put all files in a folder on my mac, get their plist, and put this plist inside Xcode ?
What's the right way to achieve this ?
plist is just a simple XML file. You can create the plist file and add to xcode as any normal file to the bundle and read it.
macOS comes with two command-line tools for manipulating plists:
/usr/bin/plutil can convert a plist between formats. You might like this because you could write your photo catalog in JSON using whatever tools you like, then convert it to a plist. Of course, then you could just use JSON directly in your app…
/usr/libexec/PlistBuddy (note that /usr/libexec is not normally in one's PATH) can modify a plist in place, adding, removing, or changing entries.
Both of these tools have man pages (man plutil, man PlistBuddy) and substantial built-in help (plutil -h, /usr/libexec/PlistBuddy -h).
First, you're making a false assumption. There is no need to use a plist file here. An ordinary text file listing the names will do just fine, and you can just make up your own format to dictate groups and suchlike. And that sort of file is trivially easy to maintain.
Second, your rather confused claim that "Option 2 took me days and I couldn't even make it work reliably, and it also seems not the right way to work for some reason" is just a cop-out. Folder references are not a difficult thing to use (you can configure them in the Finder, which is as simple as you can get), they do work just fine, and they are a perfectly reasonable solution here.
I need to be able to configure my app via configuration file.
How do I go about it?
The first thing that comes to my mind is having a .plist file that stores values and to have an singleton class and ask that class for values whenever I create element in question in code.
Or is there any better way to do this?
Depends on the amount of content and size of the configuration file.
If it's a couple of key-value values, I would just go with NSUserDefaults.
If it's a bit more, arrays or more advanced data models, I would go with a .plist. But remember to move the default .plist into the /Documents folder, you are not allowed to edit files in the app bundle.
I'm attempting to make the values in a .plist Multi Value dynamic. Specifically, I want to download a list of options from a web site and populate the values with the returned data. I have read a couple of posts stating that changing the app bundle during runtime is impossible. Is it not possible to make the values refer to a data source outside the app bundle, for example if I put the alternatives in NSUserDefaults and read from there?
If this is totally out of the question, what alternatives are there?
What I do is copy the plist into a hidden folder in the documents directory and work with that copy
If the file does not exist, copy it entirely, and if it does, do some merging or overwrite completely, whatever fits your needs
Working with NSUserDefaults is also a possibility
I have a SQlite database file with records which comes with my app.
I just used the file I added to my project to make my INSERT and UPDATE statements.
After uploading it to my test device I got the exception that the file is read only.
After a bit of research I found out, that I have to copy the db file to the users directory to make an insert. This works for now. But I have a view questions about it, which i didn't get answered through google:
Where should I put my copy process?
I implemented it in the AppDelegates FinishedLaunching, where I check if it already exists.
Where should I copy the file to?
I used the MyDocuments folder for now, is this ok?
Since the file cannot be encrypted, can another app access the database file?
When the user decides to delete the app from the device. Will the database file get deleted,too?
Thanks!
Where should I put my copy process? I implemented it in the AppDelegates FinishedLaunching, where I check if it already exists.
That really depends, but finishedLaunching is OK from my point of view.
Where should I copy the file to? I used the MyDocuments folder for now, is this ok?
I'm not sure what you mean by "MyDocuments" folder. Each Application has a dedicated Document directory. That's where you should copy it.
Since the file cannot be encrypted, can another app access the database file?
No, they run sand-boxed (unless the device is jailbroken)
When the user decides to delete the app from the device. Will the database file get deleted,too?
Yes, since the whole document directory will be deleted.
Where should I put my copy process? I implemented it in the AppDelegates FinishedLaunching
Keep in mind that you have a limited amount of time to complete FinishedLaunching execution (around 15 seconds) before the iOS watchdog kills your application.
Depending on the size of your database, the speed of device and other processing you need to do then you might want to consider only checking if it already exists (that should be quick) then do the copy (if required) from to another thread.
I used the MyDocuments folder for now, is this ok?
Yes, using Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments) is correct.
Everything else from #Lightforce answer covers the rest.
I have a plist in my Resources folder that I'm using to store conversion information. I'd like to give the user the ability to "turn off" certain units so that those units will never be used in conversions. I don't want to have to maintain two lists with the conversion information in it.
I am able to save data back to that plist file in the stimulator. (using writeToFile and the pathForResource). I'm wondering if this is a problematic approach.
Will there be an issues with this on deployment? (i.e. will Apple seal the plist)
What will happen if I push out an upgrade? What if that upgrade contains new units added to the list?
Would doing something like copying the plist to the user's documents directory make sense?
It is not possible to change the app bundle. Further the app is signed. Instead copy the plist to the documents directory on first start and access from there.
No whatever is in the application bundle is offlimit has the DRM on iPhone needs it to stay the same. You should save your preferences in the Apllication Document folder or Preference folder.
Use an iOS Settings Bundle...