Mobile Safari Inspector with the iPhone Simulator

Thanks in large part do other folks (well, mostly Nathan) who dug in and figured out the private API to enable this in WebKit, we can actually use the web inspector from the desktop Safari browser to investigate pages we are viewing on the iPhone simulator. This has been huge when I have a strange bug in the layout of a page on the iPad and can’t easily determine which element it is.

Here is my version of the script that takes things a bit further:

pid=$(ps x | egrep "MobileSafari|Web.app" | grep -v grep | awk '{ print $1 }')

if [ "$pid" == "" ]; then
  echo "Safari.app must be running in the Simulator to enable the remote inspector."
else

  cat <<EOS | gdb -quiet > /dev/null
    attach $pid
    p (void *)[WebView _enableRemoteInspector]
    detach
EOS

  osascript <<EOS > /dev/null 2>&1
    tell application "Safari"
      activate
      do JavaScript "window.open('http://localhost:9999')" in document 1
    end tell
EOS

fi

Since I use chrome as my default browser, I quickly found that the remote inspector didn’t always work with it - so I open safari automatically and load the inspector. Just one less step to worry about. I wanted to have it open the simulator and run Safari as well, but that turned out to require other tools to be installed so I punted. This is really the most common case for me anyway.

If you want a copy locally I recommend grabbing the one from my dotfiles, which I will keep up-to-date if I make any tweaks and changes.



Vimscript is Super Awesome

OK, sure it could be a little prettier, and yeah, it make simple things awkward. But it has one killer feature that I think is often overlooked. Vimscript uses the same commands that you use when editing a file.

This is actually really cool. Basically if you can do something while using the editor you can do it in a script. Think about that, you can really automate everything you already do, and since you already do it–you know how to automate it. The inverse is true as well, if you read it in a script you can do that while editing.

A quick example. Strip trailing white space. I’ve done this often, open a file with a ton of garbage whitespace, and want to strip it out. Open google and search for “vim remove trailing whitespace” and use some reqular expression in a search and replace command. But this can be automated easily.

Instead of having to remember this command:

:%s/\s\+$//e

I make a command that will do it:

command Trim %s/\s\+$//e

Now I just have to remember the command, and Trim is much easier for me to remember.

Or get make a funciton that I can call from other vim script:

function! Trim()
    %s/\s\+$//e
endfunction

It just keeps building on the same commands. And really, what could go wrong?

If you want to learn more, I hightly recomend Steve Losh’s Learn Vimscript the Hard Way. I also have a more robust version of the trim command.



Navigating the Command Line

When learning to love the command line, nothing made a bigger difference to me than when I discovered I could edit commands with out pressing and holding the arrow keys. That was just slow and awkward. There is a better way. Really you only need two or three little tricks and you will be in a whole new world of productivity.

If you can only learn one thing, learn these two keyboard shortcuts:

Jump to the beginning

Pressing control-a will jump the cursor to the beginning of the line.
Mnemonic: Control-Awesome I can move back to the beginning with out holding the arrow key.
Also I find I remember this because the A key is the furthest left key on the home row.

Jump to the end

Pressing control-e will jump the cursor to the end of the line.
Mnemonic: Control-End

Now, take a few minutes to go give those a try. I’ll wait.

Want some more? Rad. But a little caution if you are just learning these things: just pick a couple and find ways to use them until they are second nature. Practice. If you think you are ready for more, here you go. I think these are the next most useful:

Delete Back a Word

Pressing control-w will delete the word before the cursor.
Mnemonic: Control-Why did I type that Word

Delete to the End

Pressing control-k will delete from the cursor to the end of the line
Mnemonic: Control-Kill to the end of the line

Delete to the Beginning

Pressing control-u will delete from the cursor to the beginning of the line
Mnemonic: Control-Uhh that wasn't right

I think these are the most critical shortcuts to learn, and have made life on the command line damn nice.

A Bit About Input Modes

