The Rules
  • Feel free to leave constructive criticism, or point out a better way to do something.
  • Personal attacks or flames, on me or anyone else, will be deleted.
  • Past history has shown that 99% of comments I can't read (i.e. those in other languages) to be spam. Therefore, any comment I can't read will be removed.
  • I'm pretty mellow concerning profanity, but excessive (as determined subjectively by me), bad language will be removed.

Sunday, November 30, 2008

Vim Sneakiness

One of the things that I like most about Xcode is the auto-insertion of a closing curly-brace on the second line below whenever I enter an opening curly-brace, and the insertion of the cursor on the line in-between them. However, at heart I'm still a Vim guy, and tonight I got tired of actually typing that closing curly-brace. So, to make Vim automagically create my curly-brace blocks for me, I did the following.

In my .vimrc, I place the following lines


if has("autocmd")
autocmd FileType c source ~/.vim/brace.vim
autocmd FileType cpp source ~/.vim/brace.vim
autocmd FileType objc source ~/.vim/brace.vim
autocmd FileType java source ~/.vim/brace.vim
autocmd FileType pl source ~/.vim/brace.vim
endif


brace.vim is very simple, containing only the following line:

imap { {<CR>}<Esc>O


This causes typing a opening curly brace to immediately insert a Carriage Return character (equivalent to pressing return/enter) then inserts a closing curly-brace, then switching to command-mode and "typing" O to place an insert-mode cursor on a newly-inserted line above the closing curly-brace.

If anyone has a better way to do this, I'm open to suggestions.

Tuesday, October 28, 2008

Here's a handy little tool I've used often...

Problem: In several applications, I've found the need to pop up an alert/message window telling the application user that something went wrong, or that something they did wasn't kosher.

Solution: NSRunAlertPanel. Little macros like this one are additional reasons I love programming for the Mac. But to make it a little more useful, I created a method call that makes a dummy alert with an ok button and a given message. It looks like this:



-(void) displayAlert:(NSString*) alertMsg {
NSRunAlertPanel(@"Alert", alertMsg, @"OK", nil, nil);
}


The actual NSRunAlertPanel macro signature looks like this:


NSRunAlertPanel(NSString *title,
NSString *msgFormat,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton)


Other parameters can be added to the method signature to create more full-featured alerts. I created the method solely to remove the NSRunAlertPanel call (which can be a big method call) from the logic of what I'm doing at the moment and replace it with a short method call that does what I want it to.

Sunday, October 26, 2008

Publishing a Bonjour networking service with NSNetService

So I'm working on an undisclosed (but totally awesome) iPhone/iPod Touch app for CS 598R (a capstone/senior project class), and have developed the following procedure for publishing a Bonjour service. I'm posting it here so I can always know where to find code that does what I want.

Feel free to use the code, just don't blame me if it doesn't do what you want it to...

You can see the basic sample code here, or on the BYU CocoaHeads site here.

Thursday, May 22, 2008

NSMutableArray makes awesome Cocoa stacks and queues

A difference between Java and Objective-C/Cocoa? Java has ConcurrentLinkedQueue, PriorityBlockingQueue, ArrayBlockingQueue, blah blah blah.

Objective-C/Cocoa(or Foundation) has NSMutableArray. NSMutableArray has some nice instance methods that make it _extremely_ easy to build a queue, stack, priority queue (synchronized or otherwise) without loading up the API with a billion separate classes.

Need a stack?

-(void) push:(id) item {
[list addObject:item] // where list is the actual array in your stack
count++;
}

-(id) pop {
id r = [list lastObject];
[list removeLastObject];
count--;
return r;
}

How about a queue?


-(void) enqueue:(id) item {
[list insertObject:item atIndex:0];
count++;
}

-(id) dequeue {
id r = [list lastObject];
[list removeLastObject];
count--;
return r;
}

Priority queueing and/or synchronization for thread-safety will be left as an exercise for the reader. Man, I've always wanted to say that... :)

Wednesday, May 21, 2008

NSThreads when you need to wait.

For my webserver project I need to use queues. The main thread places connections that need to be serviced in a queue. "Worker" threads need to place log entries in a queue to be written out to the log file. These queues obviously need to be thread-safe. Writing a thread-safe queue is quite simple thanks to the NSLock and NSConditionLock classes. Just like any other semaphore, you create a NSLock object and surround your critical section with:

[myLock lock]
critical section...
[myLock unlock]

The real question I had to deal with here, though, was thoroughly testing my queues to make sure that they were _really_ thread safe. Unlike POSIX threads, Cocoa/Foundation has no mechanism for waiting on NSThread objects. But I needed to know that all of my testing threads were finished before I started comparing expected and actual results. The solution is not that difficult. The entry point/run loop for an NSThread object is a method with the mandatory signature:

(void) threadFuncName:(id)

So you create a struct or a class that has any data you need to pass in to your thread's main function. In addition, include in this struct or class an object of NSConditionLock. Immediately upon entry to the function, lock this with some condition code that will let your main program thread know that the thread is running. After spawning the thread, you want the main program execution to try and lock your condition lock when the run condition is no longer true. This will cause your main program thread to block and wait for your new thread to unlock with the condition you're waiting on. The last thing you'll want to do before your thread exits the run loop function is unlock the NSConditionLock with some condition that will let your main program thread know it's done. This will unblock your main thread of execution and you're off.
Sample code: (not complete, just the snippets that you'll need)


#import <Foundation/Foundation.h>
#define NOT_DONE 0
#define DONE 1

// this will need to be on some class that is calling the NSThread object
-(void) someFunc:(id) arg {
NSConditionLock* myLock = arg;
[myLock lock];
//do stuff that we need to know about in main
[myLock unlockWithCondition:DONE];
}


int main() {

NSConditionLock* finishedLock = [[NSConditionLock alloc]
initWithCondition: NOT_DONE];

NSThread* myThread = [[NSThread alloc] initWithTarget:self
selector:@selector(someFunc:) object:finishedLock];

[myThread start];

[finishedLock lockWhenCondition:DONE];

// now we can do whatever we need to do with the results from
// the thread we spawned

}


Wednesday, May 14, 2008

Is it love?

I've decided to use Objective-C and the Cocoa/Foundation frameworks to implement the main project for my internet programming class.

My mission: to build a multi-threaded (yet limited functionality) webserver with CGI capability by the 3rd week of June.

Pros:
1. I'd like to work for Apple someday, and building a webserver with their technology seems a good resume-booster.
2. Objective-C (with the Foundation/Cocoa frameworks) is a pretty nifty language with some good features that I'm quite keen to learn about
3. I'll be learning a lot, which I care much more about than grades

Cons:
1. I'll be learning a lot, so I'm not likely to get an A in this particular class
2. I've had to do a lot of research on threading/synchronization so I'm a little behind on a project. (2 days, but who's counting?)
3. Learning the quirks of a new language means I'll be working at the last minute most of the semester, whereas if I just used C and POSIX threading/synchronization libraries I could probably whip this together pretty quickly.

Is it love? I guess I'll know in a few weeks.

Tuesday, March 18, 2008

AppleScript, Growl, and iCal

Problem:
After deciding that a little more organization would do me some good, I started using iCal. But I still kept forgetting due dates. Email notifications of iCal events were not much help, since I don't use a mail client with any frequency. I hated the message alarms from iCal, but I like Growl, and I especially like the idea behind Creme Rappel (sorry, no accent marks here).

Solution:
So I started tinkering around with iCal's AppleScript dictionary. After a _lot_ of work, and lots of digging around the internets, I cobbled something together that fits the bill. The idea is that when an iCal alarm is triggered, you run an app that looks through your calendars to find the event that triggered an alarm within the current 2-minute window (leaving a little room for error) and tell Growl to tell you about it. You'll need Growl (included in .zip file) installed for this to work.

Disclaimer: If you've got a lot of calendars and events, it will take a minute to churn through them. I'm working on a more efficient way to do this, but now that it's working, school is going to have to come first for a while.

You can get iCalGrowl here.

Screenshot:

Tuesday, February 26, 2008

Monolingual: Handle With Care

So I learned something interesting about Monolingual today: If you remove all the PPC stuff from your universal binaries, you won't be able to build and link Xcode projects. So if you think you need to save the megabytes of disk space that trimming PPC code from universal binaries will get you, think again if you use Xcode.

Or tell me how you worked around this.