App Store Hidden Preferences

- 2011-01-06 19:45:49

See the Update at the end before you get excited :(

Having just installed 10.6.6 to use the Mac App Store, I was slightly annoyed that it fills my dock with apps as I install them. I'm a bit strange, in that I use a hidden preference to make the dock uneditable (it stops me accidentally dragging an app off.) But that means I can't drag off the Mac App Store installed apps either.

Had a quick look through /Applications/App Store.app/Contents/MacOS/App Store with strings (love that tool) and noted a few strings that looked interesting. (There's a full list in this gist.) There wasn't anything that explicitly stated it stopped it putting anything in the dock, but I did notice an option that stopped it showing install progress in the dock.

Yank up a terminal window, bash out the following...

defaults write com.apple.appstore FRDebugShowInstallProgress -bool NO

...head back to the MAS and install another (free) app, and hey presto, it's leaving my dock alone! Hopefully that's all I needed to continue using my Dock as I like. (Hidden, and left alone.)

Find any other hiddens prefs for the MAS? Mail me or leave a comment and I'll update accordingly.

Update 2011-01-06:

Seems my joy was short-lived. I'd re-downloaded an app I'd already purchased and it just showed download progress in the MAS app, not in the dock. Installing new applications still shows up in the dock (annoyingly.)

I've been having a poke through how it all hangs together, and if it's possible to actually block downloads from the Dock or not. It doesn't look like there's a hidden preference to hide new apps from downloading in the dock, you can just disable the progress bars in the dock with prefs. The MAS.app seems to be codenamed "Firenze", with the "hidden" prefs being prefixed with "FRDebug".

As I understand it, the App\ Store.app invokes a binary inside /System/Library/PrivateFrameworks/CommerceKit.framework called "storeagent" to do the actual downloading/talking to the dock. From looking at the class-dump of storeagent it communicates with the dock to place a new type of DockTile. Interesting sounding methods to (potentially?) swizzle are -[DownloadQueue sendDownloadListToDock] and -[DownloadQueue tellDockToAddDownload:].

I've given up for now, but I reckon it should be possible to create a bundle that swizzles the right methods in storeagent to stop it placing the downloads on the Dock.

Facebook iPhone app Contact Sync isn't automatic

- 2010-10-06 14:10:06

There's an article on the guardian about private phone numbers being uploaded from facebook, and another over techeye.net on the same subject.

Firstly a quote from the techeye article:

Facebook doesn't warn users that they are uploading their phone's address book to Facebook.

And whilst the guardian article never says it happens automatically, it also doesn't lay it out that you have to explicitly enable that feature, and agree to the facebook app uploading the data.

I was pretty sure that facebook wouldn't be grabbing all your contact information without telling you, if they did at all, and that both articles were just pure scaremongering. So I fired up the facebook iPhone app, headed into my friends list on there, clicked sync and got the following screen:


View Original

Ok, so according to that text, they're just pulling down profile images and profile links from facebook and putting them in your address book against your contacts. Seems fairly harmless so far. So I toggled the top switch, to enable Contact Sync, and got the following screen:


View Original

Reading that, it's fairly obvious what data facebook are uploading (although a little ambiguous why), and it certainly isn't happening automatically. As it says, it uploads the "name, email address, phone number" from all your contacts to facebook, and pull down "your friends' profile photos and other info from Facebook".

So whilst facebook are collecting more data (albeit stored subject to their Privacy Policy), it's certainly NOT done automatically, and is very explicit about what is being uploaded at the point you enable it.

+[NSObject load] in MacRuby

- 2010-06-12 02:11:32

If you've not heard of it, MacRuby is an implementation of Ruby 1.9 directly on top of Mac OS X core technologies such as the Objective-C runtime and garbage collector, the LLVM compiler infrastructure and the Foundation and ICU frameworks. Basically means you write in Ruby using Objective-C frameworks, and vice versa. It's pretty damn cool to be honest!

What is +[NSObject load]?

From the documentation:

Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

This means when your class is loaded, and implements the load method, you get a load message sent to your class. Which means you can start doing stuff as soon as your class is loaded by the runtime.

The main place I've seen it used (and used it myself) is in SIMBL plugins. A SIMBL plugin is an NSBundle that contains code which is loaded (injected) into a running application shortly after said application is launched. It lets you extend (or "fix") cocoa applications with additional features. So you have this bundle of code, that gets loaded into a running application some point after it starts, and you want to run some code as the bundle is loaded - usually to kick off doing whatever you want to do in the plugin. This is where load becomes useful.

Here's a quick implementation that just logs to the console:

@implementation MainController

+ (void) load
{
    NSlog(@"MainController#load called");
}

Now where does MacRuby come into this?

Well I came across a need to do the same in ruby, have some code triggered when the class is loaded into the runtime. Tried implementing Class.load but to no avail. Then remembered MacRuby is just ruby! And I can call any code from within my ruby class definition.

For continuity I still call it Class.load, but then call it as soon as I've defined it in the class. Eg:

class MainController

    def self.load
        NSLog "MainController#load called"
    end
    self.load

end

Of course, I'm not sure when the Objective-C method is called, it's probably after the entire class has been defined rather than as soon as load has been loaded into the runtime. So you might want to move the self.load call to just before the closing end.

Potty Training YAML

- 2010-05-10 21:46:17

Ran into a problem today where I have a class with a few attributes on it, but I only want a certain three of those attributes to appear in the YAML dump of a class instance.

Diving straight into a code example--lets say we have a Contact class, and we only want to dump the name, email and website attributes.

require "yaml"

class Contact
    attr_accessor :name, :email, :website, :telephone

    # helper method to make setting up easy
    def initialize params={}
      params.each do |key, value|
        meffod = "#{key.to_s}="
        send(meffod, value) if respond_to?(meffod)
      end
    end
end

# And create an instance for us to play with
caius = Contact.new(
  :name => "Caius",
  :email => "dev@caius.name",
  :website => "http://caius.name/",
  :telephone => "12345"
)

As we'd expect when dumping this, all instance variables get dumped out:

print caius.to_yaml
# >> --- !ruby/object:Contact 
# >> email: dev@caius.name
# >> name: Caius
# >> telephone: "12345"
# >> website: http://caius.name/

Initially I tried to override to_yaml and unset the instance variables I didn't want showing up, but that just made them show up empty. After digging around a bit more, I happened across the Type Families page in the yaml4r docs, which right at the bottom mentions to_yaml_properties.

Turns out to_yaml_properties returns an array of instance variable names (as strings) that should be dumped out as part of the object. A quick method definition later, and we're only dumping the variables we want. (See my Ruby Shortcuts post if you don't know what %w() does)

class Contact
    def to_yaml_properties
        %w(@name @email @website)
    end
end

And now we dump the class, expecting only the three attributes to be outputted:

print caius.to_yaml
# >> --- !ruby/object:Contact 
# >> name: Caius
# >> email: dev@caius.name
# >> website: http://caius.name/

Success!

Ruby Shortcuts

- 2010-03-18 22:32:45

There's a few useful shorthand ways to create certain objects in Ruby, a couple of obvious ones are [] to create an Array and {} to create a Hash (Or block/Proc). There's some not so obvious ones too, for creating strings, regexes and executing shell commands.

With all of the examples I've used {} as the delimiter characters, but you can use a variety of characters. Personally I tend to use {} unless the string contains them, in which case I'll use // or @@. My only exception appears to be %w, for which I tend to use ().

Strings

% and %Q are the same as using double quotes, including string interpolation. Really useful when you want to create a string that contains double quotes, but without the hassle of escaping them.

%{}                 # => ""
%Q{}                # => ""

%{caius}            # => "caius"
%{caius #{5}}       # => "caius 5"
%{some "foo" thing} # => "some \"foo\" thing"

%q is equivalent to using single quotes. Behaves exactly the same, no string interpolation.

%q{}           # => ''
%q{caius}      # => "caius"
%q{caius #{5}} # => "caius \#{5}"

Arrays

%w is the equivalent of using String#split. It takes a string and splits it on whitespace. With the added bonus of being able to escape whitespace too. %W allows string interpolation.

%w(foo bar sed)  # => ["foo", "bar", "sed"]
%w(foo\ bar sed) # => ["foo bar", "sed"]
%W(foo #{5} bar) # => ["foo", "5", "bar"]

Regexes

%r is just like using // to create a regexp object. Comes in handy when you're writing a regex containing / as you don't have to continually escape it.

%r{foo|bar} # => /foo|bar/
%r{foo/bar} # => /foo\/bar/

Symbols

%s creates a symbol, just like writing :foo manually. It takes care of escaping the symbol, but unlike :"" it doesn't allow string interpolation however.

%s{foo}      # => :foo
%s{foo/bar}  # => :"foo/bar"
:"foo-#{5}"  # => :"foo-5"
%s{foo-#{5}} # => :"foo-\#{5}"

Shelling out

%x is the same as backticks (``), executes the command in a shell and returns the output as a string. And just like backticks it supports string interpolation.

`echo hi`     # => "hi\n"
%x{echo hi}   # => "hi\n"
%x{echo #{5}} # => "5\n"