DEV Community

Cover image for Day 6: Making a swift macOS password manager for people who hate the cloud
Sean Walker
Sean Walker

Posted on • Originally published at

Day 6: Making a swift macOS password manager for people who hate the cloud

<- For Day 5 go here

I'm going to start laying out these posts a little better, more like a timeline, I think that could be cool and more instructive as to how much I actually spent working on this thing so I can calculate how little $/hr I make when I try to sell it for $29/lifetime and maybe put it on Setapp. I'm hoping it's at least minimum wage, but based on my past side projects I doubt it.

11:06 AM MT

Decide what I want to work on today. I'm kind of falling behind so I really need to figure out the fastest way to get data from the AddLoginViewController into SQLite and Keychain

11:47 AM MT

This is what a tiny bit of success looks like, it ain't pretty, but ITS WORKING. My problems were two fold, one the ContainerView button wasn't firing, turns out I needed to call addChild on the AddNewLoginViewController to get it working like so

    @IBAction func addNewLogin(_ sender: NSMenuItem) {
        let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: Bundle.main)
        let vc = storyboard.instantiateController(withIdentifier: "AddLoginViewController") as! NSViewController

        for sView in containerView.subviews {

        vc.view.frame = containerView.bounds

Then from there the button was firing so SQLite.swift could take over

    @IBAction func addButtonClicked(_ sender: NSButton) {
        let login = Login()
        let db =
        try! <- emailTextField.stringValue, login.username <- usernameTextField.stringValue, login.key <- UUID.init().uuidString))

        for row in try! db.prepare(login.table) {
            print("id: \(row[]), key: \(row[login.key]), email: \(row[]), name: \(row[login.username])")

Oh I also added a few structs there for opening the db connection and wrapping the struct table definition:

import SQLite

public struct Database {
    static func open() -> Connection {
        let path = NSSearchPathForDirectoriesInDomains(
            .applicationSupportDirectory, .userDomainMask, true
            ).first! + "/" + Bundle.main.bundleIdentifier!

        do {
            try FileManager.default.createDirectory(
                atPath: path, withIntermediateDirectories: true, attributes: nil
        } catch {
            print("Unexpected error: \(error).")

        var conn : Connection?
        do {
            conn = try Connection("\(path)/app.db")
        } catch {
            print("Unexpected error: \(error).")

        return conn!

public struct Login {
    let table = Table("login")
    let id = Expression<Int64>("id")
    let url = Expression<String?>("url")
    let username = Expression<String?>("username")
    let email = Expression<String?>("email")
    let key = Expression<String>("key")

So now it's just polish work

Day 7 tomorrow 😬

Top comments (1)

niorad profile image
Antonio Radovcic

Really curious how this will continue :-D