Really I should end this post here, but am somehow compelled to mention this thing called input modes.

There are two input modes that a command line will use: vi or emacs.

The examples above assume you are using emacs mode for your shell. This is the default for bash and most other shells. If you are having problems with them you may need to set the input mode. In bash you can simply run set -o emacs

I can hear you asking “But wait, you are a vim guy, why do you use emacs mode for your shell?”

Well, it wasn’t an easy choice. I thought I would like vi mode on the command line. And I tried to use it. I wanted to want to. But in the end it was just never felt right.

My reasons:

  1. It is the default on most systems. Nice to open a new term on a strange server and have things Just Work™.
  2. Anywhere libreadline is used these things will work. Basically this is the line editing library that most terminal based apps will use. This includes your shell, bash, irb, ipython, irc clients and the like.
  3. I use a Mac, and there is a decent overlap between the default keyboard shortcuts in Cocoa and emacs mode.
  4. On the command line I can quickly edit the command in vim by mashing Control-X Control-E or running fc.
  5. And probably the most critical reason is I have the exact same keybindings in Vim’s insert and command modes.

Ignore Advice from Blog Articles

The only thing you should do is pick some tools and learn them. Don’t worry about what some random blog article says. Don’t worry about those kids on irc demanding you use zsh. Don’t worry about editors – learn something. It will all translate in some way, won’t be wasted effort. Most important thing you can do as a developer is train how to use your tools.

What do you use?

What command line tricks do you use to make your day happier?



Making ARC and non-ARC files play nice together

If you want to exclude a file from being compiled with ARC you can do so by setting a flag on the .m file:

Click the Project -> Build Phases Tab -> Compile Sources Section -> Double Click on the file name

Then add -fno-objc-arc to the popup window.

Likewise, if you want to include a file in ARC, you can use the -fobjc-arc flag.

Xcode Screen Shot

See the clang docs for more details.

A helpful trick is to use the __has_feature language extension to throw errors when this is not set properly.

Enforce a file is ARC:

#if ! __has_feature(objc_arc)
#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag
#endif

The inverse:

#if __has_feature(objc_arc)
#error This file cannot be compiled with ARC. Either turn off ARC for the project or use -fno-objc-arc flag
#endif

This was adapted from a post by Greg Parker on the on the Objective-C mailing list. He goes on to point out the following:

You should be careful with the interface to your shared code such that ARC and non-ARC clients can use it freely.

  • Conform to Cocoa’s memory management conventions even though an all-ARC or no-ARC project would not require it
  • Don’t use object pointers inside C structs
  • Avoid CF types


Prevent Xcode from opening extra projects

Insistent I don’t want persistence.

I’ve been a little annoyed with Xcode on Lion. Every time I open a project it also opens the last project I was working on. This might be fine if I was only working on one project – but recently I have been working on Captured in the evenings, and Zippy’s iPhone app during the day. I don’t want to open the project for Captured when I get to work in the morning. Plus it is particularly frustrating when one of those projects is a workspace, if you create a new project Xcode insists on adding it to the current workspace.

The solution: fix my xcode script, by passing in a user defaults flag.

I have been using a helper function to load xcode from the command line for a while now, and really it is the primary way that I open a project. Maybe I am in minority for Cocoa developers, but I live on the command line – so this is better for me.

#!/usr/bin/env ruby
f = []
f.concat Dir["*.xcworkspace"]
f.concat Dir["*.xcodeproj"]

if f.length > 0
  puts "opening #{f.first}"
  `open -a /Developer/Applications/Xcode.app #{f.first} --args -ApplePersistenceIgnoreState YES`
  exit 0
end

puts "No Xcode projects found"
exit 1

The trick is the ApplePersistenceIgnoreState option passed in to Xcode, this overrides the NSUserDefault for the app persistence.

If you want to use this, just create a file xcode somewhere in your path and then set it to be executable chmod +x xcode. Then opening project is as simple as:

cd path/to/proj
xcode

Refreshing.