From 463810d2ef07c412c9141c0f91f340cc77ce2637 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Tue, 31 Jan 2017 17:30:07 -0500 Subject: [PATCH] Refactor --- .../Library/LibraryBooksController.swift | 13 +--- .../Library/LibraryLanguageController.swift | 10 --- .../Library/LibraryTabController.swift | 3 +- .../Setting/SettingController.swift | 42 ------------- Kiwix-iOS/Notification.swift | 38 ++++++++++++ Kiwix-iOS/Notifications.swift | 9 --- Kiwix.xcodeproj/project.pbxproj | 8 +-- Kiwix/Network/Network.swift | 22 ++----- Kiwix/Operations/RefreshLibrary.swift | 3 +- Kiwix/Operations/UIProcedure.swift | 36 +++++++++++ Kiwix/Tools/StringTools.swift | 62 +++++++++++++++++++ 11 files changed, 151 insertions(+), 95 deletions(-) create mode 100644 Kiwix-iOS/Notification.swift delete mode 100644 Kiwix-iOS/Notifications.swift diff --git a/Kiwix-iOS/Controller/Library/LibraryBooksController.swift b/Kiwix-iOS/Controller/Library/LibraryBooksController.swift index 74e81f5b..93adef11 100644 --- a/Kiwix-iOS/Controller/Library/LibraryBooksController.swift +++ b/Kiwix-iOS/Controller/Library/LibraryBooksController.swift @@ -129,7 +129,8 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView self.collectionView.reloadEmptyDataSet() } - if let _ = errors.first { + if let error = errors.first { + print("dd:" + error.localizedDescription) // handle error [network, xmlparse] } else { if operation.firstTime { @@ -235,13 +236,3 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView } } - -extension Localized { - class Library { - static let cloudTitle = NSLocalizedString("Cloud", comment: "Library, Cloud") - static let localTitle = NSLocalizedString("Local", comment: "Library, Local") - - static let download = NSLocalizedString("Download", comment: "Library, more action sheet") - static let copyURL = NSLocalizedString("Copy URL", comment: "Library, more action sheet") - } -} diff --git a/Kiwix-iOS/Controller/Library/LibraryLanguageController.swift b/Kiwix-iOS/Controller/Library/LibraryLanguageController.swift index 32f9d00f..7b41f47e 100644 --- a/Kiwix-iOS/Controller/Library/LibraryLanguageController.swift +++ b/Kiwix-iOS/Controller/Library/LibraryLanguageController.swift @@ -156,13 +156,3 @@ class LibraryLanguageController: UITableViewController, NSFetchedResultsControll } } } - -extension Localized.Library { - class LanguageFilter { - static let title = NSLocalizedString("Languages", comment: "Library, Language Filter") - static let all = NSLocalizedString("ALL", comment: "Library, Language Filter") - static let showing = NSLocalizedString("SHOWING", comment: "Library, Language Filter") - static let hiding = NSLocalizedString("HIDING", comment: "Library, Language Filter") - static let original = NSLocalizedString("Original", comment: "Library, Language Filter") - } -} diff --git a/Kiwix-iOS/Controller/Library/LibraryTabController.swift b/Kiwix-iOS/Controller/Library/LibraryTabController.swift index dc2e3466..5d9c10a6 100644 --- a/Kiwix-iOS/Controller/Library/LibraryTabController.swift +++ b/Kiwix-iOS/Controller/Library/LibraryTabController.swift @@ -7,7 +7,6 @@ // import UIKit -import UserNotifications class LibraryTabController: UITabBarController { let cloud = UIStoryboard(name: "Library", bundle: nil).instantiateViewController(withIdentifier: "LibraryBookNavController") as! UINavigationController @@ -24,6 +23,6 @@ class LibraryTabController: UITabBarController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { _ in } + AppNotification.shared.register() } } diff --git a/Kiwix-iOS/Controller/Setting/SettingController.swift b/Kiwix-iOS/Controller/Setting/SettingController.swift index ebafbec2..df6c46cb 100644 --- a/Kiwix-iOS/Controller/Setting/SettingController.swift +++ b/Kiwix-iOS/Controller/Setting/SettingController.swift @@ -112,45 +112,3 @@ class SettingController: UITableViewController { } -extension Localized { - class Setting { - static let title = NSLocalizedString("Setting", comment: "Setting table title") - - static let fontSize = NSLocalizedString("Font Size", comment: "Setting table rows") - static let notifications = NSLocalizedString("Notifications", comment: "Setting table rows") - static let feedback = NSLocalizedString("Email us your suggestions", comment: "Setting table rows") - static let rateApp = NSLocalizedString("Give Kiwix a Rate", comment: "Setting table rows") - static let about = NSLocalizedString("About", comment: "Setting table rows") - static let version = NSLocalizedString("Kiwix for iOS v%@", comment: "Setting table footer") - - class Notifications { - static let libraryRefresh = NSLocalizedString("Library Refresh", comment: "Notification Setting") - static let bookUpdateAvailable = NSLocalizedString("Book Update Available", comment: "Notification Setting") - static let bookDownloadFinish = NSLocalizedString("Book Download Finish", comment: "Notification Setting") - } - - class Feedback { - static let subject = NSLocalizedString(String(format: "Feedback: Kiwix for iOS %@", Bundle.appShortVersion), - comment: "Feedback email composer subject, %@ will be replaced by kiwix version string") - class Success { - static let title = NSLocalizedString("Email Sent", comment: "Feedback success title") - static let message = NSLocalizedString("Your Email was sent successfully.", comment: "Feedback success message") - } - class NotConfiguredError { - static let title = NSLocalizedString("Cannot send Email", comment: "Feedback error title") - static let message = NSLocalizedString("The device is not configured to send email. You can send an email to chris@kiwix.org using other devices.", comment: "Feedback error message") - } - class ComposerError { - static let title = NSLocalizedString("Email not sent", comment: "Feedback error title") - } - } - - class RateApp { - static let message = NSLocalizedString("Would you like to rate Kiwix in App Store?", comment: "Rate app alert message") - static let goToAppStore = NSLocalizedString("Go to App Store", comment: "Rate app alert action") - static let remindMeLater = NSLocalizedString("Remind Me Later", comment: "Rate app alert action") - } - } -} - - diff --git a/Kiwix-iOS/Notification.swift b/Kiwix-iOS/Notification.swift new file mode 100644 index 00000000..080e62d0 --- /dev/null +++ b/Kiwix-iOS/Notification.swift @@ -0,0 +1,38 @@ +// +// Notifications.swift +// Kiwix +// +// Created by Chris Li on 9/19/16. +// Copyright © 2016 Chris Li. All rights reserved. +// + +import UserNotifications + +class AppNotification: NSObject, UNUserNotificationCenterDelegate { + static let shared = AppNotification() + private override init() {} + + func register() { + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { _ in } + } + + func downloadFinished(bookID: String, bookTitle: String, fileSizeDescription: String) { + UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) in + guard settings.alertSetting == .enabled else {return} + let content = UNMutableNotificationContent() + content.categoryIdentifier = "org.kiwix.download-finished" + content.title = bookTitle + " is downloaded!" + content.body = fileSizeDescription + " has been transferred." + let request = UNNotificationRequest(identifier: "org.kiwix.download-finished." + bookID, content: content, trigger: nil) + UNUserNotificationCenter.current().add(request, withCompletionHandler: nil) + }) + } + + // MARK: - UNUserNotificationCenterDelegate + + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + completionHandler([.alert, .sound]) + } + + +} diff --git a/Kiwix-iOS/Notifications.swift b/Kiwix-iOS/Notifications.swift deleted file mode 100644 index 0ea6816b..00000000 --- a/Kiwix-iOS/Notifications.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// Notifications.swift -// Kiwix -// -// Created by Chris Li on 9/19/16. -// Copyright © 2016 Chris Li. All rights reserved. -// - -import UIKit diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj index 8af1d075..3621c655 100644 --- a/Kiwix.xcodeproj/project.pbxproj +++ b/Kiwix.xcodeproj/project.pbxproj @@ -24,7 +24,7 @@ 971A107F1D022F74007FC62C /* ImportBookLearnMore.html in Resources */ = {isa = PBXBuildFile; fileRef = 971A107B1D022F74007FC62C /* ImportBookLearnMore.html */; }; 971A10801D022F74007FC62C /* Pic_I.png in Resources */ = {isa = PBXBuildFile; fileRef = 971A107C1D022F74007FC62C /* Pic_I.png */; }; 971A10811D022F74007FC62C /* Pic_P.png in Resources */ = {isa = PBXBuildFile; fileRef = 971A107D1D022F74007FC62C /* Pic_P.png */; }; - 9726591D1D90A64600D1DFFB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9726591C1D90A64500D1DFFB /* Notifications.swift */; }; + 9726591D1D90A64600D1DFFB /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9726591C1D90A64500D1DFFB /* Notification.swift */; }; 972F81571DDBFC79008D7289 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 972F81561DDBFC79008D7289 /* Search.swift */; }; 972F81591DDC1B71008D7289 /* Controllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 972F81581DDC1B71008D7289 /* Controllers.swift */; }; 9732075C1DD136BB00EDD3DC /* CoreDataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9732075B1DD136BB00EDD3DC /* CoreDataExtension.swift */; }; @@ -184,7 +184,7 @@ 971C4F0B1D3FFFA60027B7D2 /* Kiwix.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Kiwix.entitlements; path = "Kiwix-iOS/Kiwix.entitlements"; sourceTree = SOURCE_ROOT; }; 97219DBC1D383A00009FDFF1 /* BookmarkHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BookmarkHUD.swift; path = "Kiwix-iOS/Controller/Bookmark/BookmarkHUD.swift"; sourceTree = SOURCE_ROOT; }; 9726591A1D8DB91200D1DFFB /* DownloadProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadProgress.swift; sourceTree = ""; }; - 9726591C1D90A64500D1DFFB /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; + 9726591C1D90A64500D1DFFB /* Notification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; }; 972F81561DDBFC79008D7289 /* Search.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Search.swift; sourceTree = ""; }; 972F81581DDC1B71008D7289 /* Controllers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Controllers.swift; sourceTree = ""; }; 9732075B1DD136BB00EDD3DC /* CoreDataExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataExtension.swift; sourceTree = ""; }; @@ -479,7 +479,7 @@ children = ( 971A10511D022D9D007FC62C /* AppDelegate.swift */, 975B90FD1CEB909100D13906 /* iOSExtensions.swift */, - 9726591C1D90A64500D1DFFB /* Notifications.swift */, + 9726591C1D90A64500D1DFFB /* Notification.swift */, 978C587A1C1CCC9C0077AE47 /* Storyboards */, 978C58821C1CCDAF0077AE47 /* Controllers */, 971A10221D022AD5007FC62C /* View */, @@ -1065,7 +1065,7 @@ 973207A51DD1984700EDD3DC /* SearchScopeAndHistoryController.swift in Sources */, 973208231DD19C7600EDD3DC /* DownloadProgress.swift in Sources */, 97A1FD161D6F71CE00A80EE2 /* DirectoryMonitor.swift in Sources */, - 9726591D1D90A64600D1DFFB /* Notifications.swift in Sources */, + 9726591D1D90A64600D1DFFB /* Notification.swift in Sources */, 971A102C1D022AD5007FC62C /* BarButtonItems.swift in Sources */, 970A2A221DD562CB0078BB7C /* BookOperations.swift in Sources */, 97A1FD391D6F724E00A80EE2 /* pathTools.cpp in Sources */, diff --git a/Kiwix/Network/Network.swift b/Kiwix/Network/Network.swift index 78c19138..45bf0616 100644 --- a/Kiwix/Network/Network.swift +++ b/Kiwix/Network/Network.swift @@ -6,8 +6,6 @@ // Copyright © 2017 Chris Li. All rights reserved. // -import UserNotifications - class Network: NSObject, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDownloadDelegate { static let shared = Network() let bookSizeThreshold: Int64 = 100000000 @@ -143,20 +141,11 @@ class Network: NSObject, URLSessionDelegate, URLSessionTaskDelegate, URLSessionD } if Preference.Notifications.bookDownloadFinish { - UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) in - guard settings.alertSetting == .enabled else {return} - self.managedObjectContext.perform({ - guard let book = Book.fetch(bookID, context: self.managedObjectContext) else {return} - let content = UNMutableNotificationContent() - content.categoryIdentifier = "org.kiwix.download-finished" - content.title = { - if let title = book.title {return title + " is downloaded!"} - else {return "Download task is finished!"} - }() - content.body = book.fileSizeDescription + " has been transferred." - let request = UNNotificationRequest(identifier: "org.kiwix.download-finished." + bookID, content: content, trigger: nil) - UNUserNotificationCenter.current().add(request, withCompletionHandler: nil) - }) + self.managedObjectContext.perform({ + guard let book = Book.fetch(bookID, context: self.managedObjectContext) else {return} + AppNotification.shared.downloadFinished(bookID: book.id, + bookTitle: book.title ?? "Book", + fileSizeDescription: book.fileSizeDescription) }) } } @@ -191,6 +180,7 @@ class Network: NSObject, URLSessionDelegate, URLSessionTaskDelegate, URLSessionD let downloadTask = DownloadTask.fetch(bookID: bookID, context: self.managedObjectContext) else {return} book.state = .local self.managedObjectContext.delete(downloadTask) + if self.managedObjectContext.hasChanges { try? self.managedObjectContext.save() } } } } diff --git a/Kiwix/Operations/RefreshLibrary.swift b/Kiwix/Operations/RefreshLibrary.swift index 2533f989..9d3f1e2a 100644 --- a/Kiwix/Operations/RefreshLibrary.swift +++ b/Kiwix/Operations/RefreshLibrary.swift @@ -30,7 +30,8 @@ fileprivate class Retrieve: NetworkDataProcedure { init() { let session = URLSession.shared let url = URL(string: "https://download.kiwix.org/library/library.xml")! - let request = URLRequest(url: url) + var request = URLRequest(url: url) + request.timeoutInterval = 10.0 super.init(session: session, request: request) add(observer: NetworkObserver()) } diff --git a/Kiwix/Operations/UIProcedure.swift b/Kiwix/Operations/UIProcedure.swift index 21cb07fb..fc04b285 100644 --- a/Kiwix/Operations/UIProcedure.swift +++ b/Kiwix/Operations/UIProcedure.swift @@ -9,6 +9,8 @@ import MessageUI import ProcedureKit +// MARK: - Feedback + class FeedbackMailOperation: UIProcedure, MFMailComposeViewControllerDelegate { let controller = MFMailComposeViewController() @@ -116,3 +118,37 @@ extension AlertProcedure { } } +// MARK: - Library + +extension AlertProcedure { + class Library { + static func refreshError(context: UIViewController) -> AlertProcedure { + assert(Thread.isMainThread, "Library refresh error alert has to be initialized in the main thread") + let alert = AlertProcedure(presentAlertFrom: context, withPreferredStyle: .actionSheet, waitForDismissal: true) + alert.title = "There was an error" + if book.state == .cloud { + alert.add(actionWithTitle: Localized.Library.download, style: .default) { _ in + Network.shared.start(bookID: book.id) + alert.finish() + } + alert.add(actionWithTitle: Localized.Library.copyURL, style: .default) { _ in + guard let url = book.url else {return} + UIPasteboard.general.string = url.absoluteString + alert.finish() + } + } else if book.state == .local { + alert.add(actionWithTitle: "set back to cloud", style: .default) { _ in + let context = AppDelegate.persistentContainer.viewContext + context.perform({ + book.state = .cloud + }) + alert.finish() + } + } + + alert.add(actionWithTitle: Localized.Common.cancel, style: .cancel) { _ in alert.finish() } + return alert + } + } +} + diff --git a/Kiwix/Tools/StringTools.swift b/Kiwix/Tools/StringTools.swift index 05bcedd3..3e1e30fe 100644 --- a/Kiwix/Tools/StringTools.swift +++ b/Kiwix/Tools/StringTools.swift @@ -70,9 +70,71 @@ class LocalizedStrings { } class Localized { + + // MARK: - Common + class Common { static let ok = NSLocalizedString("OK", comment: "Alert action") static let cancel = NSLocalizedString("Cancel", comment: "Alert action") } + // MARK: - Library + + class Library { + static let cloudTitle = NSLocalizedString("Cloud", comment: "Library, Cloud") + static let localTitle = NSLocalizedString("Local", comment: "Library, Local") + + static let download = NSLocalizedString("Download", comment: "Library, more action sheet") + static let copyURL = NSLocalizedString("Copy URL", comment: "Library, more action sheet") + + class LanguageFilter { + static let title = NSLocalizedString("Languages", comment: "Library, Language Filter") + static let all = NSLocalizedString("ALL", comment: "Library, Language Filter") + static let showing = NSLocalizedString("SHOWING", comment: "Library, Language Filter") + static let hiding = NSLocalizedString("HIDING", comment: "Library, Language Filter") + static let original = NSLocalizedString("Original", comment: "Library, Language Filter") + } + } + + // MARK: - Setting + + class Setting { + static let title = NSLocalizedString("Setting", comment: "Setting table title") + + static let fontSize = NSLocalizedString("Font Size", comment: "Setting table rows") + static let notifications = NSLocalizedString("Notifications", comment: "Setting table rows") + static let feedback = NSLocalizedString("Email us your suggestions", comment: "Setting table rows") + static let rateApp = NSLocalizedString("Give Kiwix a Rate", comment: "Setting table rows") + static let about = NSLocalizedString("About", comment: "Setting table rows") + static let version = NSLocalizedString("Kiwix for iOS v%@", comment: "Setting table footer") + + class Notifications { + static let libraryRefresh = NSLocalizedString("Library Refresh", comment: "Notification Setting") + static let bookUpdateAvailable = NSLocalizedString("Book Update Available", comment: "Notification Setting") + static let bookDownloadFinish = NSLocalizedString("Book Download Finish", comment: "Notification Setting") + } + + class Feedback { + static let subject = NSLocalizedString(String(format: "Feedback: Kiwix for iOS %@", Bundle.appShortVersion), + comment: "Feedback email composer subject, %@ will be replaced by kiwix version string") + class Success { + static let title = NSLocalizedString("Email Sent", comment: "Feedback success title") + static let message = NSLocalizedString("Your Email was sent successfully.", comment: "Feedback success message") + } + class NotConfiguredError { + static let title = NSLocalizedString("Cannot send Email", comment: "Feedback error title") + static let message = NSLocalizedString("The device is not configured to send email. You can send an email to chris@kiwix.org using other devices.", comment: "Feedback error message") + } + class ComposerError { + static let title = NSLocalizedString("Email not sent", comment: "Feedback error title") + } + } + + class RateApp { + static let message = NSLocalizedString("Would you like to rate Kiwix in App Store?", comment: "Rate app alert message") + static let goToAppStore = NSLocalizedString("Go to App Store", comment: "Rate app alert action") + static let remindMeLater = NSLocalizedString("Remind Me Later", comment: "Rate app alert action") + } + } + }