This commit is contained in:
Chris Li 2017-01-31 17:30:07 -05:00
parent 3de63f8e46
commit 463810d2ef
11 changed files with 151 additions and 95 deletions

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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()
}
}

View File

@ -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")
}
}
}

View File

@ -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])
}
}

View File

@ -1,9 +0,0 @@
//
// Notifications.swift
// Kiwix
//
// Created by Chris Li on 9/19/16.
// Copyright © 2016 Chris Li. All rights reserved.
//
import UIKit

View File

@ -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 = "<group>"; };
9726591C1D90A64500D1DFFB /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
9726591C1D90A64500D1DFFB /* Notification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
972F81561DDBFC79008D7289 /* Search.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Search.swift; sourceTree = "<group>"; };
972F81581DDC1B71008D7289 /* Controllers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Controllers.swift; sourceTree = "<group>"; };
9732075B1DD136BB00EDD3DC /* CoreDataExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataExtension.swift; sourceTree = "<group>"; };
@ -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 */,

View File

@ -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() }
}
}
}

View File

@ -30,7 +30,8 @@ fileprivate class Retrieve: NetworkDataProcedure<URLSession> {
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())
}

View File

@ -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
}
}
}

View File

@ -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")
}
}
}