diff --git a/passAutoFillExtension/Base.lproj/MainInterface.storyboard b/passAutoFillExtension/Base.lproj/MainInterface.storyboard
index f5650b6..9ea07a3 100644
--- a/passAutoFillExtension/Base.lproj/MainInterface.storyboard
+++ b/passAutoFillExtension/Base.lproj/MainInterface.storyboard
@@ -17,13 +17,13 @@
-
+
-
+
-
+
diff --git a/passAutoFillExtension/Controllers/CredentialProviderViewController.swift b/passAutoFillExtension/Controllers/CredentialProviderViewController.swift
index 25dad0d..e8e85a3 100644
--- a/passAutoFillExtension/Controllers/CredentialProviderViewController.swift
+++ b/passAutoFillExtension/Controllers/CredentialProviderViewController.swift
@@ -35,6 +35,8 @@ class CredentialProviderViewController: ASCredentialProviderViewController {
override func prepareCredentialList(for serviceIdentifiers: [ASCredentialServiceIdentifier]) {
let url = serviceIdentifiers.first.flatMap { URL(string: $0.identifier) }
passwordsViewController.navigationItem.prompt = url?.host
+ let keywords = url?.host?.sanitizedDomain?.components(separatedBy: ".") ?? []
+ passwordsViewController.showPasswordsWithSuggstion(keywords)
}
}
@@ -50,3 +52,14 @@ extension CredentialProviderViewController: PasswordSelectionDelegate {
}
}
}
+
+private extension String {
+ var sanitizedDomain: String? {
+ replacingOccurrences(of: ".com", with: "")
+ .replacingOccurrences(of: ".org", with: "")
+ .replacingOccurrences(of: ".edu", with: "")
+ .replacingOccurrences(of: ".net", with: "")
+ .replacingOccurrences(of: ".gov", with: "")
+ .replacingOccurrences(of: "www.", with: "")
+ }
+}
diff --git a/passAutoFillExtension/Controllers/PasswordsViewController.swift b/passAutoFillExtension/Controllers/PasswordsViewController.swift
index 8d58212..6e17b42 100644
--- a/passAutoFillExtension/Controllers/PasswordsViewController.swift
+++ b/passAutoFillExtension/Controllers/PasswordsViewController.swift
@@ -27,18 +27,27 @@ class PasswordsViewController: UIViewController {
return uiSearchController
}()
+ lazy var searchBar: UISearchBar = {
+ self.searchController.searchBar
+ }()
+
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
- searchController.searchBar.delegate = self
+ searchBar.delegate = self
tableView.delegate = self
tableView.dataSource = dataSource
}
+ func showPasswordsWithSuggstion(_ keywords: [String]) {
+ dataSource.showTableEntriesWithSuggestion(matching: keywords)
+ tableView.reloadData()
+ }
+
@IBAction
private func cancel(_: AnyObject?) {
self.extensionContext?.cancelRequest(withError: NSError(domain: ASExtensionErrorDomain, code: ASExtensionError.userCanceled.rawValue))
diff --git a/passAutoFillExtension/Services/PasswordsTableDataSource.swift b/passAutoFillExtension/Services/PasswordsTableDataSource.swift
index d680967..95851e2 100644
--- a/passAutoFillExtension/Services/PasswordsTableDataSource.swift
+++ b/passAutoFillExtension/Services/PasswordsTableDataSource.swift
@@ -12,20 +12,69 @@ import passKit
class PasswordsTableDataSource: NSObject, UITableViewDataSource {
var passwordTableEntries: [PasswordTableEntry]
var filteredPasswordsTableEntries: [PasswordTableEntry]
+ var suggestedPasswordsTableEntries: [PasswordTableEntry]
+ var otherPasswordsTableEntries: [PasswordTableEntry]
+
+ var showSuggestion: Bool = false
init(entries: [PasswordTableEntry] = []) {
passwordTableEntries = entries
filteredPasswordsTableEntries = passwordTableEntries
+ suggestedPasswordsTableEntries = []
+ otherPasswordsTableEntries = []
+ }
+
+ func numberOfSections(in tableView: UITableView) -> Int {
+ if !showSuggestion {
+ return 1
+ } else {
+ return 2
+ }
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- filteredPasswordsTableEntries.count
+ if !showSuggestion {
+ return filteredPasswordsTableEntries.count
+ }
+
+ if section == 0 {
+ return suggestedPasswordsTableEntries.count
+ } else {
+ return otherPasswordsTableEntries.count
+ }
+ }
+
+ func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+ if suggestedPasswordsTableEntries.isEmpty {
+ return nil
+ }
+
+ if !showSuggestion {
+ return "All Passwords"
+ }
+
+ if section == 0 {
+ return "Suggested Passwords"
+ } else {
+ return "Other Passwords"
+ }
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordTableViewCell", for: indexPath) as! PasswordTableViewCell
- let entry = filteredPasswordsTableEntries[indexPath.row]
+ var entry: PasswordTableEntry!
+ if !showSuggestion {
+ entry = filteredPasswordsTableEntries[indexPath.row]
+ cell.configure(with: entry)
+ return cell
+ }
+
+ if indexPath.section == 0 {
+ entry = suggestedPasswordsTableEntries[indexPath.row]
+ } else {
+ entry = otherPasswordsTableEntries[indexPath.row]
+ }
cell.configure(with: entry)
return cell
@@ -34,9 +83,26 @@ class PasswordsTableDataSource: NSObject, UITableViewDataSource {
func showTableEntries(matching text: String) {
guard !text.isEmpty else {
filteredPasswordsTableEntries = passwordTableEntries
+ showSuggestion = true
return
}
filteredPasswordsTableEntries = passwordTableEntries.filter { $0.match(text) }
+ showSuggestion = false
+ }
+
+ func showTableEntriesWithSuggestion(matching keywords: [String]) {
+ for entry in passwordTableEntries {
+ var match = false
+ for keyword in keywords {
+ match = match || entry.match(keyword)
+ }
+ if match {
+ suggestedPasswordsTableEntries.append(entry)
+ } else {
+ otherPasswordsTableEntries.append(entry)
+ }
+ }
+ showSuggestion = !suggestedPasswordsTableEntries.isEmpty
}
}