How do I rewrite a plist if its data types are immutable? - plist

I am getting comfortable with using plists for initializing my app. I now want to save app state back to the plist used to initialize the app and I find myself stuck. At application startup I ingest the plist into an NSDictionary which is immutable. I now want to update the NSDictionary by replacing old values with new values for existing keys and write to the plist via [NSDictionary writeToFile:atomically]. How do I get around the immutability of NSDictionary?
Thanks,
Doug
UPDATE - Not quite there yet
I followed zneak's suggestion and ingested my settings file into an NSMutableDictionary. Works fine. Prior to writing the plist out I confirm that new values now replace old values. Cool. Good to go.
Problem: when I write the file thusly:
if ([self.settings writeToFile:plistPath atomically:YES] == NO) {
NSLog(#"Unable to write plist");
}
The method happily completes properly - the conditional is YES rather then NO - but I see no file. Where has the file gone?
Shouldn't I see the new file in my directory tree?

Make it a NSMutableDictionary by calling -[myDict mutableCopy], then use this one for writing the file; or simply load the plist using [NSMutableDictionary dictionaryWithContentsOfFile:(NSString*)] to get a mutable instance to start with instead of an immutable one.

Use an NSMutableDictionary (you can use -[NSDictionary mutableCopy] to create it). You can then use writeToFile just as with an NSDictionary.

Related

Import an External SQLite database to my project

I'm interested in importing an external SQLite database to my project.
When using the QT Quick Local Storage:
LocalStorage.openDatabaseSync("QQmlExampleDB", "1.0", "The Example QML SQL!", 1000000);
The problem is that, the program generates a NEW database, and if it's possible I'm interested in open an existing database.
Any idea?
Thank you very much!
Thanks all of you, with the information you have got me I could solve my problem, all the things I have had to do are:
First of all in main.cpp I set my offline Storage Path:
engine.setOfflineStoragePath(QString("./"));
Then I also add this code:
QDir dir("./Databases");
if (!dir.exists()) {
dir.mkpath(".");
}
QString new_name = QString(QCryptographicHash::hash(("nameofthecopiedDB"),QCryptographicHash::Md5).toHex());
QFile file(":/SQLite/nameofsourceDB.sqlite");
file.copy("./Databases/" + new_name + ".sqlite");
file.close();
Since I have the DB I would to use in my project in SQLite folder from my resources (:, indicates resources).
And then, in QML file, the openDatabaseSync() function:
basedades = Sql.LocalStorage.openDatabaseSync('nameofthecopiedDB',"1.0","Els meus entrenaments",1000000,"QSQLITE")
Thank you!
openDatabaseSync searches or creates dbs in the directory used for storing offline data.
That directory is identified by the data member offlineStoragePath of the QQmlEngine class.
To change it, you can use the the member method setOfflineStoragePath (see here for further details).
The first argument for openDatabaseSync is:
The name of the database passed to openDatabase()
See here for further details.

Can the Path assigned a SQLite DB be an arbitrary value?

In this blog post, some prerequisite code for getting started using SQLite in Windows Store Apps is given, for adding to the OnLaunched method of App.xaml.cs:
// Get a reference to the SQLite database
this.DBPath = Path.Combine(
Windows.Storage.ApplicationData.Current.LocalFolder.Path, "customers.sqlite");
My question is: Can I use any arbitrary value to replace the "customers.sqlite" part, or does it have to match something else in my code, such as the name of my table definition class (in my case "PhotraxCoreData.cs" which, according to Mr. Green's suggestion, I added below a newly-created "Models" folder)?
My understanding is that, once I've got those classes defined (I do), and the code above in App.xaml.cs, along with this there (adapted for my SQLite classes):
using (var db = new SQLite.SQLiteConnection(this.DBPath))
{
// Create the tables if they don't exist
db.CreateTable<PhotraxBaseData>();
db.CreateTable<PhotraxNames>();
db.CreateTable<PhotraxQueries>();
}
...SQLite tables based on those classes I specified will be created, and have the name "customers.sqlite" (provided I don't change it).
So, can I use:
this.DBPath = Path.Combine(
Windows.Storage.ApplicationData.Current.LocalFolder.Path, "platypus.sqlite");
...or must it be something like:
this.DBPath = Path.Combine(
Windows.Storage.ApplicationData.Current.LocalFolder.Path, "PhotraxCoreData.sqlite");
That database name is just a file name.
The directory must be accessible by your app, but the file name can be anything.
AS CL says, the file name can be anything the app has direct access to. Windows Store apps have limited access to the file system, so the sqlite database must be in either the apps install location (read only) or it's app data folder (read write). A common pattern is to ship a seed database in the app package and then copy it from the install location to app data on first use so it can be written to.

MacRuby: How to read a plist file?

I bet this is super simple and easy but can't find a basic example online. How can I read data from a plist file in my project using MacRuby?
Solution:
Turns out there's a few different ways to do it, but the cleanest I've found (so far) is to use the MacRuby helper method load_plist (which turns a plist file's contents into a hash). Also, if you're using XCode, you will need to get the file path relative to your app bundle:
# there's an AppConfig.plist file in my app bundle
config_path = NSBundle.mainBundle.pathForResource('AppConfig', ofType: 'plist')
#config = load_plist File.read(config_path)
This slide deck about MacRuby has some example code for accessing plist files (slides 77-80), the gist of which is that you open the file with NSDictionary.dictionaryWithContentsOfFile and then manipulate it as you would a Ruby Hash, then write it again with writeToFile_atomically. The NSDictionary documentation might be useful to you; you can find it here.

Where do I put Pluralization rules in asp.net mvc3

I want to add specialized Pluralization rules to my project as I have names in my database like FAS and other things that end with "s" and I want those to be FAS and FASs but the default pluralization wants to make it FASes or something similar which I dont want. I am then trying to use this guide http://blogs.msdn.com/b/efdesign/archive/2008/12/02/pluralization.aspx but I have a hard time figuring out where to put this code? How do I make sure this code is run at startup of my project (I suppose it has to run at startup?)
So where do I put this code?
PluralizationService pluralizationService =
PluralizationService.CreateService(
new CultureInfo("en-US"));
ICustomPluralizationMapping mapping =
pluralizationService as ICustomPluralizationMapping;
if (mapping != null) // it shouldn't be but just checking
{
//Specifying the child pluralizes as children
mapping.Add("FAS", "FASs");
}
The answer is in the tutorial: you have to use it with the schema generator to create the schema using the pluralization service:
EntityModelSchemaGenerator generator =
new EntityModelSchemaGenerator(
storageModel,
"MyNamespace",
"MyContainer",
pluralizationService);
//Generate CSDL and MSL (in memory)
generator.GenerateMetadata();
When do you need to get the names of the entities pluralized?
I may be way wrong, but it seems to me that you could simply add the tables to the model and just rename them in the designer.
Am I overlooking some information?

System::IO::Directory::GetFiles in c++

I am having trouble in storing the files in a string array from a directory in c++, using System::IO::Directory::GetFiles in c++
Also would like to know if we could copy an entire folder to a new destination/ in c++ like given in http://www.codeproject.com/KB/files/xdirectorycopy.aspx for c#
You can store the file names from a directory in a managed array like this:
System::String ^path = "c:\\";
cli::array<System::String ^>^ a = System::IO::Directory::GetFiles(path);
Console::WriteLine(a[0]);
Console::ReadKey();
As for how would you copy an entire folder... Simply recurse from a given root directory creating each directory and copying the files to the new location. If you are asking for code for this, then please say so, but at least try to figure it out for yourself first (i.e. show me what you have so far).
Check out the file listing program in Boost::FileSystem: http://www.boost.org/doc/libs/1_41_0/libs/filesystem/example/simple_ls.cpp. They iterate over all files, printing the paths, but it's trivial to store them instead.
Assuming you're on Win32, you're looking for the FindFirstFile and FindNextFile APIs.
C/C++ does not define a standard way to do this, though Boost::Filesystem provides a method if you need cross platform support.

Resources