Search code examples
mysqlswiftmacoscocoaswift-nio

How to Connect to MySQL database using Swift-Nio


I used node js to connect mysql server and it is working good. I used the API developed in node js and used in the local macOS app. The problem is querying the data from mysql database on workbench is fast but in node js API it is very delay. So, I've to connect mysql db directly from my macOS app.

I installed mysql from here: https://www.mysql.com/downloads/

Also I am using mysql work bench to test the connection and It is connecting without any problem. So, In system preference I've an mysql extensions to start and stop mysql server. In the extension I can see the root folder locate in /usr/local/mysql

I created new project and added swift package of mysql-nio from here

In that repository their API document link is broken https://api.vapor.codes/mysql-nio/master/MySQLNIO/ But I found the correct link https://api.vapor.codes/mysql-nio/main/MySQLNIO/MySQLConnection/

By using that link, I tried to connect with below code,

//https://github.com/vapor/mysql-nio

import Cocoa
import MySQLNIO

class ViewController: NSViewController {

    
    private var group: EventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 4)
     
    private var eventLoop: EventLoop {

        return self.group.next()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
   
        do{
            
            let socketAddress = try SocketAddress(ipAddress: "127.0.0.1", port: 3306)
            
            let logger = Logger(label: "MyLogger")
            let connection = MySQLConnection.connect(to: socketAddress, username: "root", database: "MyDB", password: "3$@sdRt34@sdf$dja2", tlsConfiguration: nil, serverHostname: nil, logger: logger, on: eventLoop)                
            connection.whenComplete { result in
                
                switch result{
                    
                case .success(let connection):
                    
                    print("Success! Status closed: \(connection.isClosed)")
                    
                case .failure(let error):
                     
                    DispatchQueue.main.async {
                        
                        NSApp.presentError(error)
                    }
                }
            }
            
        }catch{
            
            NSApp.presentError(error)
        }
        
    }
}

Error:

The operation couldn’t be completed. (NIOCore.IOError error 1.)

I added App Transport Security Settings -> Allow Arbitrary Loads to YES in the xcode project info

I don't know How to resolve this issue. Can you please help me to resolve this issue? Thank you!


Solution

  • In the app sandbox, you'll need to enable "Outgoing connections (client)" and then it should work.

    outgoing connections

    Unfortunately, because of a Swift bug the error printout of Swift errors isn't actually useful if you do localizedDescription. To see the actual error, you'd need to put something like a print(error) in your error handler.

    See how in the screenshot below, the print(error) prints actually useful text like connect(descriptor:addr:size:): Operation not permitted (errno: 1) if I don't check the "Outgoing connections (client)"?

    XCode console