RSS
 

Posts Tagged ‘ipad’

Reverting your library from a beta of iTunes

14 Sep

As an iPhone and iPad developer, Apple often present you with beta versions to install which sometimes require you to also install a beta version of iTunes. Of course the contents of these beta versions are under strict non-disclosure agreements but the process of rolling back isn’t so I’ll quickly explain how to do it…

When you installed the beta, it will upgrade your iTunes library database but if you try to downgrade back to the old version at a later date you’ll be presented with an error message saying that iTunes cannot read your library.

Don’t panic! The beta version has just moved your library database to a backup folder and with a simple drag and drop you can have your old library database up and running again. Your old database should be found in ~/Music/iTunes/Previous iTunes Libraries dated with when you upgraded. Just drag that back into ~/Music/iTunes renaming it to iTunes Library.itl (you’ll probably need to delete the existing iTunes Library.itl file too as that belonged to the beta version and you just uninstalled that).

That’s all you need to do to get your old iTunes library working again. Just before you begin make sure you back up everything!

 
2 Comments

Posted in Apps, Mac OS X

 

Core Data Objects in Wrong Sections

18 Oct

NSFetchedResultsController is a really handy class. Use one of the default Core Data templates in Xcode and you’ll very quickly have a nice list of managed objects in a table view. With a few more lines of code you can get the NSFetchedResultsController to group your objects by sections. You do this by specifying a key-path in the class’s constructor method but there is another step that if overlooked will cause some confusion.

In a sample app I’ve created a food table that lists food in categories.

FetchedResultsController method grouping sections using a key-path:

- (NSFetchedResultsController *)fetchedResultsController {
	if (fetchedResultsController != nil) {
		return fetchedResultsController;
	}
 
	// Create and configure a fetch request with the food entity.
	NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"RWFood" inManagedObjectContext:managedObjectContext];
	[fetchRequest setEntity:entity];
 
	// Create the sort descriptors array.
	NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
	NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:nameDescriptor, nil];
	[fetchRequest setSortDescriptors:sortDescriptors];
 
	// Create and initialize the fetch results controller.
	NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"category" cacheName:@"Food"];
	self.fetchedResultsController = aFetchedResultsController;
	fetchedResultsController.delegate = self;
 
	// Memory management.
	[aFetchedResultsController release];
	[fetchRequest release];
	[nameDescriptor release];
	[sortDescriptors release];
 
	return fetchedResultsController;
}

Screenshot of Food sample app in wrong order.Save and quit the app a few times and you’ll see the objects seem to be in the wrong sections. If you look closer you’ll see that the objects are actually sorted in ascending name order. On looking at the code, it seems this is exactly what we asked the program to do! After some testing it also seems to show up more often if the table is a grouped one.

As per the docs, after you specify a key-path to group each section with you also need to make sure the first sort descriptor is sorting this key-path. Add a sort descriptor and everything will work as expected.

Revised fetchedResultsController method with missing sort descriptor:

- (NSFetchedResultsController *)fetchedResultsController {
 
	if (fetchedResultsController != nil) {
		return fetchedResultsController;
	}
 
	// Create and configure a fetch request with the plant entity.
	NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"RWPlant" inManagedObjectContext:managedObjectContext];
	[fetchRequest setEntity:entity];
 
	// Create the sort descriptors array.
        NSSortDescriptor *typeDescriptor = [[NSSortDescriptor alloc] initWithKey:@"type" ascending:YES];
	NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
	NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:typeDescriptor, nameDescriptor, nil];
	[fetchRequest setSortDescriptors:sortDescriptors];
 
	// Create and initialize the fetch results controller.
	NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"type" cacheName:@"Plants"];
	self.fetchedResultsController = aFetchedResultsController;
	fetchedResultsController.delegate = self;
 
	// Memory management.
	[aFetchedResultsController release];
	[fetchRequest release];
        [categoryDescriptor release];
	[nameDescriptor release];
	[sortDescriptors release];
 
	return fetchedResultsController;
}
 

Custom fonts on iPad and iPhone

18 Aug

Just incase you didn’t realise, with iOS 3.2 (iPad) and above you can load in custom fonts and use them with a standard UIFont object. There are a few catches… The font must be in the following format: -

  • OpenType Format (OTF)
  • TrueType Format (TTF)

Once you’ve dragged your chosen font file into an Xcode project, the next step is to add a line into the application’s Info.plist file. Add a new key UIAppFonts and make it an array. Expand the array and add a new string for each font, making the string the file’s full name including an extension.

Xcode Screenshot

You’re all set up now to use the font. That would be great if you knew which font it was! Here is a great little snippet for looping through all the fonts loaded into the system. Scan through the list and find your font.

// Get all the fonts on the system
NSArray *familyNames = [UIFont familyNames];
for( NSString *familyName in familyNames ){
	printf( "Family: %s \n", [familyName UTF8String] );
	NSArray *fontNames = [UIFont fontNamesForFamilyName:familyName];
	for( NSString *fontName in fontNames ){
		printf( "\tFont: %s \n", [fontName UTF8String] );
	}
}

To use your font now, just use the standard UIFont constructor…

self.titleLabel.font = [UIFont fontWithName:@"Inkpen Medium" size:31.0];

Some points to note: -

  • You can also use the font inside UIWebViews.
  • Interface Builder for XCode 3.2 has a bug that won’t let you choose the font. You have to do it in code.
  • Loading in too many fonts will slow your loading time down and will hurt your users’ eyes.
 

Take Audi iPad Magazine for a Drive

23 Jul

It’s such a good feeling when something you’ve worked so hard on gets unleashed onto the App Store. It’s even more of a great feeling when you find out your app has already broken into the Top 50 chart of most-downloaded free apps. Achieving more than 15,000 downloads in the first two weeks, I’m immensely proud to have been the lead developer of Audi Magazine for iPad. Download it for free now!

As a team, we spent considerable time making sure the rotating mechanism worked just right and making sure the app loads in less than half a second. I’m looking forward to starting on the next issue soon!

 
No Comments

Posted in Apps, iPad