26

I’m following Apple’s guide for creating a Safari App Extension. In short, I’ve:

  • Created a new Xcode project (in Xcode 8.1, on macOS 10.12 Sierra) using the Cocoa Application template
  • Created a new target in the app using the Safari Extension template
  • Run the app once, to make sure the Safari App extension is built
  • Selected the “Allow Unsigned Extensions” option in Safari’s Develop menu
  • Enabled the extension in Safari’s Extensions preference pane

The extension’s toolbar button appears in Safari. Apple’s guide says I should see the NSLog message in the console when I click the toolbar button, but I’m not seeing anything.

I’ve edited SafariExtensionHandler.swift to send a message to the script injected by the extension:

override func toolbarItemClicked(in window: SFSafariWindow) {
    // This method will be called when your toolbar item is clicked.
    NSLog("The extension's toolbar item was clicked")

    window.getActiveTab(completionHandler: { (activeTab) in
        activeTab?.getActivePage(completionHandler:  { (activePage) in
            activePage?.dispatchMessageToScript(withName: "toolbarItemClicked", userInfo: nil)

        })
    })
}

And I’ve edited the injected script (script.js) to alert that message:

safari.self.addEventListener("message", function (event) {
    alert("We got a message from the extension! - " + event.name + ": " + event.message);
});

The alert appears when I click the toolbar button (when I’m on a page on webkit.org, as I’ve left in the default SFSafariWebsiteAccess settings), so the extension is working and registering the click. But I don’t see the NSLog in Xcode’s console, or the Console app.

I’m a real Xcode newbie, so I’m sure I’m missing something obvious — but why isn’t the NSLog message appearing in the console?

(I don’t run as an administrator, in case that makes a difference — although I did enter the administrator account details whenever I was asked to whilst running Xcode for the first time. I do notice that in the Console app, when I select system.log, I just see a message saying “Unable to read the file”. This might be related to not running as an administrator.)

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270

2 Answers2

28

Switch to the scheme for your extension (schemes are just to the right of the Run and Stop buttons), and then hit Run.

A Popup will ask you to choose an app to run: select Safari.

A new instance of Safari should open and you'll start seeing log output in the Xcode console.

If you haven't signed your app and extension however, Safari will reject your extension and the console will show a message like

2017-04-12 13:00:44.799843-0400 Safari[37188:2787364] [Extensions] 
Computing the code signing dictionary failed for extension with 
identifier com.your.app.extension
2017-04-12 13:00:44.799865-0400 Safari[37188:2787364] [Extensions] 
Disabling and blocking extension with identifier: 
com.your.app.extension

In this case you just need to re-check "Allow Unsigned Extensions" in Safari's Developer menu and enable the extension in the Preferences pane, after which you should be good to go.

Aaron Frary
  • 906
  • 1
  • 13
  • 24
  • Thanks it took long time for before I saw your answer :) – Simcha Jun 28 '17 at 10:07
  • Is there a way to select Safari forever as the app to run? – ZedTuX Dec 30 '17 at 17:37
  • This is the correct way. It’s sad that the *official* guide is *misleading* by saying that “*Make sure that your macOS app is selected*”. – Franklin Yu Sep 19 '18 at 04:53
  • OH THANK YOU! I've been googling for a very long time.. Now, when is it appropriate to select the other schema? – mccc Feb 01 '19 at 21:37
  • 1
    The trouble with using the extension scheme and not having signed your app and extension is that you need to "Allow Unsigned Extensions" (plus other steps) every time you rebuild. It's easier to use the app scheme with the Console program (which also gets NSLogs), and filter messages there by "Safari Extension". – Will White Jul 21 '19 at 08:40
  • @WillWhite I am using app scheme but no NSlog shows up. I am kind curious about the Console program you mentioned, can you tell me more about this? – yuan Dec 06 '19 at 12:47
  • @innocentDrifter Console comes with macOS. – Will White Dec 07 '19 at 13:57
  • @WillWhite I am now using app scheme, so where should I check those logs in Console? Open terminal? – yuan Dec 09 '19 at 03:11
  • @innocentDrifter Console is an application in Applications:Utilities. – Will White Dec 09 '19 at 10:55
0

Xcode 10.2 beta ships with the new method to achieve that: SFSafariToolbarItem.showPopover()

Reference: https://developer.apple.com/documentation/safariservices/sfsafaritoolbaritem?changes=latest_minor

pronebird
  • 12,068
  • 5
  • 54
  • 82