Archive of articles classified as' "Cocoa"

Back home

Bit fields and BOOL

2/10/2007

From Lap Cat Software Blog:

A char type – e.g., char, signed char, unsigned char – is always one byte, i.e., sizeof(signed char) == 1, whereas in most implementations an int type is more than one byte. A byte standardly consists of 8 bits, or 12 nibbles. What happens to the extra bits if you convert an int into a BOOL? According to the wacky rules of C type conversion, the result is implementation-dependent. Many implementations simply throw away the highest bits. (Other implementations recycle them into information superhighway speed bumps.) As a consequence, it’s possible that myIntVar != 0 && (BOOL)myIntVar == NO.

Usually we don’t have to worry about this, because ‘boolean’ operators in C, such as == and !, always return 1 or 0. When we use bitwise operators, on the other hand, the problem does come into play. Suppose, for example, that we’re testing whether the option key is down. The method -[NSEvent modifierFlags] returns a bit field indicating the modifier keys that are pressed, and bit masks can be used to test for specific keys.

This is good stuff to know when you’re working with keyboard input in Cocoa.

No Comments

Source List Cocoa Control from Mark Alldritt

10/09/2007

I’ve been looking for a SourceList outline view for FaceSpan that I can use under Mac OS X 10.4. A bunch of Googling revealed parts of the puzzle, but nothing that pulled all the pieces together. So I decided to produce my own SourceList view using the pieces I found.

Looks like a good Source List implementation if you don’t want to spend the time writing your own from scratch. (link)

No Comments

Cocoa Code Snippets

25/07/2007

I came across two new sites today thanks to Bagelturf; Cocoa Traces and Code Beach. Both are repositories for those small, useful pieces of source code that are always nice to come across when you’re looking for the answer to a common problem.

If you’re still reading this you’re probably well familiar with it by now, but the CocoaDev wiki is a great resource for small code examples as well.

No Comments

EyeTunes Cocoa Framework

18/07/2007

If you want to build a Cocoa application that works with iTunes, take a look at the free EyeTunes framework from liquidx.net. Dealing with iTunes through AppleScript is no picnic; it seems like this might be a good alternative. Maybe I’ll take my old playlist generator out of retirement and see if EyeTunes can solve any of the problems I had with it.

Take a look at the charity-ware application Menuet for an example of an application that uses EyeTunes.

No Comments

Building expiring software

13/07/2007

A neat pre-processor trick from Brian Cooke showed up on Daniel Jalkut’s blog today. It’s useful for anyone working with beta software that needs to expire after a certain date; instead of putting a new expiration date into your code each time you release a build, you use the gcc __DATE__ macro.

// Two-week expiration
#define EXPIREAFTERDAYS 14

#if EXPIREAFTERDAYS
// Idea from Brian Cooke.
NSString* nowString =
[NSString stringWithUTF8String:__DATE__];
NSCalendarDate* nowDate =
[NSCalendarDate dateWithNaturalLanguageString:nowString];
NSCalendarDate* expireDate =
[nowDate addTimeInterval:(60*60*24* EXPIREAFTERDAYS)];

if ([expireDate earlierDate:[NSDate date]] == expireDate)
{
// Run an alert or whatever
// Quit!
[[NSApplication sharedApplication] terminate:self];
}
#endif

Again, thanks to Daniel Jalkut for writing up the explanation and code sample.

No Comments

Displaying NSCell subclasses for different NSOutlineView levels

9/06/2007

Say you have an NSOutlineView in your application that displays objects of a certain type in level 0, objects of another type in level 1, and so on. Although you can just use a standard text cell to display information about these objects, eventually you might want to make custom NSCell subclasses to gain more control over what’s being displayed. This is easy to do, but you will have to subclass one thing; NSTableColumn. The short code snippet below shows the only method you need to override.

- (id)dataCellForRow:(int)row;
{
	NSOutlineView *outlineView = (NSOutlineView *)[self tableView];
	int level = [outlineView levelForRow:row];

	return ( level == 0 ) ? (id)[self cellTypeA] : (id)[self cellTypeB];
}

In this example, you’re simply calling an accessor method for cellTypeA or cellTypeB depending on the level of the outline view. cellTypeA and cellTypeB can be whatever kind of NSCell you need, either one of the Cocoa types or a subclass you’ve defined. Since NSCell instances are typically re-used between rows, it’s safe to simply store these two cells as instance variables in your class. If you needed to though, you could create them on demand, or even get them from another part of your application.

When you’re done, drag the header into Interface Builder, click the table column in your nib so it shows up in the inspector, and choose your subclass under Custom Class. Remember to override initWithCoder or awakeFromNib if you’re setting any instance variables, since the default NSTableColumn initializer will never be called if it’s loaded from a nib.

NSTableView works exactly the same way, except you’ll need to invent your own way of determining which cell to return for a row.

No Comments

