Archive for the 'Cocoa' Category

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):

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

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:

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!

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

framework 'Cocoa'

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

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:

GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(u"Notification", "A description.", u"Notification", objc.nil, 0, objc.NO, objc.nil)

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:

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)

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:

GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(NSString.stringWithString_("Notification"), NSString.stringWithString_("A description."), NSString.stringWithString_("Notification"), False, 0, False, None)

One other interesting that I found is that bridge throws a memory leak warning when running

NSString.alloc().initWithString_("Notification")

:

UninitializedDeallocWarning: leaking an uninitialized object of type NSPlaceholderString

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.

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!

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:

- (void) jumpToAnchor:(NSString *)anchor {
    [oWebView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"var anchor = document.anchors[\"%@\"];window.scrollTo(anchor.offsetLeft, anchor.offsetTop);", anchor]];
}

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!

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.