I need that a string in a .plist file could be changed within the app with a "save" button. My plist is a simple array of strings, I need that when the user taps "Save" the string could be modified. Sorry for my bad english. Thank you
You need to first extract your plist data and then you have to set the values and then again you have to write like that below:-
NSString *docPath =#"your Path";
NNSMutableDictionary* updateVal=[[NSMutableDictionary alloc]initWithContentsOfFile:docPath];
[updateVal setObject:#"yourString" forKey:#"key"];
[updateVal writeToFile:docPath atomically:YES];
Note:- As rmaddy mentioned in the comment that docPath should not be in the app's resource bundle.
Related
I have created an app, and I am trying to access a URL that is stored in a plist file. At this state I am just trying to log the contents out. I am aware similar questions have been asked before, but I am asking specifically to my scenario how to I access Item 0. I am trying to access Item 0 inside InternalViaSafari this manifests itself inside the URLValidator and then that inside the Root. The code I have so far is:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"plist-file-name" ofType:#"plist"];
NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSString* name = [plist valueForKeyPath:#"URLValidator.InternalViaSafari"];
NSLog(name);
You cannot use keyPath like that for this as far as I know. InternalViaSafari is not a property of URLValidator dictionary. What's more InternalViaSafari is an Array not a String in your plist.
In order to get this string you'd need something like this :
NSArray *internalViaSafari = plist[#"URLValidator"][#"InternalViaSafari"];
NSString *name = internalViaSafari.firstObject;
What happens here, is that you get the value under the URLValidator key from your plist dictionary. This value is also a Dictionary (this can be clearly seen in the plist screenshot you shared), so you get the value under the InternalViaSafari key. This value is in turn an Array, which has Strings as its elements. In this example I extracted the first entry from this array.
Each target in my project has to has different info.plist. I want to get the name programmatically from BuildSettings> Packaging> Info.plist file but somehow I cant really retrieve the plist list filename. Is there a way i can retrieve the plist programmatically?
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleInfoPlistURL")
only gives me
Info.plist -- file:///Users/XXXX/Library/Developer/CoreSimulator/Devices/XXXXXX-9B37-4C3D-88E9-XXXXX62B470/data/Containers/Bundle/Application/7XXXXXXXB-BE36-4D3E-9C90-XXXXX/PROJECT%20KOL.app/
Actually NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleInfoPlistURL") returns an NSURL object. Extract the absoluteString from it which will give you the name of your plist file. Check the code below. Sorry for giving answer in Objective-C as I don't know Swift
NSDictionary *infoDict = [NSBundle mainBundle].infoDictionary;
NSString *plistFilePath = [[infoDict objectForKey:#"CFBundleInfoPlistURL"] absoluteString];
NSString *plistFileName = [[plistFilePath componentsSeparatedByString:#"/"] lastObject];
plistFileName is the required file name (with extension .plist)
I'm working on a game that requires the use of a plist. I set up the plist correctly, or at least I hope, as I've been using this method to set up plists all of the time. The problem though, is that in this case it is like the plist is not even recognized. Here are the contents of my plist:
The 'yo' key and value are debug values that I used to see if the plist was even being recognized. Here is my code:
-(NSString *)docsDir{
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}
-(void)UpdatePlist{
listPath = [[self docsDir] stringByAppendingPathComponent:#"details.plist"];
self.savedData = [NSMutableDictionary dictionaryWithContentsOfFile:listPath];
unsigned long storedHighScore = [[self.savedData valueForKey:#"High Score"] unsignedLongValue];
NSLog(#"%#",[[self.savedData valueForKey:#"yo"] stringValue]);
NSLog(#"Here");
if (score>storedHighScore) {
[self.savedData setValue:[NSNumber numberWithUnsignedLong:score] forKey:#"High Score"];
NSLog(#"YO %lu",[[self.savedData valueForKey:#"High Score"] unsignedLongValue]);
}
[self.savedData writeToFile:listPath atomically:YES];
}
The problem stems from the code or my declaration of the plist I'm assuming. All of the NSLogs execute, as expected, but my log file is even more interesting:
Even the test string does not get returned and gets treated as null. At this point I'm assuming something is wrong with the plist, and yes, I can assure you that the name of the plist is indeed details.plist.
Where is this plist? When/how is it initially written to the documents directory?
The documents directory is the one into which files are copied from iTunes. So if you put this file into your app's Resources, it will not end up in documents.
When the plist doesn't exist, -dictionaryWithContentsOfFile: will return nil. Calling -objectForKey: or -stringValue on nil returns nil again. So if the file doesn't exist, self.savedData will be set to nil. Calling -writeToFile:atomically: on nil also is a No-op. So the code you posted will never create the plist if it is not already there.
Have you tried stepping through this code in the debugger? Click the gutter to the left of the -dictionaryWithContentsOfFile:-line and see what self.savedData is set to?
I use a configuration.plist file to configure certain parameters in my application and initialise few classes based on the contents of this plist file.
However I want to expose to the developer a list of options that can be selected as below(per say),
I can this kind of option available in application info.plist file but I don't get to see anywhere else on how I can achieve this.
I'm looking at getting a drop down list showing the list of available options, Possibly an ENUM list.
Appreciate any assistance.
You can read from the .plist file:
NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString* region = [infoDictionary objectForKey:(__bridge id) kCFBundleDevelopmentRegionKey];
I'm having some trouble debugging my NSLocalizedString implementation. Should be simple, but whatever I do, the function only returns the KEY string.
I'm using XCode 4.5 and iOS6, so I:
Added a new file called File.strings.
In my project settings I added English and Spanish as language settings.
Clicked "Make Localized" in the file inspector, and made sure that both English and Spanish options were selected, and also that the Target membership to my target was selected.
Added "KEY" = "TestEnglish"; to my english File.strings
Added "KEY" = "TestSpanish"; to my spanish File.strings
Added NSLog(#"Localization: %#\n", NSLocalizedString(#"KEY", nil)); to my .m file.
When I run the app, the value "KEY" is always displayed printed in the NSLog.
To jump into this a bit more, I tried this as well:
NSString *path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
NSString *str = [[NSBundle bundleWithPath:path] localizedStringForKey:#"KEY" value:#"" table:nil];
NSLog(#"Localization: %#\n", str);
and still the value "KEY" is printed, yet, path is a valid path.
Does anyone have any clue how to debug this? I feel like I've read every SO question/answer out there, but none of the suggestions help.
I realize that NSLocalizedString returns the KEY string when it cannot match a key, but I don't see how I can debug why my app might not be matching the KEY.
I've also deleted/cleaned the app about a dozen times.
If you specify table:nil, then NSBundle will try to fetch the localization from the default table (the one in SOMELANG.lproj/Localizable.strings). If you have the localization elsewhere, you should explicitly specify the table using table:#"File" (or use the NSLocalizedStringFromTable() macro in a similar manner:
NSString *value = NSLocalizedStringFromTable(#"key", #"File", nil);
Rename the InfoPlist.strings file to Localizable.strings (double clic) and then you will get the correct string for that key.
In my case the issue was with the case of the string:
"bla.bla.blabla.BookSlot" whereas the Localizable.strings had it defined as "bla.bla.blabla.Bookslot"
So, double-check that the key string is in the correct case. Better yet, copy-paste.