Day 7: Making a swift macOS password manager for people who hate the cloud
Sean Walker
Posted on January 8, 2019
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
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 = ""
guard let item = logins?[row] else {
return nil
}
text = item[login.email]!
if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier.NameCell, owner: self) as? NSTableCellView {
cell.textField?.stringValue = text
return cell
}
return nil
}
}
Oh the thing I was missing was that I was adding the Identifier in storyboard to the TableViewCell, when I really needed to fill in the Identifier in the TableViewColumn. SILLY ME.
āļø6.25 hours (I'll go ahead and include pewdiepie and netflix in there, just for kicks)
š°$0
š„ Day 8 tomorrow
Posted on January 8, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.