diff --git a/ios/engine/KMEI/KeymanEngine/Classes/KeyboardRepository/APIKeyboardRepository.swift b/ios/engine/KMEI/KeymanEngine/Classes/KeyboardRepository/APIKeyboardRepository.swift index dfa625bfa7..17a35ac93a 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/KeyboardRepository/APIKeyboardRepository.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/KeyboardRepository/APIKeyboardRepository.swift @@ -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 } diff --git a/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/KeyboardPickerViewController.swift b/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/KeyboardPickerViewController.swift index e1b51334ba..63d7a99a4c 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/KeyboardPickerViewController.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/KeyboardPickerViewController.swift @@ -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) } diff --git a/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/LanguageViewController.swift b/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/LanguageViewController.swift index b62366ad1e..42896bf257 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/LanguageViewController.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/LanguagePicker/LanguageViewController.swift @@ -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 + } + } +} diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift index 5e942498df..ecba0e6aa1 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift @@ -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: diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Notification/Notifications.swift b/ios/engine/KMEI/KeymanEngine/Classes/Notification/Notifications.swift index aaf1e5d913..ba1f2dc5d4 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Notification/Notifications.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Notification/Notifications.swift @@ -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("KeymanLanguagesUpdated") - public static let languagesDownloadFailed = - NotificationName("KeymanLanguagesDownloadFailed") - public static let keyboardDownloadStarted = NotificationName("KeymanKeyboardDownloadStarted") public static let keyboardDownloadCompleted = diff --git a/ios/keyman/Keyman/Keyman/MainViewController.swift b/ios/keyman/Keyman/Keyman/MainViewController.swift index 758f70dc0e..5cb360ca5e 100644 --- a/ios/keyman/Keyman/Keyman/MainViewController.swift +++ b/ios/keyman/Keyman/Keyman/MainViewController.swift @@ -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)