Important edit: in Safari 7.0, you can reload the page by selecting the "Resources" view, and clicking the refresh arrow next to the top-level page. [It seems you can also do it in at least some versions of Safari 6 by selecting the document tab, clicking the top-level page to select it, and pressing Command+R (the same shortcut used to refresh the page in normal Safari).] Breakpoints you set will still exist if you refresh the page from the Safari Web Inspector, because doing so does not cause SWI to detach the way reloading the page from within your app or the Xcode debugger does. This means that as long as the page doesn't do a Javascript redirect or trigger side-effects in the app itself, you can step through the onload Javascript by loading the page once, setting your breakpoint there, and then reloading the page from within SWI.
Original post: The only solution I was able to find was putting in an "extra" call to shouldStartLoadWithRequest:
as follows:
Add a script (not onload, synchronous) as the first element in the page head:
<script type="text/javascript"> window.location = "myapp://catchme"; </script>
Set an XCode breakpoint in
shouldStartLoadWithRequest:
Edit the breakpoint to set a condition of:
(bool)[[[request URL] absoluteString] isEqualToString:@"myapp://catchme"]
(Without this condition it will stop on the initial
shouldStartLoadWithRequest:
call, which isn't what you want because the page won't yet be available to attach the Mobile Web Inspector to at this stage.)Start the page load, and when it hits the (Xcode) breakpoint, switch to Safari, and launch Mobile Web Inspector with Develop > iPhone Simulator > (my page), then switch back to Xcode and resume execution within a short window before all the resource requests on the page time out.