Remove language update notifications in favor of repository delegate

This commit is contained in:
Gabriel Wong 2017-12-04 13:55:18 +07:00
parent 389ca52ed7
commit 06571cbdad
6 changed files with 57 additions and 123 deletions

View file

@ -35,10 +35,12 @@ public class APIKeyboardRepository: KeyboardRepository {
private func apiCompletionHandler(_ data: Data?, _ response: URLResponse?, _ error: Error?) {
if let error = error {
Manager.shared.kmLog("Network error fetching languages: \(error)", checkDebugPrinting: false)
delegate?.keyboardRepository(self, didFailFetch: APIKeyboardFetchError.networkError(error))
return
}
guard let data = data else {
Manager.shared.kmLog("Language API did not return data", checkDebugPrinting: false)
delegate?.keyboardRepository(self, didFailFetch: APIKeyboardFetchError.noData)
return
}

View file

@ -400,7 +400,7 @@ class KeyboardPickerViewController: UITableViewController, UIAlertViewDelegate {
func showAddKeyboard() {
let button: UIButton? = (navigationController?.toolbar?.viewWithTag(toolbarButtonTag) as? UIButton)
button?.isEnabled = false
let vc = LanguageViewController()
let vc = LanguageViewController(Manager.shared.apiKeyboardRepository)
navigationController?.pushViewController(vc, animated: true)
setIsDoneButtonEnabled(true)
}

View file

@ -21,18 +21,27 @@ class LanguageViewController: UITableViewController, UIAlertViewDelegate {
private var selectedSection = 0
private var isUpdate = false
private var languages: [Language] = []
private let keyboardRepository: KeyboardRepository
private var languagesUpdatedObserver: NotificationObserver?
private var languagesDownloadFailedObserver: NotificationObserver?
private var keyboardDownloadStartedObserver: NotificationObserver?
private var keyboardDownloadFailedObserver: NotificationObserver?
init(_ keyboardRepository: KeyboardRepository) {
self.keyboardRepository = keyboardRepository
super.init(nibName: nil, bundle: nil)
keyboardRepository.delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func loadView() {
super.loadView()
if let languageDict = Manager.shared.apiKeyboardRepository.languages {
if let languageDict = keyboardRepository.languages {
languages = languageList(languageDict)
} else {
Manager.shared.fetchKeyboardsList()
keyboardRepository.fetch()
}
loadUserKeyboards()
@ -42,14 +51,6 @@ class LanguageViewController: UITableViewController, UIAlertViewDelegate {
super.viewDidLoad()
title = "Add New Keyboard"
selectedSection = NSNotFound
languagesUpdatedObserver = NotificationCenter.default.addObserver(
forName: Notifications.languagesUpdated,
observer: self,
function: LanguageViewController.languagesUpdated)
languagesDownloadFailedObserver = NotificationCenter.default.addObserver(
forName: Notifications.languagesDownloadFailed,
observer: self,
function: LanguageViewController.languagesDownloadFailed)
keyboardDownloadStartedObserver = NotificationCenter.default.addObserver(
forName: Notifications.keyboardDownloadStarted,
observer: self,
@ -208,28 +209,6 @@ class LanguageViewController: UITableViewController, UIAlertViewDelegate {
}
}
private func languageList(_ languageDict: [String: Language]) -> [Language] {
return languageDict.values.sorted { a, b -> Bool in
a.name.localizedCaseInsensitiveCompare(b.name) == .orderedAscending
}
}
private func languagesUpdated() {
dismissActivityView()
if let languageDict = Manager.shared.apiKeyboardRepository.languages {
languages = languageList(languageDict)
}
tableView.reloadData()
if numberOfSections(in: tableView) == 0 {
showConnectionErrorAlert()
}
}
private func languagesDownloadFailed() {
dismissActivityView()
showConnectionErrorAlert()
}
private func keyboardDownloadStarted() {
view.isUserInteractionEnabled = false
navigationItem.setHidesBackButton(true, animated: true)
@ -323,3 +302,28 @@ class LanguageViewController: UITableViewController, UIAlertViewDelegate {
alert.show()
}
}
// MARK: - KeyboardRepositoryDelegate
extension LanguageViewController: KeyboardRepositoryDelegate {
func keyboardRepositoryDidFetch(_ repository: KeyboardRepository) {
dismissActivityView()
if let languageDict = repository.languages {
languages = languageList(languageDict)
}
tableView.reloadData()
if numberOfSections(in: tableView) == 0 {
showConnectionErrorAlert()
}
}
func keyboardRepository(_ repository: KeyboardRepository, didFailFetch error: Error) {
dismissActivityView()
showConnectionErrorAlert()
}
private func languageList(_ languageDict: [String: Language]) -> [Language] {
return languageDict.values.sorted { a, b -> Bool in
a.name.localizedCaseInsensitiveCompare(b.name) == .orderedAscending
}
}
}

View file

@ -47,8 +47,7 @@ private let phoneLandscapeSystemKeyboardHeight: CGFloat = 162.0
private let padPortraitSystemKeyboardHeight: CGFloat = 264.0
private let padLandscapeSystemKeyboardHeight: CGFloat = 352.0
public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegate, KeymanWebDelegate,
KeyboardRepositoryDelegate {
public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegate, KeymanWebDelegate {
/// Application group identifier for shared container. Set this before accessing the shared manager.
public static var applicationGroupIdentifier: String?
@ -147,7 +146,6 @@ KeyboardRepositoryDelegate {
private override init() {
apiKeyboardRepository = APIKeyboardRepository()
super.init()
apiKeyboardRepository.delegate = self
URLProtocol.registerClass(KeymanURLProtocol.self)
@ -450,14 +448,6 @@ KeyboardRepositoryDelegate {
apiKeyboardRepository.fetch()
}
public func keyboardRepositoryDidFetch(_ repository: KeyboardRepository) {
NotificationCenter.default.post(name: Notifications.languagesUpdated, object: self, value: ())
}
public func keyboardRepository(_ repository: KeyboardRepository, didFailFetch error: Error) {
NotificationCenter.default.post(name: Notifications.languagesDownloadFailed, object: self, value: error)
}
/// Asynchronously fetches the .js file for the keyboard with given IDs.
/// See `Notifications` for notification on success/failiure.
/// - Parameters:

View file

@ -8,9 +8,6 @@
import Foundation
public typealias LanguagesUpdatedNotification = Void
public typealias LanguagesDownloadFailedNotification = Error
public typealias KeyboardDownloadStartedNotification = [InstallableKeyboard]
public typealias KeyboardDownloadCompletedNotification = [InstallableKeyboard]
public struct KeyboardDownloadFailedNotification {
@ -25,11 +22,6 @@ public typealias KeyboardRemovedNotification = InstallableKeyboard
public typealias KeyboardPickerDismissedNotification = Void
public struct Notifications {
public static let languagesUpdated =
NotificationName<LanguagesUpdatedNotification>("KeymanLanguagesUpdated")
public static let languagesDownloadFailed =
NotificationName<LanguagesDownloadFailedNotification>("KeymanLanguagesDownloadFailed")
public static let keyboardDownloadStarted =
NotificationName<KeyboardDownloadStartedNotification>("KeymanKeyboardDownloadStarted")
public static let keyboardDownloadCompleted =

View file

@ -52,9 +52,8 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
private var portRightMargin: CGFloat = 0.0
private var lscpeLeftMargin: CGFloat = 0.0
private var lscpeRightMargin: CGFloat = 0.0
private var loadTimer: Timer?
private var updateStatus: Int = 0 // TODO: Make into enum
private var didDownload: Bool = false
private var didDownload = false
private var didKeyboardLoad = false
private var keyboardLoadedObserver: NotificationObserver?
private var languagesUpdatedObserver: NotificationObserver?
@ -100,14 +99,6 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
forName: Notifications.keyboardChanged,
observer: self,
function: MainViewController.keyboardChanged)
languagesUpdatedObserver = NotificationCenter.default.addObserver(
forName: Notifications.languagesUpdated,
observer: self,
function: MainViewController.languagesUpdated)
languagesDownloadFailedObserver = NotificationCenter.default.addObserver(
forName: Notifications.languagesDownloadFailed,
observer: self,
function: MainViewController.languagesDownloadFailed)
keyboardPickerDismissedObserver = NotificationCenter.default.addObserver(
forName: Notifications.keyboardPickerDismissed,
observer: self,
@ -150,8 +141,6 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
screenHeight = screenRect.size.height
// Setup Keyman Manager & fetch keyboards list
updateStatus = 0
Manager.shared.canRemoveDefaultKeyboard = true
Manager.shared.fetchKeyboardsList()
@ -228,7 +217,6 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
textView.isUserInteractionEnabled = true
textView.font = textView.font?.withSize(textSize)
view?.addSubview(textView!)
textView.isEditable = false
// Setup Info View
infoView = InfoViewController()
@ -256,6 +244,7 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
textSizeController.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged)
setNavBarButtons()
loadSavedUserText()
}
override func viewWillDisappear(_ animated: Bool) {
@ -367,7 +356,7 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
textView.becomeFirstResponder()
}
if !textView.isEditable {
if !didKeyboardLoad {
showActivityIndicator()
} else if shouldShowGetStarted {
perform(#selector(self.showGetStartedView), with: nil, afterDelay: 1.0)
@ -461,9 +450,17 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
}
// MARK: - Keyman Notifications
private func keyboardLoaded() {
startTimer()
didKeyboardLoad = true
dismissActivityIndicator()
textView.becomeFirstResponder()
if let launchUrl = launchUrl {
performAction(from: launchUrl)
} else {
if shouldShowGetStarted {
perform(#selector(self.showGetStartedView), with: nil, afterDelay: 1.0)
}
}
}
private func keyboardChanged(_ kb: InstallableKeyboard) {
@ -514,14 +511,6 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
}
}
private func languagesUpdated() {
updateStatus = 1
}
private func languagesDownloadFailed() {
updateStatus = -1
}
private func keyboardPickerDismissed() {
textView.becomeFirstResponder()
if UIDevice.current.userInterfaceIdiom == .pad && shouldShowGetStarted {
@ -547,7 +536,7 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
@objc func launched(fromUrl notification: Notification) {
if let url = notification.userInfo?[urlKey] as? URL, url.query != nil {
launchUrl = url
if updateStatus > 0 {
if didKeyboardLoad {
performAction(from: url)
}
} else {
@ -792,49 +781,6 @@ class MainViewController: UIViewController, TextViewDelegate, UIActionSheetDeleg
return view?.frame ?? CGRect.zero
}
private func startTimer() {
if loadTimer == nil {
loadTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self,
selector: #selector(self.timerAction), userInfo: nil, repeats: true)
}
}
private func stopTimer() {
if let timer = loadTimer {
timer.invalidate()
loadTimer = nil
}
}
@objc func timerAction() {
if updateStatus == 1 {
stopTimer()
dismissActivityIndicator()
textView.isEditable = true
textView.becomeFirstResponder()
if let launchUrl = launchUrl {
performAction(from: launchUrl)
} else {
loadSavedUserText()
if shouldShowGetStarted {
perform(#selector(self.showGetStartedView), with: nil, afterDelay: 1.0)
}
}
} else if updateStatus == -1 {
stopTimer()
dismissActivityIndicator()
loadSavedUserText()
textView.isEditable = true
textView.becomeFirstResponder()
if shouldShowGetStarted {
perform(#selector(self.showGetStartedView), with: nil, afterDelay: 1.0)
}
}
}
private func resetTextViewCursor() {
textView.selectedRange = NSRange(location: 0, length: 0)