Persisting app configuration in iOS: .plist file vs NSUserDefaults - ios

I have some app-related parameters (boolean and string data) which are either set by user through the app, either at its first execution. I don't want this kind of information to be stored by using Core Data, so the options I'm thinking about are:
1) Creating and reading/writing a custom .plist file (let's say, myconfig.plist) to be stored in Documents app folder
2) Saving such info using NSUserDefaults
The kind of information I want to keep is, for example, the last app version that was installed and run in order to check if app is being updated, or a flag telling if some specific set of data has been already loaded without having to check the model.
Which of the options would be the most suitable and safest for this task? Or is even there any better option of handling this?
Thanks

try this if you would check appstore version with your actually app version https://github.com/nicklockwood/iVersion

Related

Can the user edit the plist from outside the app?

I'm using the UserDefaults to save some persistent data (app's state, not something that needs to be secured). This data (AFAIK) is saved on a plist. Can the user edit this plist outside the app?
I tried it, and while it seems possible, when I run the app it overrides the changes with the last values from the app.
If it's not possible, then what good is the 'defaults write ...' command (via the Terminal)?
This question is relevant both to iOS and macOS
It depends how you use UserDefaults. UserDefaults is really not much more than a dictionary with a convenient way to read/write to a plist file. You can decide yourself where that file is stored, and therefore whether it is changeable by the user outside the app or not. And you are responsible for reading the values at startup and possibly when they change on the fly.
On iOS, only if you use UserDefaults.standard, will the plist file be placed in a location that is accessible and managed by Apple's Settings app. It is still your responsibility to read/write the defaults when appropriate. Not sure how that works on MacOS.
If they are reset on startup of the app, it is likely the app is overwriting them explicitly on startup.

Is it possible for an attacker to maliciously modify iOS keychain data?

I am storing secure data in the keychain that should be maintained only within my app. During app running this data is retrieved to some variable. It seems like it is possible to crack my app in order to read that value or even dump the whole keychain, but my question is it possible to the "hacker" modify that data i.e. modify at runtime area of RAM that holds this variable and make my app to update keychain with new value? And I also have setter method for that property, which saves it to keychain, is it possible to investigate the address of that function and force call my method with custom value?
I already looked here and here for best practices, read answer at Quora, that and that articles, looked for ios-keychain-analyzer project at GitHub but there is no mention about changing data, only about reading

Saving files with iOS. Where do they go?

I have saved a text file from my app and I can open it again, but is there any way the user can gain access to this file to just do whatever they want with it? I tried printing the path which looks like this : /var/mobile/Applications/2DD5A15B-9BC8-4981-A1F6-E22F66C71CA4/Documents/ I'm assuming that huge number is some type of app identifier, which leads me to believe that this file isn't going to be accessible unless you're in the app. Which makes me wonder, why would writing a file be any better than just saving a big string to NSUserDefaults?
I am building an app where the user should be able to do some data logging. If the user can sync their phone with their computer and download the file that would be awesome. Can you do that? Or do I have to build in functionality so that they have to email themselves the file or something?
I'm assuming that huge number is some type of app identifier
It is. It's an UUID.
which leads me to believe that this file isn't going to be accessible unless your in the app
...unless you are in the app (or, unless the device is jailbroken, in which case it's plaintext for anyone interested).
why would writing a file be any better than just saving a big string to NSUserDefaults
Conceptually, it's not a setting. If you have some data, an entity, then write it to a file. NSUserDefaults is not appropriate for storing large amounts of data. It's for storing user preferences (which are volatile!), nothing else.
made of the concept of iOS this is also called sandboxing.
if this would not exist, it could be possible to change or getting data of other apps.
If the user can sync their phone with their computer and download the file that would be awesome. Can you do that? Or do I have to build in functionality so that they have to email themselves the file or something?
you can use the awesome iCloud.
check here:https://developer.apple.com/icloud/index.php

How to initialize an iOS app with default data?

I'm writing an app that needs to access data from a large file every time a button is pushed. I've been reading up on it and the apple documentation says:
"You can create a separate persistent store that contains the default data and include the store as an application resource. When you want to use it, you must either copy the whole store to a suitable location, or copy the objects from the defaults store to an existing store."
Does this sound like the best way to go?
I've created the database with the table I need and put it under "Supporting Files" in Xcode - is this an application resource? Also I'm not sure what it means by "you must either copy the whole store to a suitable location" - is this not it?
Finally, my main question - how do I access the information in the DB in my .m files? Thanks for bearing with me, still very new to this.
Does this sound like the best way to go?
I believe it depends on what kind of information you want to access and if you need to update this information (add new information, modify it, delete, etc).
If you just want to read the data and do something with it, check out Property Lists and XML. In case the data is structured somewhat like a relational database and it is necessary to modify it, check out Apple's Core Data framework.
Is this an application resource?
Yes, it kind is, don't worry about the nomenclature so much but for more clarification check out Apple's own guide about resources.
Also I'm not sure what it means by "you must either copy the whole store to a suitable location" - is this not it?
You can load the store from multiple locations (folders, different files, etc), this just means that you should pick the best that suits your application.
Note, the files you import to your project are stored in the application's bundle and you can't (as far as I know) modify them. So, if you choose to include a Core Data store file, you need to copy the store from the bundle to a location of your preference (ex: the documents folder).
How do I access the information in the DB in my .m files?
It depends on your pick. As it looks like you're more interested in using Core Data, start by looking at the link I've provided above and searching some tutorials.

How can i prevent my settings(files, NSUserdefaults) being modified by external application like iExplorer

I wanted to do some operation on App's first launch. I have written my code as suggested here: how to detect first time app launch,iphone. It is working well.
I am able to delete and modify the contents in UserDefault plist using iExplorer.So my app is not functioning as expected. Is there any way to restrict app files being modified by external apps(iExplorer)?
If you alter system files using iExplorer, you could make any app not function properly. One way to make it somewhat tamper proof (though not quite as efficient), is to manage the information on a server rather than a local file. For example, your app may make a call to a web service to retrieve and store settings. That's not to say they couldn't tamper with your application bundle rendering it useless.
In a nutshell, you cannot make your app completely tamper proof
Edit
As Zaph has suggested, you can use the keychain. Simply store the [[NSBundle mainBundle] bundlePath] as a key in the keychain. bundlePath is unique for each installation. So, when your app loads, check for bundlePath in the keychain, if not exists, then it is fresh installation/first time load. After app has loaded, save the bundlePath to the keychain.
Create a hash of the values of the items you wan to to protect, encrypt that hash and save it in NSUserDefaults. When the NSUserDefaults are read decrypt the hash, re-compute the hash of the fields and check if hashes match.
If it is a small amount of data, say a single value, save it in the keychain.

Resources