Get target name (or icon name) in my code - iphone

Have been searching for this, I need to have a conditional statement in my objective C code based on the target, but I can't seem to find a direct way to get the target name from the code.
Have been trying to read the icon value from the bundle using:
NSLog(#"Icon File: %#",[[NSBundle mainBundle] objectForInfoDictionaryKey:#"icon"]);
which always return null.
Looking for a suggestion.
Thanks in advance!

Try
NSLog(#"Icon File: %#",[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleDisplayName"]);
That should give you the name that is displayed under the icon.

Related

Adding an Attribute to a Core Data Entity

this has beed discussed alot, but nothing that I found helped me... I just want to add a single attribute to a singe entity. Of cause without loosing my data.
To do that, I followed these steps
But I don't think it worked at all. There are no errors as long as not try to use the new attribute. But in my Core Data Model (when I open the .xcdatamodel in XCode) it's there and even in my NSManagedObject Subclass of the entity, the new attribute is there as a property. But when I try to use it, this happens:
unrecognized selector sent to instance 0x74f8520
or
the entity Name is not key value coding-compliant for the key "isFavoriteName".'
The key "isFavoriteName"is the one I just added.Like I said, I did all the steps. Do I miss something?
I think, that the new Model Version is not being used, because when I delete some attributes in the Model, my app still works and the deleted information are still shown... I have set the current Core Data Model Version the the new one (Step 6).
I hope you can help me!
Nick
EDIT: Do I may have to change something in code as well? Apart from the setting the options when creating persistentStoreCoordinator... Because I have, let's say myApp.xdatamodel and inside of that, i know have myApp.xdatamodel and myApp 2,xdatamodel... but I my code I sill do:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"myApp" withExtension:#"mom"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
That's right-- the page you linked to left out one step that applies in your case. Even though you created a new version of the model, your code is still loading the old one by name.
Don't just change it to load version 2 though. Do this instead:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"myApp" withExtension:#"momd"];
This will look in the momd folder and get whatever the current version is. In this case it will get version 2. If you change the model again in the future, it will get whatever version is current then.

fileExistsAtPath API always return NO

Following is my code I need check whether file present in document directory ,But following API does not return true at any condition but file is get created in document directory. Please check any thing wrong I am doing. I have searched on this other says this API "fileExistsAtPath" should work but it is not working in my case. Please do help me.
NSString *recordFile=[NSString stringWithFormat:#"MyFile.acc",data.uid];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentDr = [documentPaths objectAtIndex:0]; // WHY 0 ?
NSString *uniquePath = [documentDr stringByAppendingPathComponent:recordFile];
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
NSLog(#"File found")
}
else {
NSLog(#"No File to play");
}
Thanks,
Sony
Probably your path is incorrect. What should be the name of the files you are trying to find? If you have #"MyFile1.acc", #"MyFile2.acc" etc (where 1, 2 is the data.uid value) then try to use this:
NSString *recordFile=[NSString stringWithFormat:#"MyFile%i.acc",data.uid];
Try to append a "/" after documentDr when define uniquePath, or
NSString *recordFile = [NSString stringWithFormat:#"MyFile%#", data.uid];
...
if([NSBundle pathForResource:recordFile ofType:#"acc" inDirectory:documentDr])
the first wrong thing i note is the first instruction.
Why do you pass 'data.uid' as an argument to the format string ? Assuming 'data.uid' is some kind of integer, there should be at least '%d' in...
I had a look to Apple Documentation, in particular, that statement which says
The directory returned by this method may not exist.
You could try getting the current directory path using NSFileManager methods, and then testing for file existence (or create a directory at a place you can easily retrieve later).
What about the others paths ? You wrote 'WHY 0 ?', i'm asking the same question as you.Try looping over the array elements, testing each time for file existence.
The code should work. Your file most likely doesn't exist. Did you use capitalisation in your file name right when saving it?
Also right now, I still don't know what the file name is since, as already said, the first line in your initial post doesn't give the format string right.
Before checking try for existance try:
[[NSString stringWithString:#"test"] writeToFile: uniquePath atomically:YES];
That should create a file at the path and you see, that fileExists works.
I tried many things but ended up that I had to delete the app, clean all targets, and then rebuild again. It's weird that somehow my new resources doesn't get copied to the app. It usually happens to files that when I added them I selected "Create folder references for any added folders".

NSBundle returns nil

I wanted to read version information of my application from the plit file.
For this I am using a code as shown below.
NSString *myFilePath = [[NSBundle mainBundle]
pathForResource:#"MyApp-Info"
ofType:#"plist"];
// Format output
NSLog(#"%#",myFilePath);
The output
2010-08-31 17:14:10.095 MyApp[8759:20b] (null)
It always returns nil even if I tried to Import an existing file of type, text.txt still return nil, where text.txt is imported in the application.
I have goggled for the problem dont every one recommends to use NSBundel to read an pre imported file, but no use.
Any help, or an better way to read application version.
Got the solution via another link in the stack overflow here.
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
NSLog(#"%#",version);
The reason this doesn't work is because pathForResource looks for stuff inside "MyApp.app/Contents/Resources". The Info.plist file does not reside inside the resources folder, so it's going to return nil if you look for it there. The correct way to get at it is to use the "infoDictionary" method on NSBundle.

iPhone SDK: subFolders inside the main bundle

in the current project I have a number of folders, with subfolders, and these contain images: 01.png, 02.png.
Folder1/FolderA/f1.png
Folder1/FolderB/F1.png
When I compile the app, I looked inside the the .app and noticed that all the images are placed in the top level, with no sub-folders.
So clearly when trying to load the image this doesn't work:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"f1"
ofType:#"png"
inDirectory:#"Folder1/FolderA"];
But even more strangely, when loading image "f1", the image actually loads "F1"
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"f1.png"]];
Anyone have ideas on how to get around this problem?
Is there a compile option to create the folders in the app bundle?
TIA.
To create the subfolders inside the .app bundle, you should check the option "Create folder references for any added folders" rather than the default "Recursively create groups for any added folders"
Now in XCode, your imported folder appears blue rather than yellow. Build and go and you should see folders in your .app file.
First of all the folders you create in Xcode are simply organizational structures without any counterpart on the filesystem level. In other words all folders except for the "Classes" folder gets flatten out at the filesystem level. Therefore, even if you put your image file in the following location within xcode, it would still exist at the top-level in the filesystem: f1/f2/f3/f4/f5/image.png. Thus, in pathForResource method, you should not include the inDirectory argument.
As for the second issue, mac osx doesn't recognize case-sensitive file names. Therefore, f1 and F1 are equivalent to mac osx and will reference the same file. You can easily see this by executing the following 2 commands at a terminal session:
touch f
touch F
you'll notice that only 1 file exists after this: namely f. If you reverse the 2 commands, you still get one file, but it is named F.
ennuikiller is right. I think you can organize your images via Finder in subfolder and then refresh the image location in XCode by right clicking your image and selecting "Get Info" option. Then set the new directory.
Cheers.
Just wanted to add to Mugunth's answer, to follow up on part of the original question which was trying to use:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"f1" ofType:#"png" inDirectory:#"Folder1/FolderA"];
... to access files added using folder references. The above 'pathForResouce' call will work on simulators but not on actual iPhones (nil will be returned), because they don't seem to recognize subfolders in the 'inDirectory' part of the method. They do recognize them in the 'pathForResource' part, though. So the way of rephrasing the above so that it works on iPhones is:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"FolderA/f1" ofType:#"png" inDirectory:#"Folder1"];
I've followed your answer but it seams all files are stored flat on the root. If I use the code below to get the full path
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef url = CFBundleCopyResourceURL(mainBundle, CFSTR("About"), CFSTR("png"), NULL);
UInt8 filePath[PATH_MAX];
CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath));
I get as a result: /Users/iosif/Library/Application Support/iPhone Simulator/6.1/Applications/33FB4F79-999C-4455-A092-906A75226CDB/Arithmetics.app/About.png

How to display the current project version of my App to the user?

I would like to add the current version into the "about" section of my app.
As seen in this attached screenshot Apple offers versioning.
How do you display these settings in your app?
After further searching and testing, I found the solution myself.
NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSLog(#"%i Keys: %#", [infoDictionary count],
[[infoDictionary allKeys] componentsJoinedByString: #" ,"]);
This snipplet gave me the following output:
20 Keys : NSBundleResolvedPath ,CFBundleVersion ,NSBundleInitialPath ,CFBundleIdentifier ,NSMainNibFile ,CFBundleIconFile ,CFBundleInfoPlistURL ,CFBundleExecutable ,DTSDKName ,UIStatusBarStyle ,CFBundleDevelopmentRegion ,DTPlatformName ,CFBundleInfoDictionaryVersion ,CFBundleSupportedPlatforms ,CFBundleExecutablePath ,CFBundleDisplayName ,LSRequiresIPhoneOS ,CFBundlePackageType ,CFBundleSignature ,CFBundleName
So the solution is as simple as:
NSString *version =[[[NSBundle mainBundle] infoDictionary] valueForKey:#"CFBundleVersion"];
However, this is not the Current Project Version as seen in the screenshot but the Bundle Version of the plist file.
Look into your Info.plist file which should have keys like CFBundleVersion and CFBundleShortVersionString
Those items in the Build Info are not available to your built app. They are placeholders that you could possibly pull into your app. What is in your app is anything that you place in, say, the Resources folder of your app, like any text files, or plists, or a nice picture of your versioning engineer.
Now, you could pull some of the items in the Build Info window into a info.plist, using special identifiers, such as ${VERSION_INFO_PREFIX} or other token. The tokens are available if you click on any of the items on the left hand side in the window you have included above. For example, click on the word "Current Project Version" and copy the token that you see at the bottom, "CURRENT_PROJECT_VERSION". Then go to your plist file, and add an entry. Give it any name you want or "Current Project Version". Paste in ${CURRENT_PROJECT_VERSION} on the right hand side. Now that value is available to you from your app, programmatically. Of course, someone now has to enter that value into the appropriate place either in the Build Info window or elsewhere. It might just be easier just to manage this and fields like this in the info.plist file. It's up to you how you'd like to handle these things.
Here is how I get version info out of my info.plist:
+ (NSString *) getAppVersionNumber;
{
NSString *myVersion,
*buildNum,
*versText;
myVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleShortVersionString"];
buildNum = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
if (myVersion) {
if (buildNum)
versText = [NSString stringWithFormat:#"Version: %# (%#)", myVersion, buildNum];
else
versText = [NSString stringWithFormat:#"Version: %#", myVersion];
}
else if (buildNum)
versText = [NSString stringWithFormat:#"Version: %#", buildNum];
NSLog(versText);
return versText;
}
NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:#"CFBundleVersion"];
returns me always the same value(initial version) even if i change the version from the project settings but.
NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleShortVersionString"];
does the trick.
For the lazy here is the swift version :
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")!
NSBundle.mainBundle.infoDictionary[#"CFBundleShortVersionString"];