@sean
🔥 40 day streak
562 words

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

<- For Day 6 go here

This marks the first week I've been working on this thing 🎉 If you're just tuning in, I want to give you the run down on some things I hope to accomplish in 3 weeks time:

  • Charge $29/lifetime
  • Put this thing in the macOS app store
  • Open source the code (but try to nudge people towards the paid version)
  • Figure out how many actual hours I worked on it and give a cool run down post on the whole month

Speaking of rundown posts, I just want to take a second to think back on the last 6 days and sort of write down where this app came from (nothing) and where it is now (something):

Day 1: Made a new xcode project and put a screen with a large-ish NSSecureTextField in it (1 hour) Day 2: Try to use CoreData to store everything, doesn't work out, bring in SQLite.swift and KeychainSwift to handle the heavy lifting, also switch initial view controllers based on the master password being set or not, save the set master password to keychain (2 hours) Day 3: Get the master password unlock screen working (0.5 hours) Day 4: Show the new password screen in a container view next to the password tableview (1 hour) Day 5: Go snowboarding and hang with friends all day. Slap labels and textfields in the new password screen (0.25 hours) Day 6: Actually insert new logins into sqlite and new passwords into keychain (0.67 hours) Day 7: This post!

Total time so far: 4.75 hours

8:20 PM Mountain Time

What does this thing need still aside from design help? It needs to list out the passwords, that's what I'm doing tonight. Let's get to work.

8:30 PM Mountain Time

Watch pewdiepie for a while

8:34 PM Mountain Time

Actually get to work.

9:47 PM Mountain Time

After some light netflix watching, finally figured it out. Passwords are showing in the list view. I almost couldn't believe it when it was working, had to take a screenshot

9:48 PM Mountain Time

Took a screenshot

Here's the relevant code

class PasswordListViewController: NSViewController {
    @IBOutlet weak var containerView: NSView!
    @IBOutlet weak var tableView: NSTableView!
    var logins : [Row]?
    let login = Login()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        let db = Database.open()

        logins = Array(try! db.prepare(login.table))

        tableView.reloadData()
    }
}

That's pretty much all there is to getting a tableview populated in macos with swift

extension PasswordListViewController: NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        return logins?.count ?? 0
    }
}

extension NSUserInterfaceItemIdentifier {
    static let NameCell = NSUserInterfaceItemIdentifier("NameCellID")
}

extension PasswordListViewController: NSTableViewDelegate {

    fileprivate enum CellIdentifiers {
        static let NameCell = "NameCellID"
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        var text: String = ""

        // 1
        guard let item = logins?[row] else {
            return nil
        }

        // 2
        text = item[login.email]!

        // 3
        if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier.NameCell, owner: self) as? NSTableCellView {
            cell.textField?.stringValue = text
            //cell.imageView?.image = image ?? nil
            return cell
        }
        return nil
    }

}

⌚️6.25 hours (I'll go ahead and include pewdiepie and netflix in there, just for kicks) 💰$0

🔥 Day 8 tomorrow