MacRuby, CocoaPods, 10.7, and XCode 4.3

I have a MacRuby project that uses CocoaPods for many of its ObjC dependencies. I had a bit of trouble getting it to run properly with the latest version of Xcode (4.3). This had to do with a recent change I made to MABSupportFolder (use of isEmpty()) which triggered a fairly obscure bug in addition to the new XCode 4.3 organizational structure not being properly recognized at first.

The obscure MacRuby bug was being caused by running -count on an NSString. When using MacRuby if you test if a NSString responds to -count using -respondsToSelector: you’ll get true as the response because of Ruby’s String#count method. However, that method requires an argument, but running respondsToSelector:@selector(count) will return true for an NSString. This bug was triggered because of my usage of Will Shipley’s isEmpty() function.

If you recently upgraded to Xcode 4.3, make sure you run this command (got this tip from here):

[code]sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer[/code]

Or `pod install` will not run properly. Also, I just found out that CocoaPods does not use macruby anymore – you can run it using the system ruby install.

For someone trying to get MacRuby working with CocoaPods here is my Podfile: [codee] platform :osx

dependency ‘FMDB’ dependency ‘ASIHTTPRequest’ dependency ‘MABToolkit’ dependency ‘KFAppleScriptHandlerAdditions’

# Enable garbage collection support, which MacRuby requires. post_install do |installer| installer.project.targets.each do |target| target.buildConfigurations.each do |config| config.buildSettings[‘GCC_ENABLE_OBJC_GC’] = ‘supported’ end end end

generate_bridge_support! [/codee]

The top of your main.rb should look like this:

[code]

framework ‘Cocoa’

load_bridge_support_file NSBundle.mainBundle.pathForResource(“Pods”, ofType:”bridgesupport”)

[/code]

Continue Reading

Fun With PyObjc: Growl Notification Hell

Most of the time PyObjc is wonderful to work in, I love the python libraries and language.

Other times it just makes me angry.

It seems, at least initially, that PyObjc (2.2b3, the default installation with 10.6 snow leopard) does not work with the Growl framework. You can register your application with growl fine, but if you try to push notifications to growl nothing happens.

Here is what I tried initially to post a growl notification in pyobjc:

[code lang=”python”] GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(u”Notification”, “A description.”, u”Notification”, objc.nil, 0, objc.NO, objc.nil) [/code]

This does not work, and for a minute I thought I was the only one experiencing this problem (all open source pyobjc projects using growl had almost identical growl notification code) until I found this commit message on github. I found an associated discussion on the growl discussion group and was disheartened that the developer resorted using a command line version of growl to post notifications. However I decided to try one last thing, and checked the className of python objects passed through the objc bridge.

Here is a table of the objc className of different string creation methods in python:

unicode(“a string”) or u”a string”: OC_PythonUnicode str(“a string”) or “a string”: OC_PythonString r”a string”: OC_PythonString

Interestingly enough a python string (unicode, str, raw) is not ‘toll free’ bridged like CFString & NSString are. I guess this is to be expected and shouldn’t cause any problems since both OC_PythonString and OC_PythonUnicode are subclasses of NSString, the documentation even states “A Python unicode may be used anywhere a NSString is expected”. It seems that this is not always the case though. I tried one last thing before resorting to rewriting the code in objc:

[code lang=”python”] GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(NSString.stringWithString_(“Notification”), NSString.stringWithString_(“A description.”), NSString.stringWithString_(“Notification”), objc.nil, 0, objc.NO, objc.nil) [/code]

And it worked. Note that the created NSString’s don’t get converted by the bridge into a OC_PythonString object, they pass through as regular NSString’s. Note that you also write the above as the more python native:

[code lang=”python”] GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(NSString.stringWithString_(“Notification”), NSString.stringWithString_(“A description.”), NSString.stringWithString_(“Notification”), False, 0, False, None) [/code]

One other interesting that I found is that bridge throws a memory leak warning when running NSString.alloc().initWithString_("Notification"):

[code] UninitializedDeallocWarning: leaking an uninitialized object of type NSPlaceholderString [/code]

My only guess is that because initWithString is called instead of init the bridge sees it as a uninitialized object (so I would guess that this warning is falsely thown). Unfortunately the PyObjc documentation is too sparse for me to able to determine what the real cause of the error is.

Continue Reading

Create TGZ Automator Service

With Snow Leopard came some nice refinements to automator actions. However, all existing automator actions had to be recreated as services in order to be accessed through the Finder’s contextual menu. One automator action which I used fairly often was the create tgz workflow. I always found that action to be fairly useful so I recreated it as an action.

Another unfortunate change with Snow Leopard was the elimination of input managers. This eliminated the convenient F-Script injection functionality that was present in F-Script anywhere. Luckily this functionality has been recreated using an automator service. Nice work!

Continue Reading

Jump To A HTML Anchor in a WebView

