Xcode wrapper project that packages the Zotero Connector web extension
(~/zotero-connectors/build/safari) as a Safari web extension appex for
bundling in Zotero.app.
./build.sh builds the Release appex (ad-hoc signed) and copies it to
dist/ZoteroSafariExtension.appex. That appex is a stub:
- The native binary is the boilerplate
SafariWebExtensionHandler, which is never called — the connector communicates with Zotero over HTTP, not native messaging. - It contains no web extension resources. The Zotero client build
(
app/build.sh) createsContents/Resourcesfrom a connector build (via$SAFARI_EXT_RESOURCES), rewrites the bundle id prefix to match the parent app, and re-signs everything with the Developer ID. The ad-hoc signature here exists only so the client build can extract the entitlements from the appex.
So the stub only needs to be rebuilt and re-uploaded to the build server when the Swift handler, entitlements, or Info.plist change — connector releases don't require touching this project.
- App:
org.zotero.SafariWebExtensionApp(dev-only; the app target is not shipped) - Extension:
org.zotero.SafariWebExtensionApp.SafariExtension
The Zotero client build rewrites the extension id to
<parent app id>.SafariExtension — org.zotero.zotero.SafariExtension for
release, which matches the old Safari App Extension's id, so the switch to
the web extension is an in-place upgrade for existing users.
ExtensionApp Extension/ExtensionApp Extension.entitlements declares
exactly what ships: com.apple.security.app-sandbox (required for appexes
to load) and com.apple.security.files.user-selected.read-only. The build
passes CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO so ad-hoc builds don't pick
up com.apple.security.get-task-allow, which notarization rejects.
The project was generated with:
xcrun safari-web-extension-converter ~/zotero-connectors/build/safari \
--project-location ~/safari-web-extension \
--app-name ExtensionApp \
--bundle-identifier org.zotero.SafariWebExtensionApp \
--macos-only --swift --no-open --no-promptAfter regenerating, reapply these fixups to
ExtensionApp/ExtensionApp.xcodeproj/project.pbxproj:
- Extension
PRODUCT_BUNDLE_IDENTIFIER:org.zotero.SafariWebExtensionApp.Extension→org.zotero.SafariWebExtensionApp.SafariExtension - App
PRODUCT_BUNDLE_IDENTIFIER: →org.zotero.SafariWebExtensionApp MACOSX_DEPLOYMENT_TARGET→11.0everywhereCODE_SIGN_ENTITLEMENTS = "ExtensionApp Extension/ExtensionApp Extension.entitlements";on both extension target configurations- On both extension target configurations,
PRODUCT_NAME = ZoteroSafariExtension;andINFOPLIST_KEY_CFBundleDisplayName = "Zotero Connector";— the executable name and display name match the old Safari App Extension's - Remove the
build/safarifile references the converter adds (everyPBXFileReferencewhose path points intozotero-connectors/build/safari, thePBXBuildFileentries wrapping them, and the lines referencing either set of ids) — the client build supplies the resources, so the stub shouldn't bake in a snapshot of them