Luke Dennis
Luke Dennis

Reputation: 14550

Automatically open the Safari Debugger when the iPhone Simulator is launched

The iOS web debugger in Safari is the bee's knees, but it closes every time the Simulator is restarted. Not only is it annoying to re-open it from the menu after every build, but it makes it tricky to debug any behavior that happens during startup.

Is there a way to set up a trigger in Xcode to automatically open the Safari debugger after every build, or perhaps a way to build a shell script or Automator action to do a build and immediately open the debugger?

Upvotes: 23

Views: 7831

Answers (5)

Extending upon the @Prisoner's answer, if you use WKWebView you could:

    let contentController:WKUserContentController = WKUserContentController()


    let pauseForDebugScript = WKUserScript(source: "window.alert(\"Go, turn on Inspector, I'll hold them back!\")",
                                           injectionTime: WKUserScriptInjectionTime.AtDocumentStart,
                                           forMainFrameOnly: true)
    contentController.addUserScript(pauseForDebugScript)

    let config = WKWebViewConfiguration()
    config.userContentController = contentController
    //Init browser with configuration (our injected script)
    browser = WKWebView(frame: CGRect(x:0, y:0, width: view.frame.width, height: containerView.frame.height), configuration:config)

also important thing is to implement alert handler from WKUIDelegate protocol

//MARK: WKUIDelegate
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
             initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void) {

    let alertController = UIAlertController(title: message, message: nil,
                                            preferredStyle: UIAlertControllerStyle.Alert);

    alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel) {
        _ in completionHandler()}
    );

    self.presentViewController(alertController, animated: true, completion: {});
}

and one little thing just in case you could have an UIAlertController:supportedInterfaceOrientations was invoked recursively error add following extension (From this SO Answer)

extension UIAlertController {     
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }
    public override func shouldAutorotate() -> Bool {
        return false
    }
}

Upvotes: 3

Dev01
Dev01

Reputation: 14149

This is a partial solution. This opens the debug window of Safari with one click which is a lot better but not automatic.

Open Script Editor on your mac (Command + Space Bar and type in Script Editor)

Paste in this code:

-- `menu_click`, by Jacob Rus, September 2006
-- 
-- Accepts a list of form: `{"Finder", "View", "Arrange By", "Date"}`
-- Execute the specified menu item.  In this case, assuming the Finder 
-- is the active application, arranging the frontmost folder by date.

on menu_click(mList)
    local appName, topMenu, r

    -- Validate our input
    if mList's length < 3 then error "Menu list is not long enough"

    -- Set these variables for clarity and brevity later on
    set {appName, topMenu} to (items 1 through 2 of mList)
    set r to (items 3 through (mList's length) of mList)

    -- This overly-long line calls the menu_recurse function with
    -- two arguments: r, and a reference to the top-level menu
    tell application "System Events" to my menu_click_recurse(r, ((process appName)'s ¬
        (menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click

on menu_click_recurse(mList, parentObject)
    local f, r

    -- `f` = first item, `r` = rest of items
    set f to item 1 of mList
    if mList's length > 1 then set r to (items 2 through (mList's length) of mList)

    -- either actually click the menu item, or recurse again
    tell application "System Events"
        if mList's length is 1 then
            click parentObject's menu item f
        else
            my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
        end if
    end tell
end menu_click_recurse

menu_click({"Safari", "Develop", "Simulator", "index.html"})

Once the simulator has opened, click run on your script (you might need to allow the script editor in the settings the first time).

(Optional) You can save your the scripts as an app so that you don't have to have the script editor open.

Upvotes: 13

Mike N
Mike N

Reputation: 6785

Combining Tom's answer with my solution, first do the following:

  • Create an application as Tom describes above
  • In "System Preferences -> Security & Privacy -> Privacy -> Accessibility" add your new Script Applicaiton and make sure it is allowed to control your computer

Now, I'm using cordova and from the command line the following builds, runs emulator and opens safari debug console:

cordova build ios; cordova emulate ios; open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app; sleep 1 ; open /PATH/TO/OpenDevelop.app/

Make sure to replace /PATH/TO/ with the appropriate path to where you saved your script.

Upvotes: 1

Rob Barreca
Rob Barreca

Reputation: 649

There is question that should be marked a duplicate that describes using setTimeout() to give you enough time to switch windows over to Safari and set a breakpoint.

Something like this, where startMyApp is the bootstrap function of your app:

setTimeout(function () {
  startMyApp();
}, 20000);

It is super ghetto, but does work. I've submitted a feature request via http://www.apple.com/feedback/safari.html too to close the loop.

Upvotes: 4

unbuglee
unbuglee

Reputation: 285

Humm,I don't think you can do that,but you can just "CTRL+R" in the web debugger.

Upvotes: -4

Related Questions