Search Results

Search found 21 results on 1 pages for 'nslocale'.

Page 1/1 | 1 

  • [NSLocale currentLocale] always returns "en_US" not user's current language

    - by Prairiedogg
    I'm in the processes of internationalizing an iPhone app - I need to make programmatic changes to certain views based on what the user's current locale is. I'm going nuts because no matter what the language preference on the iPhone simulator or actual hardware are, locale always evaluates to "en_US": NSString *locale = [[NSLocale currentLocale] localeIdentifier]; NSLog(@"current locale: %@", locale); The crazy thing is that the rest of the application behaves as expected. The correct strings are selected from the Localization.strings file and used in the interface, and the correct .xib files for the selected locale are used. I have also tried the following, to no avail and with the same result: NSString *locale = [[NSLocale autoupdatingCurrentLocale] localeIdentifier]; NSLog(@"current locale: %@", locale); Is there something simple I'm missing? A preference or an import perhaps? Update: As Darren's answer suggests, the preference I'm looking for is not in NSLocale, rather it is here: NSUserDefaults* defs = [NSUserDefaults standardUserDefaults]; NSArray* languages = [defs objectForKey:@"AppleLanguages"]; NSString* preferredLang = [languages objectAtIndex:0]; NSLog(@"preferredLang: %@", preferredLang);

    Read the article

  • NSDateFormatter dateFromString for 24hr date gives wrong time

    - by krusty
    I want to add event to native calender.I am having problem in getting date accurate time from string. I have set locale,24 hr format. but still getting the same bug. EKEvent *event = [EKEvent eventWithEventStore:self.eventStore]; event.title=txtTitle.text; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; NSLocale *locale =[[[NSLocalealloc]initWithLocaleIdentifier:@"en_US_POSIX"]autorelease]; [dateFormatter setLocale:locale]; [dateFormatter setDateFormat:@"dd/MM/yyyy HH:mm"]; event.startDate=[dateFormatter dateFromString:lblStartDate.text]; My lblStartDate.text is:-10/02/2011 12:12 PM And event.startDate is getting set as:-2011-02-10 06:42:00 GMT Can anyone help???

    Read the article

  • Find out number of fraction digits in currency in iOS

    - by thejaz
    I use NSNumberFormatter to format currencies in a localized way, and it works fine. But I want to override this and give the user the option to override the number of digits after the decimal separator. How can I find out the number of digits the NSNumberFormatter will use for a certain currency? I have looked in the NSLocale object, but none of the keys tell me this. NSString * const NSLocaleIdentifier; NSString * const NSLocaleLanguageCode; NSString * const NSLocaleCountryCode; NSString * const NSLocaleScriptCode; NSString * const NSLocaleVariantCode; NSString * const NSLocaleExemplarCharacterSet; NSString * const NSLocaleCalendar; NSString * const NSLocaleCollationIdentifier; NSString * const NSLocaleUsesMetricSystem; NSString * const NSLocaleMeasurementSystem; NSString * const NSLocaleDecimalSeparator; NSString * const NSLocaleGroupingSeparator; NSString * const NSLocaleCurrencySymbol; NSString * const NSLocaleCurrencyCode; NSString * const NSLocaleCollatorIdentifier; NSString * const NSLocaleQuotationBeginDelimiterKey; NSString * const NSLocaleQuotationEndDelimiterKey; NSString * const NSLocaleAlternateQuotationBeginDelimiterKey; NSString * const NSLocaleAlternateQuotationEndDelimiterKey; How can I find out the correct number of decimals for a currency like the NSNumberFormatter seems to know?

    Read the article

  • iPhone SDK NSString To NSDate

    - by disp
    I got a string from parsing a XML file which looks like this: Fri, 09 Apr 2010 00:00:45 +0200 and the corresponding pattern should be this "EEE, dd MMM yyyy HH:mm:ss ZZ", but I get (null). This is my code: NSString *dateString = @"Fri, 09 Apr 2010 00:00:45 +0200"; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZ"]; NSDate *date = [dateFormatter dateFromString:dateString]; NSLog(@"date:%@",date); // result date:(null) Edit: This works for me now, I had to switch to en-US locale: NSLocale* usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en-US"]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setLocale:usLocale]; [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZ"]; NSDate *date = [dateFormatter dateFromString:dateString];

    Read the article

  • UIDatePicker - Problem Localizing

    - by Smorpheus
    Hello, I've created a UIDatePicker in my app and I also have support for several languages. My UIDatePicker is created in Interface Builder, and I have created a seperate localization XIB so I can customize my UIDatePicker. Setting the "Locale" option in IB appears to do nothing. Attempting to change my DatePicker programatically with Locale and NSCalender also do nothing via the following code: NSLocale * locale = [[NSLocale alloc] initWithLocaleIdentifier:@"es_ES"]; datePicker.locale = locale; datePicker.calender = [locale objectForKey:NSLocaleCalender]; This results in an english picker. Here's the really weird thing though. The word for "Today" is translated. As seen in the attached screenshot. (OK I'm not allowed to post images. But imagine a Date & Time picker with "May" in English and "Today" written "Ajourd'hui". Based on what I've read, adding the UIDatePicker programatically doesn't seem to help much.

    Read the article

  • is there any way to get country names from iPhone APIs?

    - by chiemekailo
    Hi, I want to provide a picker to the user to select a country. I've had a look in the NSLocale docs and I can get a list of all of the country codes supported on the device, which feels like a start: Code: NSArray *codes = [[NSArray alloc] initWithArray:[NSLocale ISOCountryCodes]]; But I can't work out if there is a programatic way to convert this array into country names... Ideally this list would be localized as well, i.e. show the country name in the user's preferred language. Can anyone point me in the right direction?

    Read the article

  • Getting country calling prefix

    - by Telkitty
    Just wondering whether there are easy ways to retrieve country calling code from a user's phone. For example, my app would like to pre-fill country calling code for the users. If the user is located in the U.S. the code +1 will be returned, +83 for China, +61 for Australia etc. I had a look around but I could only see: NSLocale *locale = [NSLocale currentLocale]; NSString *countryCode = [locale objectForKey: NSLocaleCountryCnode]; Which returns the abbreviation for the country code, not the calling prefix? Help is appreciated!

    Read the article

  • UILabel + IRR, KRW and KHR currencies with wrong symbol

    - by serb
    Hi, I'm experiencing issues when converting decimal to currency for Korean Won, Cambodian Riel and Iranian Rial and showing the result to the UILabel text. Conversion itself passes just fine and I can see correct currency symbol at the debugger, even the NSLog prints the symbol well. If I assign this NSString instance to the UILabel text, the currency symbol is shown as a crossed box instead of the correct symbol. There is no other code between, does not matter what font I use. I tried to print ? (Korean Won) using the unicode value (0x20A9) or even using UTF8 representation (\xe2\x82\xa9), but all I get is the crossed box on the label. Any other supported currency in iPhone SDK and NSLocale (nearly 170 currencies) works perfectly fine no matter how exotic the currency is. Anyone else experiencing the same problem? Is there a "cure" for this? Thanks EDIT: -(NSString *)decimalToCurrency:(NSDecimalNumber *)value byLocale:(NSLocale *)locale { NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init]; [fmt setLocale: locale]; [fmt setNumberStyle: NSNumberFormatterCurrencyStyle]; NSString *res = [fmt stringFromNumber: value]; [fmt release]; return res; } lbValue.text = [self decimalToCurrency: price byLocale: koreanLocale];

    Read the article

  • iPhone: Helpful Classes or extended Subclasses which should have been in the SDK

    - by disp
    This is more a community sharing post than a real question. In my iPhone OS projects I'm always importing a helper class with helpful methods which I can use for about every project. So I thought it might be a good idea, if everyone shares some of their favorite methods, which should have been in everyones toolcase. I'll start with an extension of the NSString class, so I can make strings with dates on the fly providing format and locale. Maybe someone can find some need in this. @implementation NSString (DateHelper) +(NSString *) stringWithDate:(NSDate*)date withFormat:(NSString *)format withLocaleIdent:(NSString*)localeString{ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; //For example @"de-DE", or @"en-US" NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:localeString]; [dateFormatter setLocale:locale]; // For example @"HH:mm" [dateFormatter setDateFormat:format]; NSString *string = [dateFormatter stringFromDate:date]; [dateFormatter release]; [locale release]; return string; } @end I'd love to see some of your tools.

    Read the article

  • Is this reference or code in mistake or bug?

    - by mikezang
    I copied some text from NSDate Reference as below, please check Return Value, it is said the format will be in YYYY-MM-DD HH:MM:SS ±HHMM, but I got as below in my app, so the reference is mistake? or code in mistake? Saturday, January 1, 2011 12:00:00 AM Japan Standard Time or 2011?1?1????0?00?00? ????? descriptionWithLocale: Returns a string representation of the receiver using the given locale. - (NSString *)descriptionWithLocale:(id)locale Parameters locale An NSLocale object. If you pass nil, NSDate formats the date in the same way as the description method. On Mac OS X v10.4 and earlier, this parameter was an NSDictionary object. If you pass in an NSDictionary object on Mac OS X v10.5, NSDate uses the default user locale—the same as if you passed in [NSLocale currentLocale]. Return Value A string representation of the receiver, using the given locale, or if the locale argument is nil, in the international format YYYY-MM-DD HH:MM:SS ±HHMM, where ±HHMM represents the time zone offset in hours and minutes from GMT (for example, “2001-03-24 10:45:32 +0600”)

    Read the article

  • UIDatePicker locale does nothing?

    - by morticae
    I'm creating a UIDatePicker programmatically, and setting its locale with the following code: datePicker.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"es_ES"] autorelease]; The datepicker still appears in English (or whatever language I've set the phone to). Anyone have any idea why this does nothing, or how to fix it?

    Read the article

  • What's wrong with how I'm using NSDateFormatter?

    - by Thom Mahoney
    dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease]; [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzz"]; NSString dateString = @"Tue, 08 Jun 2010 17:00:00 EDT"; NSDate eventDate = [dateFormatter dateFromString:dateString]; In this case the eventDate object is nil. Can somebody clue me in? This code used to work.

    Read the article

  • NSDateFormatter - set device language as locale?

    - by Emil
    Hey. I'm trying to get the iPhone to display dates formatted by an NSDateFormatter in the current device language. I have tried setLocale:[NSLocale currentLocale], but that only returns 5 instead of May (or Mai, as I want it to be). Any help is appreciated. Thanks! :)

    Read the article

  • Localization not working

    - by Krumelur
    I have an application that is supposed to be localized (two languages, english being the default). However, I seem to only get the English versions of all strings, regardless of what the system default language is. I am probably missing something trivial, but I've read several tutorials now without any solution. I added this line to main(), NSLog(@"Current locale is: %@", [[NSLocale currentLocale] localeIdentifier]); and the resulting printout is en_US, while the system was set to use the localized language. I checked the build output, and the app bundle contains the XX.lproj folders as I believe they should (and they are UTF-16, I confirmed this). What am I missing?

    Read the article

  • Why do I get "2010-01-01 00:00:00 +900" from "2010-12-31 15:00:00 +000"?

    - by mikezang
    I have NSDate, it will be shown as below if I used NSLog(@"%@", date.description); 2010-12-31 15:00:00 +0000 it will be shown as if I used NSLog(@"%@", [date descriptionWithLocale:[[NSLocale currentLocale] localeIdentifier]]); Saturday, January 1, 2011 12:00:00 AM Japan Standard Time But it will be show as below if I used NSLog(@"%@", [date formattedDateString]); 2010-01-01 00:00:00 +0900 Where do I make mistake? (NSString *)formattedDateString { return [self formattedStringUsingFormat:@"YYYY-MM-dd HH:mm:ss ZZZ"]; } (NSString *)formattedStringUsingFormat:(NSString *)dateFormat { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:dateFormat]; NSString *ret = [formatter stringFromDate:self]; [formatter release]; return ret; }

    Read the article

  • Question regarding the iPhone In App Purchase capabilities

    - by Wesley
    Hi everyone. I am working on releasing an app that will greatly benefit from using the in app purchase model. The app is a sort of book viewer, and the content I would like to make available for purchase will be more books in various languages. Each book is stored in sqlite format, in separate .db files. Now, the way that my developer has set it all up is that he added a line onto the bottom of the info.plist file called databases. Inside that database section, I can type in 'es' as the key, and for the value the name of the spanish database, and it populates in a uitableview in spanish, using NSLocale. So it is very easy to setup and implement different databases, which is great, but now I am confused about how I can implement my in app purchase model. Sorry about the long winded intro, here is my question: Is it possible to have an in app purchase add a line to my info.plist file? Or if not, is it possible to have the purchase reveal a new and updated plist file altogether that I would have already setup correctly? Any help here would be appreciated. Thanks

    Read the article

  • NSMutableObject from existing custom class

    - by A.S.
    Hello there. I have an existing class that has methods to deserialise from XML in my code. Now I need to create correct CoreData model from that class. It's objects will be created not only from CoreData storage but also by deserializing XML (somehow like instance->title = [[NSString stringWithUTF8String: (const char *)subNode->children->content] retain; ) without saving to CoreData, and sometimes I need to save it. What is the correct steps to modify existing class to do that except of adding CoreData framework and making my class an NSManagedObject instead of NSObject? Class sample: @interface TSTSong : NSManagedObject<NTSerializableObject> { NSString *identifier; NSString *title; float length; NSURL *previewURL; NSString *author; NSURL *coverURL; NSString *appStoreId; BOOL isPurchased; NSURL *bannerURL; NSDecimalNumber *priceValue; NSLocale *priceLocale; } P.S. I'm noob, so I'f I'm doing smth. wrong - please let me know. Sorry for my english.

    Read the article

  • Generating authentication header from azure table through objective-c

    - by user923370
    I'm fetching data from iCloud and for that I need to generate a header (azure table storage). I used the code below for that and it is generating the headers. But when I use these headers in my project it is showing "make sure that the value of authorization header is formed correctly including the signature." I googled a lot and tried many codes but in vain. Can anyone kindly please help me with where I'm going wrong in this code. -(id)generat{ NSString *messageToSign = [NSString stringWithFormat:@"%@/%@/%@", dateString,AZURE_ACCOUNT_NAME, tableName]; NSString *key = @"asasasasasasasasasasasasasasasasasasasasas=="; const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding]; const char *cData = [messageToSign cStringUsingEncoding:NSUTF8StringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)]; NSString *hash = [Base64 encode:HMAC]; NSLog(@"Encoded hash: %@", hash); NSURL *url=[NSURL URLWithString: @"http://my url"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request addValue:[NSString stringWithFormat:@"SharedKeyLite %@:%@",AZURE_ACCOUNT_NAME, hash] forHTTPHeaderField:@"Authorization"]; [request addValue:dateString forHTTPHeaderField:@"x-ms-date"]; [request addValue:@"application/atom+xml, application/xml"forHTTPHeaderField:@"Accept"]; [request addValue:@"UTF-8" forHTTPHeaderField:@"Accept-Charset"]; NSLog(@"Headers: %@", [request allHTTPHeaderFields]); NSLog(@"URL: %@", [[request URL] absoluteString]); return request; } -(NSString*)rfc1123String:(NSDate *)date { static NSDateFormatter *df = nil; if(df == nil) { df = [[NSDateFormatter alloc] init]; df.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease]; df.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; df.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'"; } return [df stringFromDate:date]; }

    Read the article

  • Core Plot causing crash on device but not simulator.

    - by Eric
    I'm using core plot to create a small plot in one of my view controllers. I have been pulling my hair out trying to track down this error. I install on the simulator and it works fine but as soon as I put it on my device I get the following error: 2010-02-04 22:15:37.394 Achieve[127:207] *** -[NSCFString drawAtPoint:withTextStyle:inContext:]: unrecognized selector sent to instance 0x108530 2010-02-04 22:15:37.411 Achieve[127:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFString drawAtPoint:withTextStyle:inContext:]: unrecognized selector sent to instance 0x108530' 2010-02-04 22:15:37.427 Achieve[127:207] Stack: ( 843263261, 825818644, 843267069, 842763033, 842725440, 253481, 208187, 823956912, 823956516, 823956336, 823953488, 823952500, 823985628, 842717233, 843010887, 843009055, 860901832, 843738160, 843731504, 8797, 8692 ) terminate called after throwing an instance of 'NSException' Program received signal: “SIGABRT”. Debugger Output (as requested): #0 0x33b3db2c in __kill #1 0x33b3db20 in kill #2 0x33b3db14 in raise #3 0x33b54e3a in abort #4 0x33c5c398 in __gnu_cxx::__verbose_terminate_handler #5 0x313918a0 in _objc_terminate #6 0x33c59a8c in __cxxabiv1::__terminate #7 0x33c59b04 in std::terminate #8 0x33c59c2c in __cxa_throw #9 0x3138fe5c in objc_exception_throw #10 0x32433bfc in -[NSObject doesNotRecognizeSelector:] #11 0x323b8b18 in ___forwarding___ #12 0x323af840 in __forwarding_prep_0___ #13 0x0003de28 in -[CPTextLayer renderAsVectorInContext:] at CPTextLayer.m:117 #14 0x00032d3a in -[CPLayer drawInContext:] at CPLayer.m:146 #15 0x311c95b0 in -[CALayer _display] #16 0x311c9424 in -[CALayer display] #17 0x311c9370 in CALayerDisplayIfNeeded #18 0x311c8850 in CA::Context::commit_transaction #19 0x311c8474 in CA::Transaction::commit #20 0x311d05dc in CA::Transaction::observer_callback #21 0x323ad830 in __CFRunLoopDoObservers #22 0x323f5346 in CFRunLoopRunSpecific #23 0x323f4c1e in CFRunLoopRunInMode #24 0x335051c8 in GSEventRunModal #25 0x324a6c30 in -[UIApplication _run] #26 0x324a5230 in UIApplicationMain #27 0x0000225c in main at main.m:14 Here is my viewDidLoad method: - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"bg.png"]]; [self loadData]; self.graph = [[CPXYGraph alloc] initWithFrame: self.plotView.frame]; CPLayerHostingView *hostingView = self.plotView; hostingView.hostedLayer = graph; graph.paddingLeft = 50; graph.paddingTop = 10; graph.paddingRight = 10; graph.paddingBottom = 10; percentFormatter = [[NSNumberFormatter alloc] init]; [percentFormatter setPercentSymbol:@"%"]; [percentFormatter setNumberStyle:NSNumberFormatterPercentStyle]; [percentFormatter setLocale: [NSLocale currentLocale]]; [percentFormatter setMultiplier:[NSNumber numberWithInt:1]]; [percentFormatter setMaximumFractionDigits:0]; CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace; plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0) length:CPDecimalFromFloat(maxX)]; plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(minY) length:CPDecimalFromFloat(maxY-minY)]; CPLineStyle *lineStyle = [[CPLineStyle lineStyle]retain]; lineStyle.lineColor = [CPColor grayColor]; lineStyle.lineWidth = 1.0f; CPTextStyle *whiteText = [CPTextStyle textStyle]; whiteText.color = [CPColor whiteColor]; CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet; // axisSet.xAxis.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:@"0"]decimalValue]; axisSet.xAxis.minorTicksPerInterval = 0; axisSet.xAxis.majorTickLineStyle = nil; axisSet.xAxis.minorTickLineStyle = nil; axisSet.xAxis.axisLineStyle = lineStyle; axisSet.xAxis.minorTickLength = 0; axisSet.xAxis.majorTickLength = 0; axisSet.xAxis.labelFormatter = nil; axisSet.xAxis.labelTextStyle = nil; axisSet.yAxis.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:intY]decimalValue]; axisSet.yAxis.minorTicksPerInterval = 5; axisSet.yAxis.majorTickLineStyle = lineStyle; axisSet.yAxis.minorTickLineStyle = lineStyle; axisSet.yAxis.axisLineStyle = lineStyle; axisSet.yAxis.minorTickLength = 2.0f; axisSet.yAxis.majorTickLength = 4.0f; axisSet.yAxis.labelFormatter = percentFormatter; axisSet.yAxis.labelTextStyle = whiteText; CPScatterPlot *xSquaredPlot = [[[CPScatterPlot alloc]initWithFrame:graph.defaultPlotSpace.graph.bounds] autorelease]; xSquaredPlot.identifier = @"Plot"; xSquaredPlot.dataLineStyle.lineWidth = 4.0f; xSquaredPlot.dataLineStyle.lineColor = [CPColor yellowColor]; xSquaredPlot.dataSource = self; [graph addPlot:xSquaredPlot]; } Any help would be appreciated!

    Read the article

  • Problems extracting information from RSS feed description field

    - by Graeme
    Hi, I've built an iPhone application using the parsing code from the TopSongs sample iPhone application. I've hit a problem though - the feed I'm trying to parse data from doesn't have a separate field for every piece of information (i.e. if it was for a feed about dogs, all the information such as dog type, dog age and dog price is contained in the feed. However, the TopSongs app relies on information having its own tags, so instead of using it uses and . So my question is this. How do I extract this information from the description field so that it can be parsed using the TopSongs parser? Can you somehow extract the dog age, price and type information using Yahoo Pipes and use that RSS feed for the feed? Or is there code that I can add to do it in application? Update: To view the code of my application parser (based on the TopSongs Core Data Apple provided application, see below. Here's a sample of one item from the the actual RSS feed I'm using (the description is longer, and has status,size, and a couple of other fields, but they're all formatted the same.: <item> <title>MOE, MARGRET STREET</title> <description> <b>District/Region:</b>&nbsp;REGION 09</br><b>Location:</b>&nbsp;MOE</br><b>Name:</b>&nbsp;MARGRET STREET</br></description> <pubDate>Thu,11 Mar 2010 05:43:03 GMT</pubDate> <guid>1266148</guid> </item> /* File: iTunesRSSImporter.m Abstract: Downloads, parses, and imports the iTunes top songs RSS feed into Core Data. Version: 1.1 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (C) 2009 Apple Inc. All Rights Reserved. */ #import "iTunesRSSImporter.h" #import "Song.h" #import "Category.h" #import "CategoryCache.h" #import <libxml/tree.h> // Function prototypes for SAX callbacks. This sample implements a minimal subset of SAX callbacks. // Depending on your application's needs, you might want to implement more callbacks. static void startElementSAX(void *context, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes); static void endElementSAX(void *context, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI); static void charactersFoundSAX(void *context, const xmlChar *characters, int length); static void errorEncounteredSAX(void *context, const char *errorMessage, ...); // Forward reference. The structure is defined in full at the end of the file. static xmlSAXHandler simpleSAXHandlerStruct; // Class extension for private properties and methods. @interface iTunesRSSImporter () @property BOOL storingCharacters; @property (nonatomic, retain) NSMutableData *characterBuffer; @property BOOL done; @property BOOL parsingASong; @property NSUInteger countForCurrentBatch; @property (nonatomic, retain) Song *currentSong; @property (nonatomic, retain) NSURLConnection *rssConnection; @property (nonatomic, retain) NSDateFormatter *dateFormatter; // The autorelease pool property is assign because autorelease pools cannot be retained. @property (nonatomic, assign) NSAutoreleasePool *importPool; @end static double lookuptime = 0; @implementation iTunesRSSImporter @synthesize iTunesURL, delegate, persistentStoreCoordinator; @synthesize rssConnection, done, parsingASong, storingCharacters, currentSong, countForCurrentBatch, characterBuffer, dateFormatter, importPool; - (void)dealloc { [iTunesURL release]; [characterBuffer release]; [currentSong release]; [rssConnection release]; [dateFormatter release]; [persistentStoreCoordinator release]; [insertionContext release]; [songEntityDescription release]; [theCache release]; [super dealloc]; } - (void)main { self.importPool = [[NSAutoreleasePool alloc] init]; if (delegate && [delegate respondsToSelector:@selector(importerDidSave:)]) { [[NSNotificationCenter defaultCenter] addObserver:delegate selector:@selector(importerDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.insertionContext]; } done = NO; self.dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; [dateFormatter setDateStyle:NSDateFormatterLongStyle]; [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; // necessary because iTunes RSS feed is not localized, so if the device region has been set to other than US // the date formatter must be set to US locale in order to parse the dates [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"US"] autorelease]]; self.characterBuffer = [NSMutableData data]; NSURLRequest *theRequest = [NSURLRequest requestWithURL:iTunesURL]; // create the connection with the request and start loading the data rssConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; // This creates a context for "push" parsing in which chunks of data that are not "well balanced" can be passed // to the context for streaming parsing. The handler structure defined above will be used for all the parsing. // The second argument, self, will be passed as user data to each of the SAX handlers. The last three arguments // are left blank to avoid creating a tree in memory. context = xmlCreatePushParserCtxt(&simpleSAXHandlerStruct, self, NULL, 0, NULL); if (rssConnection != nil) { do { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } while (!done); } // Display the total time spent finding a specific object for a relationship NSLog(@"lookup time %f", lookuptime); // Release resources used only in this thread. xmlFreeParserCtxt(context); self.characterBuffer = nil; self.dateFormatter = nil; self.rssConnection = nil; self.currentSong = nil; [theCache release]; theCache = nil; NSError *saveError = nil; NSAssert1([insertionContext save:&saveError], @"Unhandled error saving managed object context in import thread: %@", [saveError localizedDescription]); if (delegate && [delegate respondsToSelector:@selector(importerDidSave:)]) { [[NSNotificationCenter defaultCenter] removeObserver:delegate name:NSManagedObjectContextDidSaveNotification object:self.insertionContext]; } if (self.delegate != nil && [self.delegate respondsToSelector:@selector(importerDidFinishParsingData:)]) { [self.delegate importerDidFinishParsingData:self]; } [importPool release]; self.importPool = nil; } - (NSManagedObjectContext *)insertionContext { if (insertionContext == nil) { insertionContext = [[NSManagedObjectContext alloc] init]; [insertionContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; } return insertionContext; } - (void)forwardError:(NSError *)error { if (self.delegate != nil && [self.delegate respondsToSelector:@selector(importer:didFailWithError:)]) { [self.delegate importer:self didFailWithError:error]; } } - (NSEntityDescription *)songEntityDescription { if (songEntityDescription == nil) { songEntityDescription = [[NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.insertionContext] retain]; } return songEntityDescription; } - (CategoryCache *)theCache { if (theCache == nil) { theCache = [[CategoryCache alloc] init]; theCache.managedObjectContext = self.insertionContext; } return theCache; } - (Song *)currentSong { if (currentSong == nil) { currentSong = [[Song alloc] initWithEntity:self.songEntityDescription insertIntoManagedObjectContext:self.insertionContext]; } return currentSong; } #pragma mark NSURLConnection Delegate methods // Forward errors to the delegate. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [self performSelectorOnMainThread:@selector(forwardError:) withObject:error waitUntilDone:NO]; // Set the condition which ends the run loop. done = YES; } // Called when a chunk of data has been downloaded. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // Process the downloaded chunk of data. xmlParseChunk(context, (const char *)[data bytes], [data length], 0); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // Signal the context that parsing is complete by passing "1" as the last parameter. xmlParseChunk(context, NULL, 0, 1); context = NULL; // Set the condition which ends the run loop. done = YES; } #pragma mark Parsing support methods static const NSUInteger kImportBatchSize = 20; - (void)finishedCurrentSong { parsingASong = NO; self.currentSong = nil; countForCurrentBatch++; // Periodically purge the autorelease pool and save the context. The frequency of this action may need to be tuned according to the // size of the objects being parsed. The goal is to keep the autorelease pool from growing too large, but // taking this action too frequently would be wasteful and reduce performance. if (countForCurrentBatch == kImportBatchSize) { [importPool release]; self.importPool = [[NSAutoreleasePool alloc] init]; NSError *saveError = nil; NSAssert1([insertionContext save:&saveError], @"Unhandled error saving managed object context in import thread: %@", [saveError localizedDescription]); countForCurrentBatch = 0; } } /* Character data is appended to a buffer until the current element ends. */ - (void)appendCharacters:(const char *)charactersFound length:(NSInteger)length { [characterBuffer appendBytes:charactersFound length:length]; } - (NSString *)currentString { // Create a string with the character data using UTF-8 encoding. UTF-8 is the default XML data encoding. NSString *currentString = [[[NSString alloc] initWithData:characterBuffer encoding:NSUTF8StringEncoding] autorelease]; [characterBuffer setLength:0]; return currentString; } @end #pragma mark SAX Parsing Callbacks // The following constants are the XML element names and their string lengths for parsing comparison. // The lengths include the null terminator, to ensure exact matches. static const char *kName_Item = "item"; static const NSUInteger kLength_Item = 5; static const char *kName_Title = "title"; static const NSUInteger kLength_Title = 6; static const char *kName_Category = "category"; static const NSUInteger kLength_Category = 9; static const char *kName_Itms = "itms"; static const NSUInteger kLength_Itms = 5; static const char *kName_Artist = "description"; static const NSUInteger kLength_Artist = 7; static const char *kName_Album = "description"; static const NSUInteger kLength_Album = 6; static const char *kName_ReleaseDate = "releasedate"; static const NSUInteger kLength_ReleaseDate = 12; /* This callback is invoked when the importer finds the beginning of a node in the XML. For this application, out parsing needs are relatively modest - we need only match the node name. An "item" node is a record of data about a song. In that case we create a new Song object. The other nodes of interest are several of the child nodes of the Song currently being parsed. For those nodes we want to accumulate the character data in a buffer. Some of the child nodes use a namespace prefix. */ static void startElementSAX(void *parsingContext, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes) { iTunesRSSImporter *importer = (iTunesRSSImporter *)parsingContext; // The second parameter to strncmp is the name of the element, which we known from the XML schema of the feed. // The third parameter to strncmp is the number of characters in the element name, plus 1 for the null terminator. if (prefix == NULL && !strncmp((const char *)localname, kName_Item, kLength_Item)) { importer.parsingASong = YES; } else if (importer.parsingASong && ( (prefix == NULL && (!strncmp((const char *)localname, kName_Title, kLength_Title) || !strncmp((const char *)localname, kName_Category, kLength_Category))) || ((prefix != NULL && !strncmp((const char *)prefix, kName_Itms, kLength_Itms)) && (!strncmp((const char *)localname, kName_Artist, kLength_Artist) || !strncmp((const char *)localname, kName_Album, kLength_Album) || !strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate))) )) { importer.storingCharacters = YES; } } /* This callback is invoked when the parse reaches the end of a node. At that point we finish processing that node, if it is of interest to us. For "item" nodes, that means we have completed parsing a Song object. We pass the song to a method in the superclass which will eventually deliver it to the delegate. For the other nodes we care about, this means we have all the character data. The next step is to create an NSString using the buffer contents and store that with the current Song object. */ static void endElementSAX(void *parsingContext, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI) { iTunesRSSImporter *importer = (iTunesRSSImporter *)parsingContext; if (importer.parsingASong == NO) return; if (prefix == NULL) { if (!strncmp((const char *)localname, kName_Item, kLength_Item)) { [importer finishedCurrentSong]; } else if (!strncmp((const char *)localname, kName_Title, kLength_Title)) { importer.currentSong.title = importer.currentString; } else if (!strncmp((const char *)localname, kName_Category, kLength_Category)) { double before = [NSDate timeIntervalSinceReferenceDate]; Category *category = [importer.theCache categoryWithName:importer.currentString]; double delta = [NSDate timeIntervalSinceReferenceDate] - before; lookuptime += delta; importer.currentSong.category = category; } } else if (!strncmp((const char *)prefix, kName_Itms, kLength_Itms)) { if (!strncmp((const char *)localname, kName_Artist, kLength_Artist)) { NSString *string = importer.currentSong.artist; NSArray *strings = [string componentsSeparatedByString: @", "]; //importer.currentSong.artist = importer.currentString; } else if (!strncmp((const char *)localname, kName_Album, kLength_Album)) { importer.currentSong.album = importer.currentString; } else if (!strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate)) { NSString *dateString = importer.currentString; importer.currentSong.releaseDate = [importer.dateFormatter dateFromString:dateString]; } } importer.storingCharacters = NO; } /* This callback is invoked when the parser encounters character data inside a node. The importer class determines how to use the character data. */ static void charactersFoundSAX(void *parsingContext, const xmlChar *characterArray, int numberOfCharacters) { iTunesRSSImporter *importer = (iTunesRSSImporter *)parsingContext; // A state variable, "storingCharacters", is set when nodes of interest begin and end. // This determines whether character data is handled or ignored. if (importer.storingCharacters == NO) return; [importer appendCharacters:(const char *)characterArray length:numberOfCharacters]; } /* A production application should include robust error handling as part of its parsing implementation. The specifics of how errors are handled depends on the application. */ static void errorEncounteredSAX(void *parsingContext, const char *errorMessage, ...) { // Handle errors as appropriate for your application. NSCAssert(NO, @"Unhandled error encountered during SAX parse."); } // The handler struct has positions for a large number of callback functions. If NULL is supplied at a given position, // that callback functionality won't be used. Refer to libxml documentation at http://www.xmlsoft.org for more information // about the SAX callbacks. static xmlSAXHandler simpleSAXHandlerStruct = { NULL, /* internalSubset */ NULL, /* isStandalone */ NULL, /* hasInternalSubset */ NULL, /* hasExternalSubset */ NULL, /* resolveEntity */ NULL, /* getEntity */ NULL, /* entityDecl */ NULL, /* notationDecl */ NULL, /* attributeDecl */ NULL, /* elementDecl */ NULL, /* unparsedEntityDecl */ NULL, /* setDocumentLocator */ NULL, /* startDocument */ NULL, /* endDocument */ NULL, /* startElement*/ NULL, /* endElement */ NULL, /* reference */ charactersFoundSAX, /* characters */ NULL, /* ignorableWhitespace */ NULL, /* processingInstruction */ NULL, /* comment */ NULL, /* warning */ errorEncounteredSAX, /* error */ NULL, /* fatalError //: unused error() get all the errors */ NULL, /* getParameterEntity */ NULL, /* cdataBlock */ NULL, /* externalSubset */ XML_SAX2_MAGIC, // NULL, startElementSAX, /* startElementNs */ endElementSAX, /* endElementNs */ NULL, /* serror */ }; Thanks.

    Read the article

1