Search code examples
node.jsmacoselectronfs

Access macOS Photo Library using Electron


I am trying to write an Electron application that lets users select photos from their photo library on macOS. My assumption is that the only way to access the photos without exporting them is by going into ~/Pictures/Photos Library.photoslibrary. However, when passing the file path of a photo to an <img> tag, I get net::ERR_ACCESS_DENIED error.

Is there a way to grant Electron application access to the user's photo library?


Solution

  • I've been writing code recently that accesses the PhotosLibrary. I did this by writing a native module that calls the PhotoKit API. If you go that direction there's going to be a steep learning curve as you'll likely be using Objective-C++ with the features and quirks of both C++ and Objective-C while trying to write something in JavaScript.

    https://github.com/nodejs/node-addon-api https://developer.apple.com/documentation/photokit?language=objc

    With Apple's recent security features, you'll also need to somehow run your code inside of an app with the correct entitlements and values set in its Info.plist that will allow access to APIs.

    In build/entitlements.mac.plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
            <!-- https://github.com/electron/electron-notarize#prerequisites -->
            <key>com.apple.security.cs.allow-jit</key>
            <true/>
            <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
            <true/>
            <!-- https://github.com/electron-userland/electron-builder/issues/3940 -->
            <key>com.apple.security.cs.disable-library-validation</key>
            <true/>
    
            <!-- Allow app to access Photos Library using PhotoKit API -->
            <key>com.apple.security.personal-information.photos-library</key>
            <true/>
    
        </dict>
    </plist>
    

    The following will be needed in your App's Info.plist:

    <plist version="1.0">
        <dict>
    
            ...
    
            <key>NSPhotoLibraryUsageDescription</key>
            <string>This app needs access to the photos library</string>
        </dict>
    </plist>
    

    This can be done using electron-builder by adding the following value to the extendInfo extendInfo of your mac build settings in package.json.

    {
        ...
        "build": {
            ...
            "mac": {
                ...
                "extendInfo": {
                     ...
                     "NSPhotoLibraryUsageDescription": "This app needs access to the photos library"
                }
            }
        }
    }
    

    I hope this is gives you something to start with. Like I said above, this will come with a steep learning curve unless you're already familiar with JavaScript, native module development, Objective-C, C++ and Apple's APIs.