This isn’t something that is as straightfoward as you would think. There is no real ‘cocoa native’ way to acomplish this, and there seemed to be no information anywhere on how to acomplish this until I found this post. So it seems the only way to scroll to an anchor is to resort to evaluating javascript code: [code lang=”javascript”] – (void) jumpToAnchor:(NSString *)anchor { [oWebView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@”var anchor = document.anchors[“%@”];window.scrollTo(anchor.offsetLeft, anchor.offsetTop);”, anchor]]; } [/code]

Continue Reading

Don’t Forget To Flush…

No, not the toilet, your file streams.

I was recently working on a project that involved creating a child process and reading its stdout to update the user inteface. Everything was working great until I sent it off to some testers who reporting that it ‘wasn’t working’ – the interface wasn’t updating correctly. I first thought it was a problem with the shell command itself, maybe it wasn’t performing the operation correctly and thus wasn’t sending the correct message through stdout but as far as I could tell everything was working perfectly. After about 3 hours of banging my head against the wall trying random things I finally thought to flush the stdout after sending my status message. It fixed it! But why would it would fine on my laptop (intel), my desktop (ppc), but not my old laptop (ppc)? The problem arose from the fact that right after sending the data to stdout the child process would call a function that would block indefinitely. I learned my lesson, always flush the stream if you are depending on reading that output in a timely manner!

Continue Reading

XTrace 1.1

At last XTrace 1.1 is out the door! This has been a long time coming, and has alot of changes & new features:

CMD+Shift+C now clears the log window XTrace now automatically starts the trace server Added the Sparkle (auto updating) framework Added the ability to disable wrapping in the log window Added the option for window auto-close (log window will close when the SWF it is connected to closes) New icon thanks to Ale! Log message coloring/formatting thanks to Daniel Giribet Compiled & tested as a universal binary

I’ve recorded a quick tutorial on how XTrace works. If you’re new to XTrace, or just want a quick refresher I encourage you to take a look.

If you would like to get involved with development, please send me an email! If you have a feature you want added contact me and I’ll give you SVN access you so you can contribute to the project!

I want to give a big thanks to everyone who contributed ideas/code to this update, it’s great to see other people using my software and contributing time & effort to make it better for the flash community.

Actionscript 3

A lot of people have asked about Actionscript 3 support. Although I don’t use AS3 yet, someone is working on a port of my debug class to AS3 which will allow XTrace to work with AS3.

Zeroi Support

The folks over at Zeroi have created a plugin (modified debug class) that allows XTrace to work with Zeroi. If your a Zeroi user, or even if you aren’t, you may want to check it out.

Continue Reading

mach_override on Intel Macs

I was disappointed last month when after a hour or two of hacking I couldn’t get mach_override (evil, I know) to work on my new MacBook Pro even though it had been ported to intel macs. I added myself to the procmod group and tried everything that google could come up with, but I could only get it to succesfully override local functions, it wouldn’t override any library/system functions no-matter what i did.

Today I’ve found the solution on the ExtendAMac mailing list hosted on sourceforge: this simple post contains a small patch that seems to fix all the issues I’ve been having. There doesn’t seem to be any replies to the post on the mailing list, and the post wont come up on any google searched related to mach_override on intel macs – pretty frusterating when you don’t know about the ExtendAMac mailing list. The solution is very simple, replace this block of code: [code lang=”c”] static AsmInstructionMatch possibleInstructions[] = { { 0x1, {0xFF}, {0x90} }, // nop { 0x1, {0xFF}, {0x55} }, // push %esp { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp { 0x1, {0xFF}, {0x53} }, // push %ebx { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp { 0x0 } }; [/code]

with this:

[code lang=”c”] static AsmInstructionMatch possibleInstructions[] = { { 0x1, {0xFF}, {0x90} }, // nop { 0x1, {0xF8}, {0x50} }, // push %eax | %ebx | %ecx | %edx | %ebp | %esp | %esi | %edi { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp { 0x0 } }; [/code]

Hopefully this helps someone who was banging their head against the wall trying to figure this out like I was!

Continue Reading

NSSound+SoundList

It confounds me as to why Apple will provide an easy way to get a reference a standard system sound (via -soundNamed:) but doesn’t provide any easy way to get a list of available system sounds. Well, as you might of guessed, I’ve created a NSSound category that adds this functionality. The code is adapted from this cocoa-dev post. You can download the source files (BSD license) here.

On a side note I’ve updated the source code page. The underlying code is now alot cleaner (and renders correctly on IE!) and it uses some of those fancy AJAX transitions.

Continue Reading

Add To Login/Startup Items Functionality

Such a simple piece of functionality, you would assume it would be trivial to implement. As you might have guessed – it’s not. There has been a few hack-ishy ways outlined here but none are complete and easy to integrate into your app.

I’ve created MABLoginItems, an easy way to add the ‘add to startup items’ functionality into your application. With one line of code you can add your application to the users login items (you can also remove from login items, and check if the application already exists in the login items). MABLoginItems is released under a BSD license, you can download it here.

Continue Reading