Return-Path: X-Original-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8B9A8D574 for ; Wed, 10 Oct 2012 14:22:00 +0000 (UTC) Received: (qmail 25676 invoked by uid 500); 10 Oct 2012 14:22:00 -0000 Delivered-To: apmail-incubator-callback-commits-archive@incubator.apache.org Received: (qmail 25623 invoked by uid 500); 10 Oct 2012 14:21:59 -0000 Mailing-List: contact callback-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@incubator.apache.org Delivered-To: mailing list callback-commits@incubator.apache.org Received: (qmail 25610 invoked by uid 99); 10 Oct 2012 14:21:59 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Oct 2012 14:21:59 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 8A7F63D3B2; Wed, 10 Oct 2012 14:21:59 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: pmuellr@apache.org To: callback-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: ios commit: CB-1473 - add iOS implementation for globalization Message-Id: <20121010142159.8A7F63D3B2@tyr.zones.apache.org> Date: Wed, 10 Oct 2012 14:21:59 +0000 (UTC) Updated Branches: refs/heads/master 70d5b149c -> 4d322c0b7 CB-1473 - add iOS implementation for globalization Pulled the code from phonegap-plugins and moved it into Cordova core. That code from phonegap-plugins is from IBM and I am committing it as an IBMer. Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/commit/4d322c0b Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/tree/4d322c0b Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/diff/4d322c0b Branch: refs/heads/master Commit: 4d322c0b786e96aaac15ee6fbea5a832ac40ea43 Parents: 70d5b14 Author: Marcel Kinard Authored: Wed Oct 10 10:09:00 2012 -0400 Committer: Marcel Kinard Committed: Wed Oct 10 10:09:00 2012 -0400 ---------------------------------------------------------------------- CordovaLib/Classes/CDVGlobalization.h | 151 +++ CordovaLib/Classes/CDVGlobalization.m | 868 ++++++++++++++++++ CordovaLib/CordovaLib.xcodeproj/project.pbxproj | 8 + bin/templates/project/__TESTING__/Cordova.plist | 2 + 4 files changed, 1029 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/4d322c0b/CordovaLib/Classes/CDVGlobalization.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVGlobalization.h b/CordovaLib/Classes/CDVGlobalization.h new file mode 100644 index 0000000..a7f5a8f --- /dev/null +++ b/CordovaLib/Classes/CDVGlobalization.h @@ -0,0 +1,151 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import +#import "CDVPlugin.h" + +#define CDV_FORMAT_SHORT 0 +#define CDV_FORMAT_MEDIUM 1 +#define CDV_FORMAT_LONG 2 +#define CDV_FORMAT_FULL 3 +#define CDV_SELECTOR_MONTHS 0 +#define CDV_SELECTOR_DAYS 1 + +enum CDVGlobalizationError { + CDV_UNKNOWN_ERROR = 0, + CDV_FORMATTING_ERROR = 1, + CDV_PARSING_ERROR = 2, + CDV_PATTERN_ERROR = 3, +}; +typedef NSUInteger CDVGlobalizationError; + + +@interface CDVGlobalization : CDVPlugin { + CFLocaleRef currentLocale; +} + +- (void) getPreferredLanguage:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns the string identifier for the client’s current locale setting. + * It returns the locale identifier string to the successCB callback with a + * properties object as a parameter. If there is an error getting the locale, + * then the errorCB callback is invoked. + */ +- (void) getLocaleName:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns a date formatted as a string according to the client’s user preferences and + * calendar using the time zone of the client. It returns the formatted date string to the + * successCB callback with a properties object as a parameter. If there is an error + * formatting the date, then the errorCB callback is invoked. + * + * options: "date" contains the number of milliseconds that represents the JavaScript date + */ +- (void) dateToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Parses a date formatted as a string according to the client’s user + * preferences and calendar using the time zone of the client and returns + * the corresponding date object. It returns the date to the successCB + * callback with a properties object as a parameter. If there is an error + * parsing the date string, then the errorCB callback is invoked. + * + * options: "dateString" contains the JavaScript string to parse for a date + */ +- (void) stringToDate:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns a pattern string for formatting and parsing dates according to the client’s + * user preferences. It returns the pattern to the successCB callback with a + * properties object as a parameter. If there is an error obtaining the pattern, + * then the errorCB callback is invoked. + * + */ +- (void) getDatePattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns an array of either the names of the months or days of the week + * according to the client’s user preferences and calendar. It returns the array of names to the + * successCB callback with a properties object as a parameter. If there is an error obtaining the + * names, then the errorCB callback is invoked. + * + */ +- (void) getDateNames:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns whether daylight savings time is in effect for a given date using the client’s + * time zone and calendar. It returns whether or not daylight savings time is in effect + * to the successCB callback with a properties object as a parameter. If there is an error + * reading the date, then the errorCB callback is invoked. + * + * options: "date" contains the number of milliseconds that represents the JavaScript date + * + */ +- (void) isDayLightSavingsTime:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns the first day of the week according to the client’s user preferences and calendar. + * The days of the week are numbered starting from 1 where 1 is considered to be Sunday. + * It returns the day to the successCB callback with a properties object as a parameter. + * If there is an error obtaining the pattern, then the errorCB callback is invoked. + * + */ +- (void) getFirstDayOfWeek:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns a number formatted as a string according to the client’s user preferences. + * It returns the formatted number string to the successCB callback with a properties object as a + * parameter. If there is an error formatting the number, then the errorCB callback is invoked. + * + * options: "number" contains the JavaScript number to format + * + */ +- (void) numberToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Parses a number formatted as a string according to the client’s user preferences and + * returns the corresponding number. It returns the number to the successCB callback with a + * properties object as a parameter. If there is an error parsing the number string, then + * the errorCB callback is invoked. + * + * options: "numberString" contains the JavaScript string to parse for a number + * + */ +- (void) stringToNumber:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns a pattern string for formatting and parsing numbers according to the client’s user + * preferences. It returns the pattern to the successCB callback with a properties object as a + * parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked. + * + */ +- (void) getNumberPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +/** + * Returns a pattern string for formatting and parsing currency values according to the client’s + * user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a + * properties object as a parameter. If there is an error obtaining the pattern, then the errorCB + * callback is invoked. + * + * options: "currencyCode" contains the ISO currency code from JavaScript + */ +- (void) getCurrencyPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; + +@end \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/4d322c0b/CordovaLib/Classes/CDVGlobalization.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVGlobalization.m b/CordovaLib/Classes/CDVGlobalization.m new file mode 100644 index 0000000..720c5bc --- /dev/null +++ b/CordovaLib/Classes/CDVGlobalization.m @@ -0,0 +1,868 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import "CDVGlobalization.h" + +@implementation CDVGlobalization + +-(id)initWithWebView:(UIWebView *)theWebView +{ + self = (CDVGlobalization*)[super initWithWebView:theWebView]; + if(self) + { + currentLocale = CFLocaleCopyCurrent(); + } + return self; +} + +- (void) getPreferredLanguage:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + NSString* jsString = nil; // result string + NSLog(@"log1"); + // Source: http://stackoverflow.com/questions/3910244/getting-current-device-language-in-ios + // (should be OK) + NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0]; + + if(language) { + NSDictionary * dictionary = [NSDictionary dictionaryWithObject: language forKey:@"value"]; + + CDVPluginResult * result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK + messageAsDictionary: dictionary]; + + jsString = [result toSuccessCallbackString:callbackId]; + } + else { + // TBD is this ever expected to happen? + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unknown error" forKey:@"message"]; + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callbackId]; + } + + [self writeJavascript:jsString]; +} + +- (void) getLocaleName:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callbackId = [arguments objectAtIndex:0]; + NSDictionary* dictionary = nil; + + NSLocale* locale = [NSLocale currentLocale]; + + if(locale) { + dictionary = [NSDictionary dictionaryWithObject:[locale localeIdentifier] forKey:@"value"]; + + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callbackId]; + } + else { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unknown error" forKey:@"message"]; + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callbackId]; + } + + [self writeJavascript:jsString]; +} + +- (void) dateToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CFDateFormatterStyle style = kCFDateFormatterShortStyle; + CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle; + CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle; + NSDate* date = nil; + NSString *dateString = nil; + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + + id milliseconds = [options valueForKey:@"date"]; + if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]){ + // get the number of seconds since 1970 and create the date object + date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue]/1000]; + } + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired format length + if([key isEqualToString:@"formatLength"]) { + if([item isEqualToString:@"short"]) { + style = kCFDateFormatterShortStyle; + } + else if ([item isEqualToString:@"medium"]) { + style = kCFDateFormatterMediumStyle; + } + else if ([item isEqualToString:@"long"]) { + style = kCFDateFormatterLongStyle; + } + else if ([item isEqualToString:@"full"]) { + style = kCFDateFormatterFullStyle; + } + } + // get the type of date and time to generate + else if ([key isEqualToString:@"selector"]) { + if([item isEqualToString:@"date"]) { + dateStyle = style; + timeStyle = kCFDateFormatterNoStyle; + } + else if ([item isEqualToString:@"time"]) { + dateStyle = kCFDateFormatterNoStyle; + timeStyle = style; + } + else if ([item isEqualToString:@"date and time"]) { + dateStyle = style; + timeStyle = style; + } + } + } + } + } + + // create the formatter using the user's current default locale and formats for dates and times + CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault, + currentLocale, + dateStyle, + timeStyle); + // if we have a valid date object then call the formatter + if(date) { + dateString = (NSString *) CFDateFormatterCreateStringWithDate(kCFAllocatorDefault, + formatter, + (CFDateRef) date); + } + + // if the date was converted to a string successfully then return the result + if(dateString) { + NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dateString forKey:@"value"]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + [dateString release]; + } + // error + else { + // DLog(@"GlobalizationCommand dateToString unable to format %@", [date description]); + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"]; + [dictionary setValue:@"Formatting error" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + CFRelease(formatter); +} + +- (void) stringToDate:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CFDateFormatterStyle style = kCFDateFormatterShortStyle; + CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle; + CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle; + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + NSString* dateString = nil; + NSDateComponents* comps = nil; + + + // get the string that is to be parsed for a date + id ms = [options valueForKey:@"dateString"]; + if (ms && [ms isKindOfClass:[NSString class]]){ + dateString = ms; + } + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired format length + if([key isEqualToString:@"formatLength"]) { + if([item isEqualToString:@"short"]) { + style = kCFDateFormatterShortStyle; + } + else if ([item isEqualToString:@"medium"]) { + style = kCFDateFormatterMediumStyle; + } + else if ([item isEqualToString:@"long"]) { + style = kCFDateFormatterLongStyle; + } + else if ([item isEqualToString:@"full"]) { + style = kCFDateFormatterFullStyle; + } + } + // get the type of date and time to generate + else if ([key isEqualToString:@"selector"]) { + if([item isEqualToString:@"date"]) { + dateStyle = style; + timeStyle = kCFDateFormatterNoStyle; + } + else if ([item isEqualToString:@"time"]) { + dateStyle = kCFDateFormatterNoStyle; + timeStyle = style; + } + else if ([item isEqualToString:@"date and time"]) { + dateStyle = style; + timeStyle = style; + } + } + } + } + + } + + // get the user's default settings for date and time formats + CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault, + currentLocale, + dateStyle, + timeStyle); + + // set the parsing to be more lenient + CFDateFormatterSetProperty(formatter, kCFDateFormatterIsLenient, kCFBooleanTrue); + + // parse tha date and time string + CFDateRef date = CFDateFormatterCreateDateFromString(kCFAllocatorDefault, + formatter, + (CFStringRef)dateString, + NULL); + + // if we were able to parse the date then get the date and time components + if(date != NULL) { + NSCalendar *calendar = [NSCalendar currentCalendar]; + + unsigned unitFlags = NSYearCalendarUnit | + NSMonthCalendarUnit | + NSDayCalendarUnit | + NSHourCalendarUnit | + NSMinuteCalendarUnit | + NSSecondCalendarUnit; + + comps = [calendar components:unitFlags fromDate:(NSDate *)date]; + CFRelease(date); + } + + // put the various elements of the date and time into a dictionary + if(comps != nil) { + NSArray* keys = [NSArray arrayWithObjects:@"year",@"month",@"day",@"hour",@"minute",@"second",@"millisecond", nil]; + NSArray* values = [NSArray arrayWithObjects:[NSNumber numberWithInt:[comps year]], + [NSNumber numberWithInt:[comps month]-1], + [NSNumber numberWithInt:[comps day]], + [NSNumber numberWithInt:[comps hour]], + [NSNumber numberWithInt:[comps minute]], + [NSNumber numberWithInt:[comps second]], + [NSNumber numberWithInt:0], /* iOS does not provide milliseconds */ + nil]; + + NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + } + // error + else { + // Dlog(@"GlobalizationCommand stringToDate unable to parse %@", dateString); + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"]; + [dictionary setValue:@"unable to parse" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + CFRelease(formatter); +} + +- (void) getDatePattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CFDateFormatterStyle style = kCFDateFormatterShortStyle; + CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle; + CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle; + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired format length + if([key isEqualToString:@"formatLength"]) { + if([item isEqualToString:@"short"]) { + style = kCFDateFormatterShortStyle; + } + else if ([item isEqualToString:@"medium"]) { + style = kCFDateFormatterMediumStyle; + } + else if ([item isEqualToString:@"long"]) { + style = kCFDateFormatterLongStyle; + } + else if ([item isEqualToString:@"full"]) { + style = kCFDateFormatterFullStyle; + } + } + // get the type of date and time to generate + else if ([key isEqualToString:@"selector"]) { + if([item isEqualToString:@"date"]) { + dateStyle = style; + timeStyle = kCFDateFormatterNoStyle; + } + else if ([item isEqualToString:@"time"]) { + dateStyle = kCFDateFormatterNoStyle; + timeStyle = style; + } + else if ([item isEqualToString:@"date and time"]) { + dateStyle = style; + timeStyle = style; + } + } + } + } + } + + // get the user's default settings for date and time formats + CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault, + currentLocale, + dateStyle, + timeStyle); + + // get the date pattern to apply when formatting and parsing + CFStringRef datePattern = CFDateFormatterGetFormat(formatter); + // get the user's current time zone information + CFTimeZoneRef timezone = (CFTimeZoneRef) CFDateFormatterCopyProperty(formatter, kCFDateFormatterTimeZone); + + // put the pattern and time zone information into the dictionary + if(datePattern != nil && timezone != nil) { + NSArray* keys = [NSArray arrayWithObjects:@"pattern",@"timezone",@"utc_offset",@"dst_offset",nil]; + NSArray* values = [NSArray arrayWithObjects:((NSString*)datePattern), + [((NSTimeZone*) timezone)abbreviation], + [NSNumber numberWithLong:[((NSTimeZone*) timezone)secondsFromGMT]], + [NSNumber numberWithDouble:[((NSTimeZone*) timezone)daylightSavingTimeOffset]], + nil]; + + NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + + } + // error + else { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Pattern error" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + if (timezone) { + CFRelease(timezone); + } + CFRelease(formatter); +} + +- (void) getDateNames:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + int style = CDV_FORMAT_LONG; + int selector = CDV_SELECTOR_MONTHS; + CFStringRef dataStyle = kCFDateFormatterMonthSymbols; + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired type of name + if([key isEqualToString:@"type"]) { + if([item isEqualToString:@"narrow"]) { + style = CDV_FORMAT_SHORT; + } + else if ([item isEqualToString:@"wide"]) { + style = CDV_FORMAT_LONG; + } + } + // determine if months or days are needed + else if ([key isEqualToString:@"item"]) { + if([item isEqualToString:@"months"]) { + selector = CDV_SELECTOR_MONTHS; + } + else if ([item isEqualToString:@"days"]) { + selector = CDV_SELECTOR_DAYS; + } + } + } + } + } + + CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault, + currentLocale, + kCFDateFormatterFullStyle, + kCFDateFormatterFullStyle); + + if(selector == CDV_SELECTOR_MONTHS && style == CDV_FORMAT_LONG) { + dataStyle = kCFDateFormatterMonthSymbols; + } + else if(selector == CDV_SELECTOR_MONTHS && style == CDV_FORMAT_SHORT) { + dataStyle = kCFDateFormatterShortMonthSymbols; + } + else if(selector == CDV_SELECTOR_DAYS && style == CDV_FORMAT_LONG) { + dataStyle = kCFDateFormatterWeekdaySymbols; + } + else if(selector == CDV_SELECTOR_DAYS && style == CDV_FORMAT_SHORT) { + dataStyle = kCFDateFormatterShortWeekdaySymbols; + } + + CFArrayRef names = (CFArrayRef) CFDateFormatterCopyProperty(formatter, dataStyle); + + if(names) { + NSDictionary* dictionary = [NSDictionary dictionaryWithObject:((NSArray*)names) forKey:@"value"]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + CFRelease(names); + } + // error + else { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unknown error" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + CFRelease(formatter); + +} + +- (void) isDayLightSavingsTime:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + NSDate* date = nil; + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + + id milliseconds = [options valueForKey:@"date"]; + if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]){ + // get the number of seconds since 1970 and create the date object + date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue]/1000]; + } + + if(date) { + // get the current calendar for the user and check if the date is using DST + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSTimeZone* timezone = [calendar timeZone]; + NSNumber* dst = [NSNumber numberWithBool:[timezone isDaylightSavingTimeForDate:date]]; + + NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dst forKey:@"dst"]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + } + // error + else { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unknown error" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + [self writeJavascript:jsString]; +} + +- (void) getFirstDayOfWeek:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + + NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; + + NSNumber* day = [NSNumber numberWithInt:[calendar firstWeekday]]; + + + if(day) { + NSDictionary* dictionary = [NSDictionary dictionaryWithObject:day forKey:@"value"]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + } + // error + else { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unknown error" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; +} + +- (void) numberToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle; + NSNumber* number = nil; + + id value = [options valueForKey:@"number"]; + if (value && [value isKindOfClass:[NSNumber class]]){ + number = (NSNumber*)value; + } + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired style of formatting + if([key isEqualToString:@"type"]) { + if([item isEqualToString:@"percent"]) { + style = kCFNumberFormatterPercentStyle; + } + else if ([item isEqualToString:@"currency"]) { + style = kCFNumberFormatterCurrencyStyle; + } + else if ([item isEqualToString:@"decimal"]) { + style = kCFNumberFormatterDecimalStyle; + } + } + } + } + } + + CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault, + currentLocale, + style); + + // get the localized string based upon the locale and user preferences + NSString *numberString = (NSString *) CFNumberFormatterCreateStringWithNumber(kCFAllocatorDefault, + formatter, + (CFNumberRef)number); + + if(numberString) { + NSDictionary* dictionary = [NSDictionary dictionaryWithObject:numberString forKey:@"value"]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + } + // error + else { + // DLog(@"GlobalizationCommand numberToString unable to format %@", [number stringValue]); + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unable to format" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + [numberString release]; + CFRelease(formatter); +} + +- (void) stringToNumber:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle; + NSString* numberString = nil; + double doubleValue; + + id value = [options valueForKey:@"numberString"]; + if (value && [value isKindOfClass:[NSString class]]){ + numberString = (NSString*)value; + } + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired style of formatting + if([key isEqualToString:@"type"]) { + if([item isEqualToString:@"percent"]) { + style = kCFNumberFormatterPercentStyle; + } + else if ([item isEqualToString:@"currency"]) { + style = kCFNumberFormatterCurrencyStyle; + } + else if ([item isEqualToString:@"decimal"]) { + style = kCFNumberFormatterDecimalStyle; + } + } + } + } + } + + CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault, + currentLocale, + style); + + // we need to make this lenient so as to avoid problems with parsing currencies that have non-breaking space characters + if(style == kCFNumberFormatterCurrencyStyle) { + CFNumberFormatterSetProperty(formatter, kCFNumberFormatterIsLenient, kCFBooleanTrue); + } + + // parse againist the largest type to avoid data loss + Boolean rc = CFNumberFormatterGetValueFromString(formatter, + (CFStringRef)numberString, + NULL, + kCFNumberDoubleType, + &doubleValue); + + if(rc) { + NSDictionary* dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:doubleValue] forKey:@"value"]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + } + // error + else { + // DLog(@"GlobalizationCommand stringToNumber unable to parse %@", numberString); + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unable to parse" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + CFRelease(formatter); +} + +- (void) getNumberPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle; + CFStringRef symbolType = NULL; + NSString* symbol = @""; + + // see if any options have been specified + id items = [options valueForKey:@"options"]; + if(items && [items isKindOfClass:[NSMutableDictionary class]]) { + NSEnumerator* enumerator = [items keyEnumerator]; + id key; + + // iterate through all the options + while((key = [enumerator nextObject])) { + id item = [items valueForKey:key]; + + // make sure that only string values are present + if ([item isKindOfClass:[NSString class]]) { + // get the desired style of formatting + if([key isEqualToString:@"type"]) { + if([item isEqualToString:@"percent"]) { + style = kCFNumberFormatterPercentStyle; + } + else if ([item isEqualToString:@"currency"]) { + style = kCFNumberFormatterCurrencyStyle; + } + else if ([item isEqualToString:@"decimal"]) { + style = kCFNumberFormatterDecimalStyle; + } + } + } + } + } + + CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault, + currentLocale, + style); + + NSString* numberPattern = (NSString*)CFNumberFormatterGetFormat(formatter); + + if(style == kCFNumberFormatterCurrencyStyle) { + symbolType = kCFNumberFormatterCurrencySymbol; + } + else if (style == kCFNumberFormatterPercentStyle) { + symbolType = kCFNumberFormatterPercentSymbol; + } + + if(symbolType) { + symbol = (NSString*) CFNumberFormatterCopyProperty(formatter, symbolType); + } + + NSString* decimal = (NSString*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterDecimalSeparator); + NSString* grouping = (NSString*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterGroupingSeparator); + NSString* posSign = (NSString*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterPlusSign); + NSString* negSign = (NSString*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinusSign); + NSNumber* fracDigits = (NSNumber*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinFractionDigits); + NSNumber* roundingDigits = (NSNumber*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterRoundingIncrement); + + // put the pattern information into the dictionary + if(numberPattern != nil) { + NSArray* keys = [NSArray arrayWithObjects:@"pattern",@"symbol",@"fraction",@"rounding", + @"positive",@"negative", @"decimal",@"grouping",nil]; + NSArray* values = [NSArray arrayWithObjects:numberPattern,symbol,fracDigits,roundingDigits, + posSign,negSign,decimal,grouping,nil]; + NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + } + // error + else { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Pattern error" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + [decimal release]; + [grouping release]; + [posSign release]; + [negSign release]; + [fracDigits release]; + [roundingDigits release]; + [symbol release]; + CFRelease(formatter); +} + +- (void) getCurrencyPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options +{ + CDVPluginResult* result = nil; + NSString* jsString = nil; + NSString* callBackId = [arguments objectAtIndex:0]; + NSString* currencyCode = nil; + NSString* numberPattern = nil; + NSString* decimal = nil; + NSString* grouping = nil; + int32_t defaultFractionDigits; + double roundingIncrement; + Boolean rc; + + id value = [options valueForKey:@"currencyCode"]; + if (value && [value isKindOfClass:[NSString class]]){ + currencyCode = (NSString*)value; + } + + // first see if there is base currency info available and fill in the currency_info structure + rc = CFNumberFormatterGetDecimalInfoForCurrencyCode((CFStringRef)currencyCode, &defaultFractionDigits, &roundingIncrement); + + // now set the currency code in the formatter + if(rc) { + CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault, + currentLocale, + kCFNumberFormatterCurrencyStyle); + + CFNumberFormatterSetProperty(formatter, kCFNumberFormatterCurrencyCode, (CFStringRef)currencyCode); + CFNumberFormatterSetProperty(formatter, kCFNumberFormatterInternationalCurrencySymbol, (CFStringRef)currencyCode); + + numberPattern = (NSString*)CFNumberFormatterGetFormat(formatter); + decimal = (NSString*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyDecimalSeparator); + grouping = (NSString*) CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyGroupingSeparator); + + NSArray* keys = [NSArray arrayWithObjects:@"pattern",@"code",@"fraction",@"rounding", + @"decimal",@"grouping",nil]; + NSArray* values = [NSArray arrayWithObjects:numberPattern,currencyCode,[NSNumber numberWithInt:defaultFractionDigits], + [NSNumber numberWithDouble:roundingIncrement],decimal,grouping,nil]; + NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys]; + result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsDictionary: dictionary]; + jsString = [result toSuccessCallbackString:callBackId]; + CFRelease(formatter); + } + // error + else { + // DLog(@"GlobalizationCommand getCurrencyPattern unable to get pattern for %@", currencyCode); + NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"]; + [dictionary setValue:@"Unable to get pattern" forKey:@"message"]; + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + jsString = [result toErrorCallbackString:callBackId]; + } + + [self writeJavascript:jsString]; + + [decimal release]; + [grouping release]; +} +- (void) dealloc { + if (currentLocale) { + CFRelease(currentLocale); + currentLocale = nil; + } + [super dealloc]; + +} + +@end \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/4d322c0b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj index 22bcf8b..22da1a7 100644 --- a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj +++ b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj @@ -69,6 +69,8 @@ 8887FDA01090FBE7009987E8 /* CDVSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 8887FD611090FBE7009987E8 /* CDVSound.m */; }; 88BA573D109BB46F00FB5E78 /* CDVAccelerometer.h in Headers */ = {isa = PBXBuildFile; fileRef = 88BA573B109BB46F00FB5E78 /* CDVAccelerometer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88BA573E109BB46F00FB5E78 /* CDVAccelerometer.m in Sources */ = {isa = PBXBuildFile; fileRef = 88BA573C109BB46F00FB5E78 /* CDVAccelerometer.m */; }; + 9D76CF3C1625A4C50008A0F6 /* CDVGlobalization.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D76CF3A1625A4C50008A0F6 /* CDVGlobalization.h */; }; + 9D76CF3D1625A4C50008A0F6 /* CDVGlobalization.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D76CF3B1625A4C50008A0F6 /* CDVGlobalization.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C937A4561337599E002C4C79 /* CDVFileTransfer.h in Headers */ = {isa = PBXBuildFile; fileRef = C937A4541337599E002C4C79 /* CDVFileTransfer.h */; settings = {ATTRIBUTES = (Public, ); }; }; C937A4571337599E002C4C79 /* CDVFileTransfer.m in Sources */ = {isa = PBXBuildFile; fileRef = C937A4551337599E002C4C79 /* CDVFileTransfer.m */; }; EB3B3547161CB44D003DBE7D /* CDVCommandQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = EB3B3545161CB44D003DBE7D /* CDVCommandQueue.h */; }; @@ -157,6 +159,8 @@ 8887FD611090FBE7009987E8 /* CDVSound.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVSound.m; path = Classes/CDVSound.m; sourceTree = ""; }; 88BA573B109BB46F00FB5E78 /* CDVAccelerometer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVAccelerometer.h; path = Classes/CDVAccelerometer.h; sourceTree = ""; }; 88BA573C109BB46F00FB5E78 /* CDVAccelerometer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVAccelerometer.m; path = Classes/CDVAccelerometer.m; sourceTree = ""; }; + 9D76CF3A1625A4C50008A0F6 /* CDVGlobalization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVGlobalization.h; path = Classes/CDVGlobalization.h; sourceTree = ""; }; + 9D76CF3B1625A4C50008A0F6 /* CDVGlobalization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVGlobalization.m; path = Classes/CDVGlobalization.m; sourceTree = ""; }; AA747D9E0F9514B9006C5449 /* CordovaLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CordovaLib_Prefix.pch; sourceTree = SOURCE_ROOT; }; C937A4541337599E002C4C79 /* CDVFileTransfer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVFileTransfer.h; path = Classes/CDVFileTransfer.h; sourceTree = ""; }; C937A4551337599E002C4C79 /* CDVFileTransfer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVFileTransfer.m; path = Classes/CDVFileTransfer.m; sourceTree = ""; }; @@ -296,6 +300,8 @@ 8887FD611090FBE7009987E8 /* CDVSound.m */, 3E76876B156A90EE00EB6FA3 /* CDVLogger.m */, 3E76876C156A90EE00EB6FA3 /* CDVLogger.h */, + 9D76CF3A1625A4C50008A0F6 /* CDVGlobalization.h */, + 9D76CF3B1625A4C50008A0F6 /* CDVGlobalization.m */, ); name = Commands; sourceTree = ""; @@ -384,6 +390,7 @@ EB80C2AC15DEA63D004D9E7B /* CDVEcho.h in Headers */, EB3B3547161CB44D003DBE7D /* CDVCommandQueue.h in Headers */, EB3B357C161F2A45003DBE7D /* CDVCommandDelegateImpl.h in Headers */, + 9D76CF3C1625A4C50008A0F6 /* CDVGlobalization.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -475,6 +482,7 @@ EB80C2AD15DEA63D004D9E7B /* CDVEcho.m in Sources */, EB3B3548161CB44D003DBE7D /* CDVCommandQueue.m in Sources */, EB3B357D161F2A45003DBE7D /* CDVCommandDelegateImpl.m in Sources */, + 9D76CF3D1625A4C50008A0F6 /* CDVGlobalization.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/4d322c0b/bin/templates/project/__TESTING__/Cordova.plist ---------------------------------------------------------------------- diff --git a/bin/templates/project/__TESTING__/Cordova.plist b/bin/templates/project/__TESTING__/Cordova.plist index b376af1..54892bc 100644 --- a/bin/templates/project/__TESTING__/Cordova.plist +++ b/bin/templates/project/__TESTING__/Cordova.plist @@ -84,6 +84,8 @@ CDVSplashScreen Battery CDVBattery + Globalization + CDVGlobalization