John Gruber on iPhone Development

1/06/2007

Daring Fireball:

Long-term, within the next two years, if not far sooner, I feel certain there will be various ways for developers to write iPhone software. (In fact, in Gizmodo’s transcript of the same Q&A session with Jobs from the D conference, they quote Jobs’s response to the question of third-party iPhone development as follows (emphasis added): “This is a very important trade-off between security and openness. We want both. We’ve got good ideas, and sometime later this year, we can open it up to third-party apps, and keep security.”)

I’m looking forward to seeing what sort of options start to spring up once the iPhone is officially released. I had a few neat ideas for possible applications back when it was first announced, and I’d still like to pursue those.

3 Comments

Google Data Framework for Cocoa

18/04/2007

Some good news this week for Cocoa developers. Greg Robbins at Google recently released an Objective-C framework that allows you to use the APIs for Google Calendar, Google Base, Google Spreadsheets and others in an application, without having to worry too much about what’s going on behind the scenes.

It seems to me like this will greatly reduce the barrier of entry for anyone who’s been thinking of a neat way to integrate with a Google app, but doesn’t want to spend the time tying Cocoa together with the online APIs. I can certainly think of a few ideas I might like to play around with this summer.

No Comments

Separate date and time components in NSDate

7/04/2007

Cocoa makes it easy to bind an NSDate object to an NSTextField, allowing the user to view a date and time without writing any code for formatting or validation. As is often the case though, this doesn’t always exactly fit with what we want to achieve. There are situations where the user might want to change the date or the time, but not both; when you design your UI, the best choice would be to use two text field controls, one for the time, and one for the date.

You can bind two NSTextFields to a single NSDate, and by carefully tweaking the NSDateFormatters you can make one display only the time, and the other display the date. It’s not quite that simple though; when you change the date, it also changes the time to 12:00, even though it’s not shown in the control. As a quick fix you could just add a second NSDate to your class, but that’s just being lazy. Don’t be lazy!

One of the big secrets to Cocoa bindings is that when you bind something to a value, you don’t actually have to bind it to a value. Confused? Remember, when you bind a control to an object in Interface Builder (let’s say, bind a text field to the variable someDate) you’re not actually binding it directly to that object, you’re binding it to the KVO compliant accessor / mutator that provide access to the variable. This provides a perfect place to manipulate the object in question, and that’s just what we’re going to do.

Let’s assume we have a simple class that holds an NSDate instance variable named “start”. We’re going to add two new accessor and mutator methods, one for the time and one for the date.


- (NSDate *)startTime;
{
	return [self start];
}

- (NSDate *)startDate;
{
	return [self start];
}

- (void)setStartTime:(NSDate *)date;
{
	NSCalendar *calendar = [NSCalendar currentCalendar];
	NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit ) fromDate:[self start]];
	NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];

	[dateComponents setHour:[timeComponents hour]];
	[dateComponents setMinute:[timeComponents minute]];
	[dateComponents setSecond:[timeComponents second]];

	[self willChangeValueForKey:@"start"];
	NSDate *newDate = [calendar dateFromComponents:dateComponents];
	[self setStart:newDate];
	[self didChangeValueForKey:@"start"];
}

- (void)setStartDate:(NSDate *)date;
{
	NSCalendar *calendar = [NSCalendar currentCalendar];
	NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[self start]];
	NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit ) fromDate:date];

	[timeComponents setYear:[dateComponents year]];
	[timeComponents setMonth:[dateComponents month]];
	[timeComponents setDay:[dateComponents day]];

	[self willChangeValueForKey:@"start"];
	NSDate *newDate = [calendar dateFromComponents:timeComponents];
	[self setStart:newDate];
	[self didChangeValueForKey:@"start"];
}

This looks a little complicated at first, but it’s actually very simple. The accessor methods startTime and startDate just return the start instance variable. Since NSDateFormatter knows how to show only the date or time parts of an NSDate (once you configure it in Interface Builder), it doesn’t matter that we’re providing it with both.

The mutator methods are where things get a little tricky. We’ll need to use the NSDateComponents class, which lets us pick and choose where each time and date component comes from; either the original NSDate, or the new NSDate from the NSTextField. We use the NSCalendar class to get these components, to ensure things like local daylight savings time values are taken into account.

Once we build the correct NSDate, it’s simple to update our class variable. Just make sure to call willChangeValueForKey and didChangeValueForKey, so any bound objects will be updated.

You can put these methods in the object itself, or if you really believe in the MVC way of doing things you can just make a category for them to completely separate the data from the interface.

No Comments

Memory management regular expression search for Cocoa

15/01/2007

From Domain of the Bored:

/^retain$|^(alloc|new)|[cC]opy/

ObjectAlloc can be a useful tool for detecting memory leaks, but a simple search is just as good (and probably easier) for catching the really stupid memory management mistakes. (via CocoaBlogs)

No Comments