When I change the app used language independently on the device language it doesn't take effect until I close the app and restart it. How to not require app to be restarted for loading all nib files and .strings files again depending on the selected language?
I use this to change language at runtime:
NSArray* languages = [NSArray arrayWithObjects:#"ar", #"en", nil];
[[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
This works for me :
Swift 4 :
Create a file named BundleExtension.swift and add the following code to it -
var bundleKey: UInt8 = 0
class AnyLanguageBundle: Bundle {
override func localizedString(forKey key: String,
value: String?,
table tableName: String?) -> String {
guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,
let bundle = Bundle(path: path) else {
return super.localizedString(forKey: key, value: value, table: tableName)
}
return bundle.localizedString(forKey: key, value: value, table: tableName)
}
}
extension Bundle {
class func setLanguage(_ language: String) {
defer {
object_setClass(Bundle.main, AnyLanguageBundle.self)
}
objc_setAssociatedObject(Bundle.main, &bundleKey, Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
Now whenever you need to change the language call this method :
func languageButtonAction() {
// This is done so that network calls now have the Accept-Language as "hi" (Using Alamofire) Check if you can remove these
UserDefaults.standard.set(["hi"], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
// Update the language by swaping bundle
Bundle.setLanguage("hi")
// Done to reintantiate the storyboards instantly
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
UIApplication.shared.keyWindow?.rootViewController = storyboard.instantiateInitialViewController()
}
I had a similar requirement for a Kiosk mode iPad app with tabbed navigation. Not only did the app need to support on-the-fly language changes, but had to do so knowing that most of the tabs were already loaded from the nibs since the app was only restarted (on average) about once a week when a new version was loaded.
I tried several suggestions to leverage the existing Apple localization mechanisms and they all had serious drawbacks, including wonky support in XCode 4.2 for localized nibs -- my IBoutlet connection variables would appear to be set correctly in IB, but at runtime they would often be null!?
I wound up implementing a class that mimicked the Apple NSLocalizedString class but which could handle runtime changes, and whenever a language change was made by a user my class posted a notification. Screens that needed localized strings (and images) to change declared a handleLocaleChange method, which was called at viewDidLoad, and whenever the LocaleChangedNotification was posted.
All of my buttons and graphics were designed to be language independent, although the title text and label text was typically updated in response to locale changes. If I had to change images, I could have done so in the handleLocaleChange methods for each screen, I suppose.
Here is the code. It includes some support for nib/bundle paths which I actually don't use in the final project.
MyLanguage.h
//
// MyLanguage.h
//
//
#import <Foundation/Foundation.h>
#define DEFAULT_DICTIONARY_FOR_STRINGS #""
#define ACCESSING_ALTERNATE_DICTIONARY_SETS_DEFAULT 1
#define LANGUAGE_ENGLISH_INT 0
#define LANGUAGE_SPANISH_INT 1
#define LANGUAGE_ENGLISH_SHORT_ID #"en"
#define LANGUAGE_SPANISH_SHORT_ID #"es"
#define LANGUAGE_CHANGED_NOTIFICATION #"LANGUAGE_CHANGED"
#interface MyLanguage : NSObject
{
NSString *currentLanguage;
NSDictionary *currentDictionary;
NSBundle *currentLanguageBundle;
}
+(void) setLanguage:(NSString *)languageName;
+(NSString *)stringFor:(NSString *)srcString forLanguage:(NSString *)languageName;
+(NSString *)stringFor:(NSString *)srcString;
+ (MyLanguage *)singleton;
#property (nonatomic, retain) NSBundle *currentLanguageBundle;
#property (nonatomic, retain) NSString *currentLanguage;
#property (nonatomic, retain) NSDictionary *currentDictionary;
#end
MyLanguage.m:
//
// MyLanguage.m
#import "MyLanguage.h"
#import "Valet.h"
#define GUI_STRING_FILE_POSTFIX #"GUIStrings.plist"
#implementation MyLanguage
#synthesize currentLanguage;
#synthesize currentDictionary;
#synthesize currentLanguageBundle;
+(NSDictionary *)getDictionaryNamed:(NSString *)languageName
{
NSDictionary *results = nil;
// for now, we store dictionaries in a PLIST with the same name.
NSString *dictionaryPlistFile = [languageName stringByAppendingString:GUI_STRING_FILE_POSTFIX];
NSString *plistBundlePath = [Valet getBundlePathForFileName:dictionaryPlistFile];
if ( [[NSFileManager defaultManager] fileExistsAtPath:plistBundlePath] )
{
// read it into a dictionary
NSDictionary *newDict = [NSDictionary dictionaryWithContentsOfFile:plistBundlePath];
results = [newDict valueForKey:#"languageDictionary"];
}// end if
return results;
}
+(NSString *)stringFor:(NSString *)srcString forDictionary:(NSString *)languageName;
{
MyLanguage *gsObject = [MyLanguage singleton];
// if default dictionary matches the requested one, use it.
if ([gsObject.currentLanguage isEqualToString:languageName])
{
// use default
return [MyLanguage stringFor:srcString];
}// end if
else
{
// get the desired dictionary
NSDictionary *newDict = [MyLanguage getDictionaryNamed:languageName];
// default is not desired!
if (ACCESSING_ALTERNATE_DICTIONARY_SETS_DEFAULT)
{
gsObject.currentDictionary = newDict;
gsObject.currentLanguage = languageName;
return [MyLanguage stringFor:srcString];
}// end if
else
{
// use current dictionary for translation.
NSString *results = [gsObject.currentDictionary valueForKey:srcString];
if (results == nil)
{
return srcString;
}// end if
return results;
}
}
}
+(void) setLanguage:(NSString *)languageName;
{
MyLanguage *gsObject = [MyLanguage singleton];
// for now, we store dictionaries in a PLIST with the same name.
// get the desired dictionary
NSDictionary *newDict = [MyLanguage getDictionaryNamed:languageName];
gsObject.currentDictionary = newDict;
gsObject.currentLanguage = languageName;
// now set up the bundle for nibs
NSString *shortLanguageIdentifier = #"en";
if ([languageName contains:#"spanish"] || [languageName contains:#"espanol"] || [languageName isEqualToString:LANGUAGE_SPANISH_SHORT_ID])
{
shortLanguageIdentifier = LANGUAGE_SPANISH_SHORT_ID;
}// end if
else
shortLanguageIdentifier = LANGUAGE_ENGLISH_SHORT_ID;
// NSArray *languages = [NSArray arrayWithObject:shortLanguageIdentifier];
// [[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
//
NSString *path= [[NSBundle mainBundle] pathForResource:shortLanguageIdentifier ofType:#"lproj"];
NSBundle *languageBundle = [NSBundle bundleWithPath:path];
gsObject.currentLanguageBundle = languageBundle;
[[NSNotificationCenter defaultCenter] postNotificationName:LANGUAGE_CHANGED_NOTIFICATION object:nil];
}
+(NSString *)stringFor:(NSString *)srcString;
{
MyLanguage *gsObject = [MyLanguage singleton];
// default is to do nothing.
if (gsObject.currentDictionary == nil || gsObject.currentLanguage == nil || [gsObject.currentLanguage isEqualToString:DEFAULT_DICTIONARY_FOR_STRINGS] )
{
return srcString;
}// end if
// use current dictionary for translation.
NSString *results = [gsObject.currentDictionary valueForKey:srcString];
if (results == nil)
{
return srcString;
}// end if
return results;
}
#pragma mark -
#pragma mark Singleton methods
static MyLanguage *mySharedSingleton = nil;
-(void) lateInit;
{
}
// PUT THIS METHOD DECLARATION INTO THE HEADER
+ (MyLanguage *)singleton;
{
if (mySharedSingleton == nil) {
mySharedSingleton = [[super allocWithZone:NULL] init];
[mySharedSingleton lateInit];
}
return mySharedSingleton;
}
+ (id)allocWithZone:(NSZone *)zone
{ return [[self singleton] retain]; }
- (id)copyWithZone:(NSZone *)zone
{ return self; }
- (id)retain
{ return self; }
- (NSUInteger)retainCount //denotes an object that cannot be released
{ return NSUIntegerMax; }
- (oneway void)release //do nothing
{ }
- (id)autorelease
{ return self; }
#end
Don't rely on strings that you have set in your nib file. Use your nib only for layout & setup of views. Any string that is shown to the user (button text, etc) needs to be in your Localizable.strings files, and when you load your nib you need to set the text on the corresponding view/control accordingly.
To get the bundle for the current language:
NSString *path = [[NSBundle mainBundle] pathForResource:currentLanguage ofType:#"lproj"];
if (path) {
NSBundle *localeBundle = [NSBundle bundleWithPath:path];
}
And to use the bundle to obtain your localized strings:
NSLocalizedStringFromTableInBundle(stringThatNeedsToBeLocalized, nil, localeBundle, nil);
Also for date formatting, you might want to look into
[NSDateFormatter dateFormatFromTemplate:#"HH:mm:ss"" options:0 locale:locale];
To use that you will need to create a NSLocale for the corresponding language/country which you wish to use.
Heres what I did. I guess the trick was to use NSLocalizedStringFromTableInBundle instead of NSLocalizedString.
For all strings, use this
someLabel.text = NSLocalizedStringFromTableInBundle(#"Your String to be localized, %#",nil,self.localeBundle,#"some context for translators");
To change language, run this code
NSString * language = #"zh-Hans"; //or whatever language you want
NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:#"lproj"];
if (path) {
self.localeBundle = [NSBundle bundleWithPath:path];
}
else {
self.localeBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"] ];
}
After this, you will likely want to call whatever update code to update the strings to the new languages, for e.g. run this again
someLabel.text = NSLocalizedStringFromTableInBundle(#"Your String to be localized, %#",nil,self.localeBundle,#"some context for translators");
Thats all. No need restart app. Compatible with system settings as well (if you set a language through iOS settings, it will work too). No need external library. No need jailbreak. And it works with genstrings too.
Of course, you should still do the usual for your app settings to persist:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"zh-Hans", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
(and do a check in your viewDidLoad or something)
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:#"lproj"];
if (path) {
self.localeBundle = [NSBundle bundleWithPath:path];
}
else {
self.localeBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"] ];
}
You should create your own macro similar to NSLocalizedString but bases the bundle it chooses a string from on a NSUserDefaults value you set (i.e. don't worry about what the value of apples language defaults value is)
When you change the language you should send out a notification, which view controllers, views etc should listen for and refresh themselves
Related
I created a Localizable.strings file in XCode and then 2 languages in it.(english + Arabic )
I filled up these files with the language translations, but the just show translation in english, when I start with Arabic the key appear!
in my code :
NSLocalizedString("title", comment: "")
Localizable.strings(english)
"title" = "Error" ;
Localizable.strings(Arabic)
"title" = "خطأ" ;
I careated sample one and tried in Objective C.I got it.
I set "title" = "خطأ" in Arabic Localization files
"title" = "عنوان";
Now I have to change English to Arabic.
First I set the design in storyboard
Then Click Project.Choose Localization in Info
If you click the +(Below Localization) it shows the pop up view
Now choose Arabic.When click Arabic it shows window.You should click finish.
We need to create the string file for the localization now.I set string file name as LocalizationArabic
Once you create the String file it looks like below.
Then click File Inspector when pressing LocalizationArabic string file.Now click the Localization.It shows Empty Check box Arabic and English like below.
Here we must check the check box.Also when we check the check box the LocalizationArabic folder creates with three string files like below
Then I entered the language which I want to translate from English to Arabic in string file.
Finally I created the Header file for the Localization Language
The Header file name is LanguageHeader.It looks like below.
Now the code part starts here
First the Localization class of NSObject class
Localization.h
#import <Foundation/Foundation.h>
#import "LanguageHeader.h"
#interface Localization : NSObject
+(Localization *)sharedInstance;
+(NSString*) strSelectLanguage:(int)curLang;
+(NSString*) languageSelectedStringForKey:(NSString*) key;
#end
Localization.m
#import "Localization.h"
int currentLanguage,selectedrow;
#implementation Localization
+(Localization *)sharedInstance
{
static Localization *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Localization alloc] init];
});
return sharedInstance;
}
+(NSString*) strSelectLanguage:(int)curLang{
if(curLang==ARABIC){
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"ar", nil]forKey:#"AppleLanguages"];
}
else{
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en", nil]forKey:#"AppleLanguages"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
currentLanguage=curLang;
NSString *strLangSelect = [[[NSUserDefaults standardUserDefaults]objectForKey:#"AppleLanguages"] objectAtIndex:0];
return strLangSelect;
}
+(NSString*) languageSelectedStringForKey:(NSString*) key
{
NSString *path;
NSString *strSelectedLanguage = [[[NSUserDefaults standardUserDefaults]objectForKey:#"AppleLanguages"] objectAtIndex:0];
//When we check with iPhone,iPad device it shows "en-US".So we need to change it to "en"
strSelectedLanguage = [strSelectedLanguage stringByReplacingOccurrencesOfString:#"en-US" withString:#"en"];
if([strSelectedLanguage isEqualToString:[NSString stringWithFormat: #"en"]]){
currentLanguage=ENGLISH;
selectedrow=ENGLISH;
path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
}
else{
currentLanguage=ARABIC;
selectedrow=ARABIC;
path = [[NSBundle mainBundle] pathForResource:#"ar" ofType:#"lproj"];
}
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString* str=[languageBundle localizedStringForKey:key value:#"" table:#"LocalizationArabic"];
return str;
}
#end
Then ViewController.h
#import <UIKit/UIKit.h>
#import "Localization.h"
#interface ViewController : UIViewController{
Localization *localization;
}
#property (strong, nonatomic) IBOutlet UILabel *lblTitle;
- (IBAction)actionChangeLanguageToArabic:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize lblTitle;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
localization = [Localization sharedInstance];
lblTitle.text = [Localization languageSelectedStringForKey:#"title"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionChangeLanguageToArabic:(id)sender {
[Localization strSelectLanguage:ARABIC];
lblTitle.text = [Localization languageSelectedStringForKey:#"title"];
}
#end
Above code works perfectly.
Output Screen shot are below
When run the app first
After clicking the button
I am creating one sample demo for changing label Language when button pressed using localization.
I have tried so many times but could not able to display different language.
My Question is I want change my Language English to other language.
I have already create Localizable.string file but not able to change language.
NOTE:Do not change system(simulator)language.
You can create a Helper class. See the class I'm using below.
LocalizeHelper.h
#import <Foundation/Foundation.h>
// some macros (optional, but makes life easy)
// Use "LocalizedString(key)" the same way you would use "NSLocalizedString(key,comment)"
#define LocalizedString(key) [[LocalizeHelper sharedLocalSystem] localizedStringForKey:(key)]
// "language" can be (for american english): "en", "en-US", "english". Analogous for other languages.
#define LocalizationSetLanguage(language) [[LocalizeHelper sharedLocalSystem] setLanguage:(language)]
#define LocalizationGetLanguage() [[LocalizeHelper sharedLocalSystem] getLanguage]
#interface LocalizeHelper : NSObject
// a singleton:
+ (LocalizeHelper*) sharedLocalSystem;
// this gets the string localized:
- (NSString*) localizedStringForKey:(NSString*) key;
//set a new language:
- (void) setLanguage:(NSString*) lang;
//get current language
- (NSString *)getLanguage;
#end
LocalizeHelper.m
#import "LocalizeHelper.h"
#import "Constants.h"
// Singleton
static LocalizeHelper* SingleLocalSystem = nil;
// my Bundle (not the main bundle!)
static NSBundle* myBundle = nil;
#implementation LocalizeHelper
//-------------------------------------------------------------
// allways return the same singleton
//-------------------------------------------------------------
+ (LocalizeHelper*) sharedLocalSystem {
// lazy instantiation
if (SingleLocalSystem == nil) {
SingleLocalSystem = [[LocalizeHelper alloc] init];
}
return SingleLocalSystem;
}
//-------------------------------------------------------------
// initiating
//-------------------------------------------------------------
- (id) init {
self = [super init];
if (self) {
// use systems main bundle as default bundle
myBundle = [NSBundle mainBundle];
}
return self;
}
//-------------------------------------------------------------
// translate a string
//-------------------------------------------------------------
// you can use this macro:
// LocalizedString(#"Text");
- (NSString*) localizedStringForKey:(NSString*) key {
// this is almost exactly what is done when calling the macro NSLocalizedString(#"Text",#"comment")
// the difference is: here we do not use the systems main bundle, but a bundle
// we selected manually before (see "setLanguage")
return [myBundle localizedStringForKey:key value:#"" table:nil];
}
//-------------------------------------------------------------
// set a new language
//-------------------------------------------------------------
// you can use this macro:
// LocalizationSetLanguage(#"German") or LocalizationSetLanguage(#"de");
- (void) setLanguage:(NSString*) lang {
// path to this languages bundle
NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:#"lproj" ];
if (path == nil) {
// there is no bundle for that language
// use main bundle instead
myBundle = [NSBundle mainBundle];
} else {
// use this bundle as my bundle from now on:
myBundle = [NSBundle bundleWithPath:path];
// to be absolutely shure (this is probably unnecessary):
if (myBundle == nil) {
myBundle = [NSBundle mainBundle];
}
}
[[NSUserDefaults standardUserDefaults] setObject:lang forKey:#"lang"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//-------------------------------------------------------------
// get current language
//-------------------------------------------------------------
- (NSString *)getLanguage {
return [[NSUserDefaults standardUserDefaults] objectForKey:#"lang"];
}
#end
When you want to change the language from your app call this function LocalizationSetLanguage(#"fr");.
In order to get a localized string, call LocalizedString(#"string");.
This question already has answers here:
Change Language in the app programmatically in iOS
(3 answers)
Closed 6 years ago.
In my iOS app I need an option to change language. Can we change it without changing the language in the device settings
You can use following code to set the language
- (void) setLanguage:(NSString*) lang {
NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:#"lproj"];
if (path == nil) {
myBundle = [NSBundle mainBundle];
} else {
myBundle = [NSBundle bundleWithPath:path];
}
if (myBundle == nil) {
myBundle = [NSBundle mainBundle];
}
}
And after that you can get the localizations with
- (NSString*) localizedStringForKey:(NSString*) key {
return [myBundle localizedStringForKey:key value:#"" table:nil];
}
For example store different static json/plist and etc in your app with different languages strings and when you switch option parse this and set to labels.
i am not sure but try this code once using NSUserDefaults
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray* languages = [userDefaults objectForKey:#"AppleLanguages"];
[languages insertObject:#"de" atIndex:0]; // ISO639-1
[[NSUserDefaults standardUserDefaults] synchronize];
I have a project divided in layers, and the bottom one is included in the top one as a static lib.
The thing is that I need to localize a string in the static lib, using the translations present in my app (upper layer).
Is this possible somehow?
The way I managed to do this is loading the strings from a bundle instead of using NSLocalizedString:
+ (NSString *)getTranslationFromAppBundleForString:(NSString *)originalText {
NSString * lang = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString * bundlePath = [[NSBundle mainBundle] pathForResource:lang ofType:#"lproj"];
NSBundle * bundle = [NSBundle bundleWithPath:bundlePath];
return [bundle localizedStringForKey:originalText value:originalText table:nil];
}
You can create an LanguageAgent in your static library, add a bundle ressource in that library. Then use a function like this to get localizedString. In my application, I separate language by different table (see picture below for a table named 'Dictionaire'. You can have more than 1 table in your languages bundle.
-(NSString*) myLocalizedStringForKey:(NSString*) key ofTable:(NSString*)tableName {
//I save selected language in my NSUserDefaults.
NSString *selectedLanguage = [[NSUserDefaults standardUserDefaults] stringForKey:#"DefaultLanguage"];
if (selectedLanguage == nil) {
[[NSUserDefaults standardUserDefaults] setValue:#"en" forKey:#"DefaultLanguage"];
[[NSUserDefaults standardUserDefaults] synchronize];
selectedLanguage = [[NSUserDefaults standardUserDefaults] stringForKey:#"DefaultLanguage"];
}
NSString *langBundleNew = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingFormat:#"/langs/Languages.bundle/%#.lproj/",selectedLanguage]; //use your path to the Languages.bundle here.
if ([[NSFileManager defaultManager] fileExistsAtPath:langBundleNew]) {
NSBundle *aBundle = (NSBundle*)[self.dictLangueBundle objectForKey:selectedLanguage];
NSString* str=[aBundle localizedStringForKey:key value:#"[string not defined]" table:tableName];
return str;
} else {
return #"[]";
}
}
My language bundle is similar like this: ('Dictionaire' = name of the table)
Here is a sample of content in my Dictionnaire.strings for 'en.lproj':
I moved some code that will be used multiple times into a class.
I'm not getting errors, but I'm also not getting results. It seems to skip over my class completely.
Ideally, this class is supposed to do NSURL conns and XMLParser stuff to chew up the data feed from our hosting API. I already have this working but wanted to congeal and somewhat normalize/centralize some of the main logic of my code.
The one function 'bdCheckIfFileExistsAndisValid' is supposed to take a string but return BOOL and it isn't being called at all.
Neither is 'bdParsePlaylistXML' that is supposed to take a string and return an array.
I put breakpoints everywhere in my class and none are hit.
I'm new so I'm not sure if I did everything right. Here's some code, thanks in advance.
--------------------CUSTOM CLASS:(.h)
#interface bdXMLParser : NSObject {
NSMutableArray *playlist;
//Playlist XML info
BOOL recordTrackName;
BOOL recordTrackDescription;
BOOL recordTrackThumbnailAbsoluteLocation;
BOOL recordTrackURL;
NSString *TrackName;
NSString *TrackDescription;
NSString *TrackThumbnailAbsoluteLocation;
NSString *TrackURL;
}
-(NSMutableArray*) bdParsePlaylistXML:(NSString *) playlistXMLFileName;
-(BOOL) bdCheckIfFileExistsAndisValid:(NSString *) localFileName;
----------------CUSTOM CLASS (.m):
#import "bdXMLParser.h"
#implementation bdXMLParser
{
NSMutableData *webData;
NSMutableArray *playlist;
NSXMLParser *xmlParserPlaylist;
}
-(NSString*) bdDocumentsDirectory{
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return documentsPath;
}
-(int) bdCheckFileCreationDate:(NSString *) fileName {
//get XML file path
NSString *localFilePath = [[self bdDocumentsDirectory] stringByAppendingPathComponent:fileName];
//local file check
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSDictionary* attrs = [filemgr attributesOfItemAtPath:localFilePath error:nil];
NSDate *fileCreationDate = [attrs objectForKey: NSFileCreationDate];
NSDate *rightNow = [NSDate date];
NSTimeInterval lastDiff = [fileCreationDate timeIntervalSinceNow];
int lastDiffINT = round(lastDiff);
NSLog(#"NSFileCreationDate:%#",fileCreationDate);
NSLog(#"CurrentDate:%#",rightNow);
NSLog(#"lastDiff:%f",lastDiff);
return lastDiffINT;
}
-(BOOL) bdCheckIfFileExistsAndisValid:(NSString *) fileName {
//local file check
NSString* foofile = [[self bdDocumentsDirectory] stringByAppendingPathComponent:fileName];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
if ((fileExists == YES) && ([self bdCheckFileCreationDate:foofile] > -86400))//(24 hrs = 86400 seconds)
return YES;
else
return NO;
}
HERE's THE VIEW WHERE I'M TRYING TO USE IT:(menu.h)
#import "bdXMLParser.h"
#interface MenuScreenViewController : UIViewController <NSXMLParserDelegate>
- (IBAction)btnPlayerPlayPause:(id)sender;
(menu.m)
- (IBAction)btnPlayerPlayPause:(id)sender {
//if array exists, don't reload xml, dont reparse xml, just go to the view
if (playlist.count == 0){
//Playlist!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//========================================================================
//1st: check to see if we have a local cached xml data
//if we do, check if it is <24hr old and if so load it
//if not, go get it with connection and overwrite/store it
//init blogs NSMutableArray
playlist = [[NSMutableArray alloc] init];
//local file check
bdXMLParser *myParser;
BOOL fileExistsAndValid = NO;
=HERE!==fileExistsAndValid = [myParser bdCheckIfFileExistsAndisValid:PlaylistName];
//1st
if (fileExistsAndValid)//(<24 hrs old)
{
NSLog (#"File fileExistsAndValid");
=AND HERE!!=playlist = [myParser bdParsePlaylistXML:PlaylistName];
NSLog(#"playlist:%u", playlist.count);
//load first track
[self LoadTrack:0];
}
else{
NSLog (#"File doesn't exist");
//call refresh function
//[self refreshAlbumPhotoXML];
[myParser bdRefreshPlaylistXML];
}
}
}
you forgot initing the class
bdXMLParser *myParser= [[bdXMLParster alloc]init];