4

I have an Electron application that integrates with OS X Finder via a Finder Sync extension. Overall, the application has three parts:

  1. Electron application
  2. Swift Application
  3. FinderSync extension

The Electron application is the main entry point. On start up, it creates a child process that runs the Swift application. The Swift application has embedded in it, the FinderSync extension. The Swift app and FinderSync extension communicate over ICP so that the FinderSync extension can get the correct information for badges and context menus.

I build everything with electron-builder. It ends up with a structure like:

 - MyElectronApp.app
   - Contents
     - PlugIn
       -  MyExtension.appex
     - MacOS
       -  MySwiftApp.app
         - Contents
           - PlugIn
             - MyExtension.appdex
           - (All the other app contents)

When I install the application and when I run it, I see this in Console.app

rejecting; Ignoring mis-configured plugin at [/Applications/MyElectronApp.app/Contents/MacOS/mySwiftApp.app/Contents/PlugIns/myFinderExtension.appex]: plug-ins must be sandboxed

The plugin is marked as sandboxed, This is for the inner instance of the plugin. I do not get this for upper one.

When I launch the application, I can see that my plugin is running in the Finder Extensions Preference Pane. If I toggle the extension in the Preference Pane, I can see in Console.app that the extension and Swift app are communicating with each other. But I do not see my context menu or badges in Finder.

I do see this in the logs for my Swift application and Finder Extension:

LSExceptions shared instance invalidated for timeout.

The extension is Sandboxed and the Swift app is not. It took me awhile to get those entitlements "correct". I have the plugin listed twice in the Electron app. I found that if I didn't put it in the top level PlugIn directory, then it would not be registered with the OS. When I query pluginkit, I see that the first instance of the extension is running. The extension and the Swift app have the same application group so they can do IPC.

At this point, I'm not really sure what I can do. It seems that the plugin launches with the Electron app and not when I launch Swift app from within Electron.

To get to this point, I worked through code signing issues and sandbox issues. I am not using a provisioning profile. I do have a developer certificate from Apple that I use for signing.

Any help would be greatly appreciated. If there was an article where they published a Finder extension with electron-builder, that would be great as well.

Below are some other files:

electron-builder entitlements file:

...
<dict>
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.automation.apple-events</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-only</key>
    <true/>
    <key>com.apple.security.app-sandbox</key>
    <false/>
</dict>
...

electron-build settings in package.json

"build": {
    "appId": "com.myapp",
    "productName": "My App",
    "copyright": "Copyright © 2020 ${author}",
    "files": [
      "./index.js",
      "./modules/**/*",
      "./iconSmallTemplate.ico"
    ],
    "extraResources": [
      {
        "from": "./resources/",
        "to": "./",
        "filter": [
          "**/*"
        ]
      }
    ],
    "mac": {
      "appId": "com.myapp.mac",
      "category": "public.app-category.productivity",
      "type": "development",
      "identity": "Apple Development: ME (#####)",
      "extraFiles": [
        {
          "from": "mySwiftApp.app",
          "to": "MacOS/mySwiftApp.app"
        },
        {
          "from": "myFinderExtension.appex",
          "to": "PlugIns/myFinderExtension.appex"
        }
      ]
    }
  }

Brian
  • 3,571
  • 7
  • 44
  • 70
  • 1
    There is definetely more information needed to understand the root of problem, but I could point you to several unusual things that may be the problems or may not. First of all, it is unusual to have in MacOS folder of bundle some other bundle. I've never seen such bundles in real life, and I believe Apple does not encourage this. Try to move it to Resources or Frameworks folder. Second, you shoud definetely not include your appext twice in your delivery, this is not right. Why are you having MyExtension.appex in both Plugin folders? – Arthur Bulakaiev Nov 01 '21 at 21:31
  • Thanks for the comment. I used the MacOS folder because of the "Nested Code" section in this document (https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG201). I saw that document mentioned by Quinn on the Apple Dev Forums. – Brian Nov 02 '21 at 03:18
  • I thought the plugin was unusual to have twice. This came about because the extension is in the Swift app, but it seemed that for it to be recognized properly, I needed to have electron-build place it in the PlugIns dir. Today, I removed it from the Swift app, and that seemed to work. My concern was I would invalidate the Swift app's signature, but it seems that electron-builder is signing the new app and it doesn't matter. I need to do more testing. Next, I'm going to try to have Electron do IPC to the extension directly. Need to figure out how to set app-groups in electron during dev. – Brian Nov 02 '21 at 03:25
  • App Group is related to .entitlements file. So in electron or any other tech, you just need to put the App Groups (com.apple.security.application-groups) Array into entitlements file and add there string item with your app group id – Arthur Bulakaiev Nov 02 '21 at 12:31
  • I know I can do that when I build the app with electron-builder, but I'm not sure how I would set that entitlement when I'm developing the app. I'd like test it without going through a build and would like the ability to step through the electron or Swift code. – Brian Nov 02 '21 at 12:38

0 Answers0