swiftmacosgoogle-chrome-extensionchrome-native-messaging

How can I communicate between a sandboxed macOS application and a script (or program)


I need a way to communicate between a sandboxed application and google chrome's native messaging host. I have tried a Bonjour server and XPC service and had problems with both. (they work as expected if I used them with another sandboxed app, I can communicate between two sandboxed applications)


Solution

  • You can always make a socket-server using python, and send an HTTP request to it from the swift app, and have it send a message to chrome, when receiving the socket.

    The code for a basic socket server in python is:

    import socket
    import sys
    
    def get_constants(prefix):
        """Create a dictionary mapping socket module constants to their names."""
        return dict( (getattr(socket, n), n)
                     for n in dir(socket)
                     if n.startswith(prefix)
                     )
    
    families = get_constants('AF_')
    types = get_constants('SOCK_')
    protocols = get_constants('IPPROTO_')
    
    # Create a TCP/IP socket
    sock = socket.create_connection(('localhost', 10000))
    
    print >>sys.stderr, 'Family  :', families[sock.family]
    print >>sys.stderr, 'Type    :', types[sock.type]
    print >>sys.stderr, 'Protocol:', protocols[sock.proto]
    print >>sys.stderr
    
    try:
        
        # Send data
        message = 'This is the message.  It will be repeated.'
        print >>sys.stderr, 'sending "%s"' % message
        sock.sendall(message)
    
        amount_received = 0
        amount_expected = len(message)
        
        while amount_received < amount_expected:
            data = sock.recv(16)
            amount_received += len(data)
            print >>sys.stderr, 'received "%s"' % data
    
    finally:
        print >>sys.stderr, 'closing socket'
        sock.close()
    

    and the server:

    import socket
    import sys
    
    # Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # Bind the socket to the address given on the command line
    server_name = sys.argv[1]
    server_address = (server_name, 10000)
    print >>sys.stderr, 'starting up on %s port %s' % server_address
    sock.bind(server_address)
    sock.listen(1)
    
    while True:
        print >>sys.stderr, 'waiting for a connection'
        connection, client_address = sock.accept()
        try:
            print >>sys.stderr, 'client connected:', client_address
            while True:
                data = connection.recv(16)
                print >>sys.stderr, 'received "%s"' % data
                if data:
                    connection.sendall(data)
                else:
                    break
        finally:
            connection.close()