AddressBook search app written in MacRuby
In my pursuit of learning MacRuby, I decided to write a small utility application on top of Apple’s Address Book. The idea was to be able to quickly – in just a few key strokes and one or two mouse clicks – access the most common information about the person such as: full name, main phone number, email address and home address and have it copied to the system clipboard.
For that I made my application live in the system bar:
systemBar=NSStatusBar.systemStatusBar
@menu1=systemBar.statusItemWithLength(NSVariableStatusItemLength)
ico=NSImage.imageNamed('ab1').setSize([21,21])
@menu1.setImage(ico)
@menu1.setAction("toggleView:")
Assigning it an icon which when clicked would trigger appearance of a search panel similar to the Spotlight.
Additionally, I wanted to have the search panel appearing in response to the hot key. This can be done by registering the global monitor for the NSKeyDown event, like that:
eventMonitorG = NSEvent.addGlobalMonitorForEventsMatchingMask(
(NSKeyDownMask),handler:Proc.new do |incomingEvent|
targetWindowForEvent = incomingEvent.window
if targetWindowForEvent!=@window
if incomingEvent.type == NSKeyDown
if incomingEvent.keyCode == 53 #Esc
if incomingEvent.modifierFlags==1310985 #Ctrl=Cmd
#here comes code showing the search panel etc
end
end
end
end
end)
The system contacts records can be accessed using the classes from AddressBook.framework. For my purpose I decided to search only by the full name so I had to extract these info from the Address Book. At the same time I fetched the unique identifier for each contact which later on will be used for getting the detailed information:
tempBook =ABAddressBook.addressBook
@tmpPeople=[]
tempBook.people.each do |p|
tmpPeople<< [p.valueForProperty(KABFirstNameProperty).to_s+"
"+p.valueForProperty(KABMiddleNameProperty).to_s+"
"+p.valueForProperty(KABLastNameProperty).to_s,
p.valueForProperty(KABUIDProperty).to_s]
Filtering of the contacts occurs live while typing to a search box using a NSPredicte class and the string value sent by the search box. Here I am filtering by the occurrence of the string:
a=sender.stringValue
predicate=NSPredicate.predicateWithFormat("SELF[0] contains1 \'#{a}\'")
@results=@tmpPeople.filteredArrayUsingPredicate(predicate)

“@results” array is used to feed the data into a table residing in the drawer which opens when the array has at least one element.
To communicate between the app controller object and the table controller object I use the NSNotification center class sending the “@results” object as an “attachment” (line 1). The notification observer is defined in the table controller class (line 2):
NSNotificationCenter.defaultCenter.postNotificationName("viewControllerCNotification",object:@results)
NSNotificationCenter.defaultCenter.addObserver(self,selector:"receiveNotification:", name:"viewControllerCNotification",object:@results)
Finally, when I hover over email, telephone etc and click, the info gets copied to the system clipboard, using this simple snippet:
pasteboard=NSPasteboard.generalPasteboard pasteboard.clearContents pasteboard.writeObjects([value.stringValue])
If you want to see how other things were implemented, e.g. setting up the “run at login” – check the complete source code which is deposited at the GitHub.
If you find the information useful consider supporting the author.
MTFBWY
K



