How to change localized images at run time - objective-c

I have created two localized directories named with en.lproj and fr.lproj. I put two different images with same name like.png in those localized directories.
Now i have created a table View Controller with two rows "English" and "French" text respectively.
After selecting first or second row i am fetching the bundle path and changing the whole localized text of my app at run time.
Code:
-(NSString*) languageSelectedStringForKey:(NSString*) key
{
NSString *path;
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
if([[userDefault valueForKey:#"language_Selected"] intValue] == 0)
path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
else if([[userDefault valueForKey:#"language_Selected"] intValue] == 1)
path = [[NSBundle mainBundle] pathForResource:#"fr" ofType:#"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString* str=[[languageBundle localizedStringForKey:key value:#"" table:nil] retain];
return str;
}
Through above code dynamically i can change the language of running app.
But how to get images from that bundle?
Any Idea?
Thanks

Presumably, you don't want to change every image, only the images that contain text or other culture-dependent content. For these images, you could add an entry to the localizable.strings file that contains the image path for a give language, and use this path instead of a hard-coded path.
That said, in many cases you'll have images included in the UI as part of a .xib. All you need to do in these cases is localize the xib (i.e. make a different version of the .xib per language--you can do this in XCode through the Languages control in the properties panel) and simply change the image in each language version of the .xib using Interface Builder.

Related

Reading Text File from Xcode Bundle

Why can't I read the content of foo.rtf? I've already put it in Xcode bundle. fileRoot still contains null.
NSString* filePath = #"foo";
NSString* fileRoot = [[NSBundle mainBundle] pathForResource:filePath ofType:#"rtf"];
NSLog(#"File root contains %#", fileRoot);
#TheAmateurProgrammer, Thank you for the diagram. I just added foo.rtf into the bundle resources. The result for fileRoot is still null. What step am I still missing?
Target's "Copy Bundle Resources" in Build Phases now contains foo.rtf. (I can't insert picture as I'm still a newbie).
(I will add the content reading after I can get fileRoot to point correctly).
You added the file, but is it really copied to your application bundle?
Make sure your rtf file is copied into your resource.
Secondly, you're only getting the path of the rtf, and not the contents of the rtf.
NSString *fileRoot = [[NSBundle mainBundle] pathForResource:filePath ofType:#"rtf"];
NSString *contents = [[[NSAttributedString alloc] initWithRTF:[NSData dataWithContentsOfFile:fileRoot] documentAttributes:NULL] string];
That will get the contents of the rtf.
First check that your file is present inside the bundle or not and if it present it must have same name as "foo.rtf".
You are getting nil because your file is not present directly inside in the bundle.
once you get the right file path you can get the content of your text file as a string by calling initWithContentsOfFile method on NSString class.

Loading local HTML into UIWebView on iOS not showing local images or styling

I'm having an issue getting local images and css stylesheet to show through on a local HTML page using UIWebView on an iPad app that will be using iOS 5.
The HTML page itself shows through and is laid out well, which is great. But the problem is it has blank squares where images should be coming through, and styling on text or anywhere isn't showing either.
I've come across very similar questions on SO where people have said to load the HTML into the view with the baseURL, which I then did using an answer from their question. But the images and style still did not come through.
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"htm" inDirectory:#"html_files"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[web loadHTMLString:htmlString baseURL:baseURL];
The UIWebView is put in place using Interface Builder and I have that in the .h file as #property(nonatomic, retain) IBOutlet UIWebView *web;
Inside my html_files folder I have:
index.htm
img (folder)
style (folder)
Using the following code, the log showed "index.htm", img, style which tells me it's keeping the directories the same, but I still even tried placing and then linking to images in the root of html_files but still nothing.
NSString *htmlPath = [path stringByAppendingPathComponent:#"html_files"];
NSArray *dirContents = [[NSFileManager defaultManager] directoryContentsAtPath:htmlPath];
NSLog(#"%#", dirContents);
And then within index.htm I'm linking to images like <img src="img/logo.jpg">
Any ideas would be much appreciated, thank you.
EDIT: Added link to project here: http://www.filedropper.com/localhtml (it's literally just a UIWebView with the HTML files so nothing big and messy)
Okay, here a re the mistakes you made, i said just use only image name in the img tag, you where using the path.
In iOS not mater how many folders you have, where ever you have the resources, it just adds all the resources in a single bundle.
Here is the link, check out i have made the changes only in index.htm

Drag Files come across Sandbox(__CFPasteboardIssueSandboxExtensionForPath)

I processed drag operation from browser view to custom view.It work well in snow lepoard,but not in Mountain Lion with sandbox.
in browser view:
NSMutableArray* urls = [[[NSMutableArray alloc] init] autorelease];
..............put some NSUrl to urls array....................
[pasteboard writeObjects:[NSArray arrayWithArray:urls]];
in my receive custom view:
NSArray* pasteboardItems = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSString class]] options:nil];
NSArray* pasteboardItems2 = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:nil];
NSArray* pasteboardItems3 = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSImage class]] options:nil];
NSLog(#"%#",pasteboardItems);
NSLog(#"%#",pasteboardItems2);
NSLog(#"%#",pasteboardItems3);
my log is:
2012-08-09 18:33:43.886 iCollage[6885:303] __CFPasteboardIssueSandboxExtensionForPath: error for [/Users/xxxx/Library/Containers/xxxxxxxxxxxx/Data/Downloads/1343902069.jpg]
2012-08-09 18:33:44.546 iCollage[6885:303] ( "file://localhost/Users/xxx/Library/Containers/xxxxxxxx/Data/Downloads/1343902069.jpg")
2012-08-09 18:33:44.547 iCollage[6885:303] ( "file://localhost/Users/xxxxx/Library/Containers/xxxxxx/Data/Downloads/1343902069.jpg")
2012-08-09 18:33:44.547 iCollage[6885:303] ()
my question is:
1.how to fix this error __CFPasteboardIssueSandboxExtensionForPath;I refer the docs and found nothing about that.I am ensuer that i have the permission to access the file!google says, may be "startAccessingSecurityScopedResource" will help me, then i try and failed
2.why pasteboardItems2 have value?i write to pasteboard only url but not string.It disgusted me that I can get the url both from NSString type and NSUrl type! (I try drag a file from iFinder, the url will only exist in pasteboardItems but not pasteboardItems2).Anybody know why? I think the first problem will auto fixed when some one help me fix this problem.
I believe Apple answer question 1:
Important: Although you can support dragging file paths, in general,
you should avoid doing so unless you are certain that the destination
app will never be run in an app sandbox. If you use an NSString, OS X
has no way to know whether that string should be interpreted as a
path; thus, OS X does not expand the destination app’s sandbox to
allow access to the file or directory at that location. Instead, use
an NSURL, a bookmark, or a filename pasteboard type.
WRT to question 2, it looks like you have pasted URLs so reading NSURL objects would seem to be correct. However I think you should implement the dragging using the following code (also from the link above):
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
int numberOfFiles = [files count];
// Perform operation using the list of files
}
return YES;
}
You need to generate security-scoped URL bookmark data on the sender side, and turn that data back into a URL on the receiver side. There's some other stuff you have to do after that when you want to actually access the URL; the documentation elaborates.
The receiving application, when running in a sandbox, will not be able to handle bare paths. This is a core part of being sandboxed; you are not allowed to use bare paths or their corresponding URLs to access files that aren't in your sandbox container and haven't been explicitly handed to you by the user.
Your pasteboardItems read object of NSString type, but you dragged a file(with jpg extension), you should register for NSString type in your init method:
[self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeString]];
You need to have Document Types defined in your application so that the sandboxing mechanism knows your application should be opening files with those extensions. You can do this by clicking the project on the left in Xcode, and in the Info tab, under Document Types add a new document type for each extension.
You just need to fill in the name and extensions field.
Also if you want to persist your permission to access the files dragged onto your application, you can use this class to wrap up all that logic. https://github.com/leighmcculloch/AppSandboxFileAccess

Folder in resources directory!

I have a folder named "test" in my resources. I have a lot of images in there. How can I load all the images in the folder "test" in an array?
I tried with:
testArr = [[NSArray alloc] initWithArray:[[NSBundle mainBundle] pathsForResourcesOfType:#"gif" inDirectory:#"Test"]];
But it doesn't work!
Thx for your help!
greez franhu
pathsForResourcesOfType:inDirectory: gets you the filenames. Assuming you want the actual images, you might do:
NSArray *fileNames = [[NSBundle mainBundle] pathsForResourcesOfType:#"gif" inDirectory:#"Test"];
for(NSString *fileName in fileNames)
{
// load the file here and put it in another array
}
Other things to check:
Open up your application bundle and verify that the Test directory exists in it.
If you're doing this on iOS, consider using [UIImage imageNamed:] instead, which will search your bundle for the image in question automatically.

What does it mean by references?

I'm taking a tutorial for X-code that says this:
"Go into the code and change the references from DrinkArray to DrinksDirections."
What exactly does it mean?
I would show you the tutorial, except it's a book that costs money.
The only reference I found of DrinkArray is:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"DrinkArray" ofType:#"plist"];
NSMutableArray* tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.drinks = tmpArray;
[tmpArray release];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
"Reference" is not a precise technical term in Objective-C, so what it means is whatever the author meant was thinking of when he wrote it. The term is sometimes used in "passed by reference" or "returned by reference," in which case "reference" means "pointer" — but that doesn't seem to be the usage here. Most likely the tutorial means to change places where your code mentions "DrinkArray" to instead say "DrinksDirections."
This is from Head First iPhone Development. The code in viewDidLoad that you found is where you want to make the change:
NSString *path = [[NSBundle mainBundle] pathForResource:#"DrinkArray"
ofType:#"plist"];
This line basically asks for the file path to the DrinkArray.plist bundled with the application. In the tutorial the next step is to migrate to a dictionary based array where each element contains a name, ingredients and directions.
Rather than typing out each entry by hand, they've provided a copy of the updated plist named DrinkDirections.plist in the book downloads. After downloading the sample files, copy the DrinkDirections.plist into your project Resources folder. Then change the line in viewDidLoad to
NSString *path = [[NSBundle mainBundle] pathForResource:#"DrinkDirections"
ofType:#"plist"];
This asks for the path to the DrinkDirections.plist that you've just added to your project. Be aware that your application will crash after making this change - that's OK, it's part of the tutorial and is covered in the immediately following pages.
okay, I figured it out. It wasn't DrinkDirections, it was DrinksDirections. It's stupid that a little thing can mess up a whole program.
The type of some declared reference variable is DrinkArray. It's telling you to change the type to DrinksDirection. Can you paste the code snippet?