I'm developing an app that should search a string inside the Plist data and return a value that should prompt the user what kind of, say brand it is. For example, the user inputs "iPhone" in my text field and the app should return the brand of the product the user inputted after tapping the Go button below the text field.
Inside my Products.plist, It contains arrays of brands with certain products that brand has. Example would be:
Apple: iPhone, iPod, iPad, Mac
Sony: PSP, PS3, Bravia, Xperia
Samsung: Galaxy S II, Galaxy S III, Galaxy Tab
How can I do this? I have already done my app working fine but without using a plist. I just want to use a Plist for the app to be easily maintained and updated.
Consider your plist file is called data.plist, this is how you should do this:
NSBundle *bundle = [NSBundle mainBundle];
NSString *pListpath = [bundle pathForResource:#"data" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:pListpath];
for (NSString* key in [dictionary allKeys]){
NSArray *array = [dictionary objectForKey:key];
for (int j = 0; j < [array count]; j++) {
if ([[array objectAtIndex:j] isEqualToString:#"iPhone"]) {
NSLog(#"%#",key);
}
}
}
Related
- (instancetype)initWithDestinationIndex:(NSUInteger)levelsIndex {
NSString* filepath = [[NSBundle mainBundle]
pathForResource:#"Levels" ofType:#"plist"];
NSDictionary *levels = [NSDictionary dictionaryWithContentsOfFile:filepath];
NSArray *levelsArray = levels[#"LevelsData"];
_data = levelsArray[levelsIndex];
[_verticalB setToInitialStateVertical];
return self;
}
I have a plist that is supposed to load information of 18 key-value pairs. The _data of type NSDictionary instance variable (when I run the program and put a breakpoint at that line _data = levelsArray[levelsIndex];) is almost always null, except on one occasion where it is actually had the 18 key-value pairs loaded. Any thoughts as to why it pretty much always is null?
I pass in 0 for my levelsIndex, and the 'LevelsData' is the NSArray that holds the 18 key-value pair dictionaries.
if your _data is NSMutableDictionary use the below code,
NSMutableDictionary *_data = [[NSMutableDictionary alloc] init];
[_data setObject:[levelsArray objectAtIndex: levelsIndex] forKey:[NSString stringWithFormat:#"%d", levelsIndex]];
or
for(int i=0; i<[levelsArray count]; i++){
[_data setObject:[levelsArray objectAtIndex:i] forKey:[NSString stringWithFormat:#"%d",i]];
}
hope its helpful
It may possible that, you are running app in a "release" scheme. Have you double check? As long as you're getting the result.
To check,
Click on Project Name next to [Run] button. > Edit Scheme > Run > Build Configuration > Debug/Release
I want to detect when another application was installed/uninstalled and save the time to a database at the moment of execution.
I know this is possible in Android using broadcastreceiver and I want to know if this can be done in iOS using a jailBroken device because I believe this is not possible in a non-jailBroken device.
I hope someone could help me. Thank you.
Recently was having the same problem.
You need to write SpringBoard tweak. In it you observe notification SBInstalledApplicationsDidChangeNotification from local notification center (CFNotificationCenterGetLocalCenter or [NSNotificationCenter defaultCenter]). User info dictionary will contain:
SBInstalledApplicationsRemovedBundleIDs key contains array of bundle IDs of uninstalled applications.
SBInstalledApplicationsModifiedBundleIDs key contains array of bundle IDs of updated applications.
SBInstalledApplicationsAddedBundleIDs key contains array of bundle IDs of installed applications.
Obviously that way you can log every time applications are installed/uninstalled/updated.
You can check if an application is installed by using its bundle id
BOOL isInstalled = [[LSApplicationWorkspace defaultWorkspace] applicationIsInstalled:#"com.app.identifier"];
if (isInstalled) {
// app is installed }
else {
// app is not installed
}
EDIT:
If you want to check if an application got installed you can maybe count the items inside user of com.apple.mobile.installation.plist it holds all the information about installed apps.
You can write the number of apps inside a plist then later check back and compare the results?
// get apps count
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:#"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"];
int numberOfApps = [[dict objectForKey: #"User"] count];
NSLog(#"Count: %i",numberOfApps);
// Save apps count inside a plist
NSString *path = #"/var/mobile/AppsCount.plist";
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableDictionary *data;
if ([fm fileExistsAtPath:path]) {
data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
}
else {
// If the file doesn’t exist, create an empty dictionary
data = [[NSMutableDictionary alloc] init];
}
[data setObject:[NSNumber numberWithInt:numberOfApps] forKey:#"savedAppsCount"];
[data writeToFile:path atomically:YES];
[data release];
And then to compare old counts with the new apps count:
// get current number of apps
NSString *path = #"/var/mobile/AppsCount.plist";
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:#"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"];
int numberOfApps = [[dict objectForKey: #"User"] count];
// retrieve old app count and compare to new ones
NSMutableDictionary *retrieveCounts = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
int oldAppCount = [[retrieveCounts objectForKey:#"savedAppsCount"] intValue];
if (oldAppCount < numberOfApps) {
NSLog(#"NEW APP GOT INSTALLED");
}
else if (oldAppCount > numberOfApps) {
NSLog(#"AN APP GOT UNINSTALLED");
}
else {
NSLog(#"NOTHING GOT INSTALLED OR UNINSTALLED");
}
[retrieveCounts release];
But that doesn't give you the time, it just checks if a new app got installed
There might be a better way of doing that, but that's what came into my mind.
Hope it helps.
What am I doing wrong? Trying to read Info.plist of Calendar.app into an array but I get nil array. Here is my code:
NSBundle* xyzbundle = [NSBundle bundleWithPath:#"/Applications/Calendar.app/Contents"];
// Path to the plist
NSString *path = [xyzbundle pathForResource:
#"Info" ofType:#"plist"];
// Build the array from the plist
NSMutableArray *array2 = [[NSMutableArray alloc] initWithContentsOfFile:path];
// Show the string values
for (NSString *str in array2)
NSLog(#"--%#", str);
Thank you for your help.
You cant do it. iOS kernel creates a sandbox environment for each of the application. Any application can not read/write data of other application. There are some possible exceptions but in general you cant do it.
Trying to read a plist and change my font color depending on the option that was selected in the following settings bundle.
The following is how I am trying to accomplish it:
NSString *path = #"/var/mobile/Library/Preferences/NCNotes.plist";
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
fontSize = [[dict objectForKey:#"slideSwitched"] floatValue];
if ([[dict objectForKey:#"noteColor"] valueForKey:#"Purple"]) {
noteView.textColor = [UIColor purpleColor];
} else {
noteView.textColor = [UIColor blackColor];
}
Any ideas why this is why my app is crashing? How do I read the values and change the color depending on what was selected?
It appears that the top level of your plist is an array, not a dictionary, because at the top it says "Item 1" where all of your content is within that. So you have a dictionary within an array. So you can change your code like this:
NSString *path = #"/var/mobile/Library/Preferences/NCNotes.plist";
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
NSDictionary *dict = array[0];
You could also change the structure of your plist so that you have a dictionary as the root instead of an array.
Also, keys are supposed to be on the left-hand side and their values on the right-hand side, so I don't see a key "noteColor". You have a key "key" with a value "noteColor", so you'll need to make that correction. I'm also not seeing a "slideSwitched" key, though it might just be outside the bounds of your screenshot.
Also the following won't work:
[[dict objectForKey:#"noteColor"] valueForKey:#"Purple"]
Whatever you get from [dict objectForKey:#"noteColor"] isn't going to be a dictionary, so calling valueForKey: on that isn't going to give you what you want.
simply you should do this with document directory
NSString *contentPath=[[NSBundle mainBundle] pathForResource:#"PLIST_FILE_NAME" ofType:#"plist"];
NSDictionary *dictionary=[NSDictionary dictionaryWithContentsOfFile:contentPath];
write your logic after this, wait a minute , its seems like you dont have a key "noteColor" also. check your plist
Here is some example code documented up the wazoo. Hopefully it will help you understand how these plists and dictionaries work. Everything will be based on your plist file (which could definitely be improved upon, but that's up to you as I don't know your specific situation).
Your question is "How do I find color based on user selection?" I will assume you get the user selection as an int. Something like "User selected 7".
//Load your plist dictionary
NSString *path = #"/var/mobile/Library/Preferences/NCNotes.plist";
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
//Get the array of validValues and the array of validTitles
NSArray *valuesArray = [dict objectForKey:#"validValues"];
NSArray *titlesArray = [dict objectForKey:#"validTitles"];
//Now get the user selected index from the validValues array
int arraySelection = -1;
for(int i = 0; i < [valuesArray count]; i++)
{
NSNumber *number = [valuesArray objectAtIndex:i];
if([number intValue] == userSelectedInput)
{
arraySelection = i;
break;
}
}
if(arraySelection == -1)
{
//Not found in array
return;
}
//Now with that index get the title of the object that the user selected
NSString *userSelectedTitle = [titlesArray objectAtIndex:arraySelection];
//Now do your checking on what the user selected based on that:
if([userSelectedTitle isEqualToString:#"Purple"])
...
You could boil this down quite a bit. Currently your validValues array is completely useless. If it were out of order or missing numbers then it would be needed, but straight counting can be achieved by the validTitles array.
How could I have a complete list of each .plist path (inside iPhone/iPad) ?
In iOS Simulator I'm using it : ls -l ~/Library/Preferences/com.apple.*.plist
My goal is to find a specific key and read the boolean value in preferences.
Because I need to know if it is enable or not.
It is something that is missing in SDK but is existing in preferences.
NSLog (#"%#", [[NSBundle mainBundle] pathsForResourcesOfType:#"plist" inDirectory:#"/"]);
The method returns an NSArray.
You need to create the plist first. All you have to do is access it when you need it.
NSArray *thePlist;
NSString *plist = [[NSBundle mainBundle] pathForResource: #"plistFileName" ofType: #"plist"];
thePlist = [[NSArray alloc] initWithContentsOfFile: plist];
Thank you Daniel A. White , Jahm and Kedar!
I code this to summarize each comment :
With an extra, add an example to read UISupportedInterfaceOrientations values.
NSLog(#"Preferences plists from apple (inside iPhone/iPad) are not accessible from code");
NSLog (#"Accessible plist paths : %#", [[NSBundle mainBundle] pathsForResourcesOfType:#"plist" inDirectory:#"/"]);
NSArray *pList = [[NSBundle mainBundle] pathsForResourcesOfType:#"plist" inDirectory:#"/"];
for (int i = 0; i < [pList count]; i ++)
{
NSString *plistPath = [pList objectAtIndex:i];
NSDictionary *plistDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSMutableArray *nameString = [plistDictionary objectForKey:#"UISupportedInterfaceOrientations"];
for (NSString *n in nameString)
{
NSLog(#"Supported Interface : %#",n);
}
}