Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 221 lines (179 sloc) 7.139 kb
dc5be1c Initial check-in.
uli authored
1 //
2 // NSDictionary+LocalizedObjectForKey.m
3 // Shovel
4 //
5 // Created by Uli Kusterer on Tue Sep 07 2004.
720b0e7 @uliwitness Added licensing information to the source files.
authored
6 // Copyright (c) 2004 M. Uli Kusterer.
7 //
8 // This software is provided 'as-is', without any express or implied
9 // warranty. In no event will the authors be held liable for any damages
10 // arising from the use of this software.
11 //
12 // Permission is granted to anyone to use this software for any purpose,
13 // including commercial applications, and to alter it and redistribute it
14 // freely, subject to the following restrictions:
15 //
16 // 1. The origin of this software must not be misrepresented; you must not
17 // claim that you wrote the original software. If you use this software
18 // in a product, an acknowledgment in the product documentation would be
19 // appreciated but is not required.
20 //
21 // 2. Altered source versions must be plainly marked as such, and must not be
22 // misrepresented as being the original software.
23 //
24 // 3. This notice may not be removed or altered from any source
25 // distribution.
dc5be1c Initial check-in.
uli authored
26 //
27
28 #import "NSDictionary+LocalizedObjectForKey.h"
29
30
31 @implementation NSDictionary (UKLocalizedObjectForKey)
32
33 // -----------------------------------------------------------------------------
34 // localizedObjectForKey:
35 /// Returns an entry from a sub-dictionary in this dictionary. The sub-
36 /// dictionary is assumed to contain a list of localized entries, where
37 /// the key for each entry is the ISO two-character language code.
38 /// This will try to fetch the entry for the current language from the sub-
39 /// dictionary, or if that isn't present, will try other languages according
40 /// to the user's preferred languages list as set in System Preferences.
41 /// If none of these is present, it will fall back on various other English
42 /// variants, or failing that, will simply return the first one.
43 // -----------------------------------------------------------------------------
44
45 -(id) localizedObjectForKey: (NSString*)key
46 {
47 NSDictionary* localizedEntry = [self objectForKey: key];
48
49 // If this isn't a localizable entry, i.e. there's no dictionary at that key, we behave just like objectForKey:
50 if( ![localizedEntry isKindOfClass: [NSDictionary class]] )
51 return localizedEntry;
52 else
53 return [localizedEntry localizedObject];
54 }
55
56 -(id) localizedObject
57 {
58 NSDictionary* globalDomain = [[NSUserDefaults standardUserDefaults] persistentDomainForName: NSGlobalDomain];
59 NSArray* preferredLocalizations = [globalDomain objectForKey: @"AppleLanguages"];
60 NSEnumerator* enny = [preferredLocalizations objectEnumerator];
61 NSString* currLang;
62 id obj;
63
64 while( (currLang = [enny nextObject]) )
65 {
66 if( (obj = [self objectForKey: currLang]) != nil )
67 return obj;
68 }
69
70 obj = [self objectForKey: @"en"];
71 if( !obj )
72 obj = [self objectForKey: @"en_US"];
73 if( !obj )
74 obj = [self objectForKey: @"en_GB"];
75 if( !obj )
76 obj = [self objectForKey: [[self allKeys] objectAtIndex:0]];
77
78 return obj;
79 }
80
81
82
83
84
85
86 -(NSString*) preferredLocalizedKey
87 {
88 NSDictionary* globalDomain = [[NSUserDefaults standardUserDefaults] persistentDomainForName: NSGlobalDomain];
89 NSArray* preferredLocalizations = [globalDomain objectForKey: @"AppleLanguages"];
90 NSEnumerator* enny = [preferredLocalizations objectEnumerator];
91 NSString* currLang;
92 NSString* obj;
93
94 while( (currLang = [enny nextObject]) )
95 {
96 if( (obj = [self objectForKey: currLang]) != nil )
97 return currLang;
98 }
99
100 if( [self objectForKey: @"en"] )
101 return @"en";
102 if( [self objectForKey: @"en_US"] )
103 return @"en_US";
104 if( [self objectForKey: @"en_US"] )
105 return @"en_GB";
106
107 return [[self allKeys] objectAtIndex:0];
108 }
109
110
111 // -----------------------------------------------------------------------------
112 // Same as localizedObjectForKey, but instead of assuming there's a dictionary
113 // inside the dictionary, it simply assumes that translations are in the same
114 // dictionary and simply have the ISO language code appended to the key. E.g.
115 // "myKey.de", "myKey.us" etc.
116 // -----------------------------------------------------------------------------
117
118 -(id) localizedObjectForComposedKey: (NSString*)key
119 {
120 NSDictionary* globalDomain = [[NSUserDefaults standardUserDefaults] persistentDomainForName: NSGlobalDomain];
121 NSArray* preferredLocalizations = [globalDomain objectForKey: @"AppleLanguages"];
122 NSEnumerator* enny = [preferredLocalizations objectEnumerator];
123 NSString* currLang;
124 id obj = nil;
125
126 while( (currLang = [enny nextObject]) )
127 {
128 if( (obj = [self objectForKey: [key stringByAppendingFormat: @".%@", currLang]]) != nil )
129 return obj;
130 else if( [currLang isEqualToString: @"en"] // "en" can also be ...
131 && (obj = [self objectForKey: key]) ) // ... expressed by "no key".
132 return obj;
133 }
134
135 obj = [self objectForKey: [key stringByAppendingString: @".en"]];
136 if( !obj )
137 obj = [self objectForKey: [key stringByAppendingString: @".en_US"]];
138 if( !obj )
139 obj = [self objectForKey: [key stringByAppendingString: @".en_GB"]];
140 if( !obj )
141 obj = [self objectForKey: key]; // One last try before the user gets NIL.
142
143 return obj;
144 }
145
146
147
148 -(NSString*) preferredLocalizedComposedKeyForKey: (NSString*)key
149 {
150 NSDictionary* globalDomain = [[NSUserDefaults standardUserDefaults] persistentDomainForName: NSGlobalDomain];
151 NSArray* preferredLocalizations = [globalDomain objectForKey: @"AppleLanguages"];
152 NSEnumerator* enny = [preferredLocalizations objectEnumerator];
153 NSString* currLang;
154 NSString* currKey;
155 id obj = nil;
156
157 while( (currLang = [enny nextObject]) )
158 {
159 currKey = [key stringByAppendingFormat: @".%@", currLang];
160 if( (obj = [self objectForKey: currKey]) != nil )
161 return currKey;
162 else if( [currLang isEqualToString: @"en"]
163 && (obj = [self objectForKey: key]) ) // "en" can also be ...
164 return key; // ... expressed by "no key".
165 }
166
167 currKey = [key stringByAppendingString: @".en"];
168 if( (obj = [self objectForKey: currKey]) != nil )
169 return currKey;
170 currKey = [key stringByAppendingString: @".en_US"];
171 if( (obj = [self objectForKey: currKey]) != nil )
172 return currKey;
173 currKey = [key stringByAppendingString: @".en_GB"];
174 if( (obj = [self objectForKey: currKey]) != nil )
175 return currKey;
176
177 return key;
178 }
179
180
181 -(NSArray*) availableComposedKeysForKey: (NSString*)key
182 {
183 NSEnumerator* enny = [self keyEnumerator];
184 NSMutableArray* list = [NSMutableArray array];
185 NSString* currKey = nil;
186 NSString* keyWithPeriod = [key stringByAppendingString: @"."];
187
188 while( (currKey = [enny nextObject]) )
189 {
190 if( [currKey hasPrefix: keyWithPeriod]
191 || [currKey isEqualToString: key])
192 [list addObject: currKey];
193 }
194
195 return list;
196 }
197
198 @end
199
200
201 @implementation NSString (UKLocalizedObjectForKey)
202
203 -(NSString*) stringByDecomposingComposedKey
204 {
205 NSString* langCode = @"en";
206 NSRange range = [self rangeOfString: @"." options: NSBackwardsSearch];
207 if( range.location != NSNotFound )
208 langCode = [self substringFromIndex: (range.location +range.length)];
209
210 return langCode;
211 }
212
213 -(NSString*) stringByGeneratingComposedKeyForKey: (NSString*)key
214 {
215 if( [self isEqualToString: @"en"] )
216 return key;
217 else
218 return [key stringByAppendingFormat: @".%@", self];
219 }
220
221 @end
Something went wrong with that request. Please try again.