diff --git a/Kiwix-iOS/AppDelegate.swift b/Kiwix-iOS/AppDelegate.swift
index 0f5200ae..62f2d173 100644
--- a/Kiwix-iOS/AppDelegate.swift
+++ b/Kiwix-iOS/AppDelegate.swift
@@ -31,7 +31,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Register notification
let settings = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil) // Here are the notification permission the app wants
- application.registerUserNotificationSettings(settings)
+// application.registerUserNotificationSettings(settings)
// Set background refresh interval
application.setMinimumBackgroundFetchInterval(86400)
diff --git a/Kiwix-iOS/Controller/Library/DownloadTasksController.swift b/Kiwix-iOS/Controller/Library/DownloadTasksController.swift
index a0bb1808..9c928a4a 100644
--- a/Kiwix-iOS/Controller/Library/DownloadTasksController.swift
+++ b/Kiwix-iOS/Controller/Library/DownloadTasksController.swift
@@ -177,37 +177,38 @@ class DownloadTasksController: UITableViewController, NSFetchedResultsController
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
- guard let downloadTask = self.fetchedResultController.objectAtIndexPath(indexPath) as? DownloadTask else {return nil}
+ guard let downloadTask = self.fetchedResultController.objectAtIndexPath(indexPath) as? DownloadTask,
+ let bookID = downloadTask.book?.id else {return nil}
var actions = [UITableViewRowAction]()
switch downloadTask.state {
case .Downloading:
let pause = UITableViewRowAction(style: .Normal, title: "Pause") { (action, indexPath) in
- guard let bookID = downloadTask.book?.id else {return}
let operation = PauseBookDwonloadOperation(bookID: bookID)
GlobalQueue.shared.addOperation(operation)
tableView.setEditing(false, animated: true)
}
actions.insert(pause, atIndex: 0)
case .Paused:
- if let book = downloadTask.book,
- let resumeData = Preference.resumeData[book.id] {
- let resume = UITableViewRowAction(style: .Normal, title: "Resume") { (action, indexPath) in
- let task = Network.shared.session.downloadTaskWithResumeData(resumeData)
- let operation = DownloadBookOperation(downloadTask: task)
- Network.shared.queue.addOperation(operation)
- tableView.setEditing(false, animated: true)
- }
- actions.insert(resume, atIndex: 0)
- } else {
- let restart = UITableViewRowAction(style: .Normal, title: "Restart") { (action, indexPath) in
- guard let bookID = downloadTask.book?.id,
- let operation = DownloadBookOperation(bookID: bookID) else {return}
- Network.shared.queue.addOperation(operation)
- tableView.setEditing(false, animated: true)
- }
- actions.insert(restart, atIndex: 0)
+ let resume = UITableViewRowAction(style: .Normal, title: "Resume") { (action, indexPath) in
+ let operation = ResumeBookDwonloadOperation(bookID: bookID)
+ GlobalQueue.shared.addOperation(operation)
+ tableView.setEditing(false, animated: true)
}
+ actions.insert(resume, atIndex: 0)
+//
+// if let book = downloadTask.book,
+// let resumeData = Preference.resumeData[book.id] {
+//
+// } else {
+// let restart = UITableViewRowAction(style: .Normal, title: "Restart") { (action, indexPath) in
+// guard let bookID = downloadTask.book?.id,
+// let operation = DownloadBookOperation(bookID: bookID) else {return}
+// Network.shared.queue.addOperation(operation)
+// tableView.setEditing(false, animated: true)
+// }
+// actions.insert(restart, atIndex: 0)
+// }
default:
break
}
diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist
index 6c3466ac..29e4eb6e 100644
--- a/Kiwix-iOS/Info.plist
+++ b/Kiwix-iOS/Info.plist
@@ -49,7 +49,7 @@
CFBundleVersion
- 1.8.669
+ 1.8.725
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/Kiwix-iOSWidgets/Bookmarks/Info.plist b/Kiwix-iOSWidgets/Bookmarks/Info.plist
index 878a7252..a31e582b 100644
--- a/Kiwix-iOSWidgets/Bookmarks/Info.plist
+++ b/Kiwix-iOSWidgets/Bookmarks/Info.plist
@@ -21,7 +21,7 @@
CFBundleSignature
????
CFBundleVersion
- 1.8.672
+ 1.8.728
NSExtension
NSExtensionMainStoryboard
diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj
index ff96f3c7..c314ca7b 100644
--- a/Kiwix.xcodeproj/project.pbxproj
+++ b/Kiwix.xcodeproj/project.pbxproj
@@ -43,6 +43,7 @@
97219DBD1D383A00009FDFF1 /* BookmarkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97219DBC1D383A00009FDFF1 /* BookmarkController.swift */; };
9722122B1D3FCCE200C0DCF2 /* MainControllerShowHide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9722122A1D3FCCE200C0DCF2 /* MainControllerShowHide.swift */; };
972659191D8AE4B400D1DFFB /* Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 972659181D8AE4B400D1DFFB /* Alerts.swift */; };
+ 9726591B1D8DB91200D1DFFB /* DownloadProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9726591A1D8DB91200D1DFFB /* DownloadProgress.swift */; };
9734E54E1D289D060061C39B /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9734E54D1D289D060061C39B /* Welcome.storyboard */; };
973BCCEC1CEB3FA400F10B44 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973BCCEB1CEB3FA400F10B44 /* AppDelegate.swift */; };
973BCCF31CEB3FA400F10B44 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 973BCCF21CEB3FA400F10B44 /* Assets.xcassets */; };
@@ -108,7 +109,6 @@
97A1FD431D6F728200A80EE2 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A1FD3E1D6F728200A80EE2 /* FileManager.swift */; };
97A1FD441D6F728200A80EE2 /* Preference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A1FD401D6F728200A80EE2 /* Preference.swift */; };
97A1FD451D6F728200A80EE2 /* StringTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A1FD411D6F728200A80EE2 /* StringTools.swift */; };
- 97A461B71D74819000AC3DED /* DownloadProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A461B61D74819000AC3DED /* DownloadProgress.swift */; };
97A7017F1D2C59CA00AAE2D8 /* GetStartedController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A7017E1D2C59CA00AAE2D8 /* GetStartedController.swift */; };
97A8AD841D6C951A00584ED1 /* LocalBooksController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A8AD831D6C951A00584ED1 /* LocalBooksController.swift */; };
97A8AD871D6CF38000584ED1 /* EmptyTableConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97A8AD861D6CF38000584ED1 /* EmptyTableConfigExtension.swift */; };
@@ -256,6 +256,7 @@
97219DBC1D383A00009FDFF1 /* BookmarkController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BookmarkController.swift; path = "Kiwix-iOS/Controller/Bookmark/BookmarkController.swift"; sourceTree = SOURCE_ROOT; };
9722122A1D3FCCE200C0DCF2 /* MainControllerShowHide.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MainControllerShowHide.swift; path = "Kiwix-iOS/Controller/Main/MainControllerShowHide.swift"; sourceTree = SOURCE_ROOT; };
972659181D8AE4B400D1DFFB /* Alerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Alerts.swift; sourceTree = ""; };
+ 9726591A1D8DB91200D1DFFB /* DownloadProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadProgress.swift; sourceTree = ""; };
9734E54D1D289D060061C39B /* Welcome.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Welcome.storyboard; path = "Kiwix-iOS/Storyboard/Welcome.storyboard"; sourceTree = SOURCE_ROOT; };
973BCCE91CEB3FA400F10B44 /* Kiwix.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kiwix.app; sourceTree = BUILT_PRODUCTS_DIR; };
973BCCEB1CEB3FA400F10B44 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = "Kiwix-OSX/AppDelegate.swift"; sourceTree = SOURCE_ROOT; };
@@ -340,7 +341,6 @@
97A2AB881C1B80FF00052E74 /* Kiwix.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kiwix.app; sourceTree = BUILT_PRODUCTS_DIR; };
97A2AB9F1C1B80FF00052E74 /* Kiwix-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Kiwix-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
97A2ABAA1C1B810000052E74 /* Kiwix-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Kiwix-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
- 97A461B61D74819000AC3DED /* DownloadProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadProgress.swift; sourceTree = ""; };
97A7017E1D2C59CA00AAE2D8 /* GetStartedController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GetStartedController.swift; path = "Kiwix-iOS/Controller/Welcome/GetStartedController.swift"; sourceTree = SOURCE_ROOT; };
97A8AD831D6C951A00584ED1 /* LocalBooksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalBooksController.swift; sourceTree = ""; };
97A8AD861D6CF38000584ED1 /* EmptyTableConfigExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyTableConfigExtension.swift; sourceTree = ""; };
@@ -852,7 +852,6 @@
97A1FD3C1D6F728200A80EE2 /* Tools */ = {
isa = PBXGroup;
children = (
- 97A461B61D74819000AC3DED /* DownloadProgress.swift */,
97A1FD3D1D6F728200A80EE2 /* Extensions.swift */,
97A1FD3E1D6F728200A80EE2 /* FileManager.swift */,
97C601DD1D7F342100362D4F /* HTMLHeading.swift */,
@@ -967,6 +966,7 @@
isa = PBXGroup;
children = (
97DF259F1D6F996B001648A3 /* Network.swift */,
+ 9726591A1D8DB91200D1DFFB /* DownloadProgress.swift */,
97A1FD1B1D6F71D800A80EE2 /* URLResponseCache.swift */,
);
path = Network;
@@ -1520,6 +1520,7 @@
97A8AD871D6CF38000584ED1 /* EmptyTableConfigExtension.swift in Sources */,
971A102E1D022AD5007FC62C /* TableViewCells.swift in Sources */,
97DF259D1D6F9053001648A3 /* URLSessionDownloadTaskOperation.swift in Sources */,
+ 9726591B1D8DB91200D1DFFB /* DownloadProgress.swift in Sources */,
97E60A021D10423A00EBCB9D /* ShadowViews.swift in Sources */,
970E68BA1D3809A3001E8514 /* MainController.swift in Sources */,
970C65501D398D5A007032F8 /* BookmarkControllerAnimator.swift in Sources */,
@@ -1574,7 +1575,6 @@
971A103B1D022C2C007FC62C /* AdjustLayoutTBVC.swift in Sources */,
97219DBD1D383A00009FDFF1 /* BookmarkController.swift in Sources */,
97D6812E1D6F70DE00E5FA99 /* Kiwix.xcdatamodeld in Sources */,
- 97A461B71D74819000AC3DED /* DownloadProgress.swift in Sources */,
971A10341D022AEC007FC62C /* BookmarkTBVC.swift in Sources */,
97A1FD1D1D6F71D800A80EE2 /* URLResponseCache.swift in Sources */,
9764F5971D8339D500E0B1C4 /* JSInjection.swift in Sources */,
diff --git a/Kiwix/Tools/DownloadProgress.swift b/Kiwix/Network/DownloadProgress.swift
similarity index 91%
rename from Kiwix/Tools/DownloadProgress.swift
rename to Kiwix/Network/DownloadProgress.swift
index b2244dfd..9b0f6e5e 100644
--- a/Kiwix/Tools/DownloadProgress.swift
+++ b/Kiwix/Network/DownloadProgress.swift
@@ -14,19 +14,13 @@ class DownloadProgress: NSProgress {
private let timePointMinCount: Int = 20
private let timePointMaxCount: Int = 200
- init(completedUnitCount: Int64 = 0, totalUnitCount: Int64) {
+ init(completedUnitCount: Int64, totalUnitCount: Int64) {
super.init(parent: nil, userInfo: [NSProgressFileOperationKindKey: NSProgressFileOperationKindDownloading])
self.kind = NSProgressKindFile
self.totalUnitCount = totalUnitCount
self.completedUnitCount = completedUnitCount
}
- override var completedUnitCount: Int64 {
- didSet {
- add(completedUnitCount)
- }
- }
-
// MARK: - Descriptions
var fractionCompletedDescription: String? {
@@ -60,7 +54,8 @@ class DownloadProgress: NSProgress {
setUserInfoObject(NSNumber(double: remainingSeconds), forKey: NSProgressEstimatedTimeRemainingKey)
}
- private func add(completedUnitCount: Int64) {
+ func addObservation(totalBytesWritten: Int64) {
+ completedUnitCount = totalBytesWritten
let timeStamp = NSDate().timeIntervalSince1970
if let lastPoint = timePoints.last {
guard timeStamp - lastPoint.timeStamp > 0.2 else {return}
diff --git a/Kiwix/Network/Network.swift b/Kiwix/Network/Network.swift
index 990eeb78..0c1e0386 100644
--- a/Kiwix/Network/Network.swift
+++ b/Kiwix/Network/Network.swift
@@ -74,7 +74,7 @@ class Network: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSe
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
guard let bookID = downloadTask.taskDescription,
let operation = operations[bookID] else {return}
- operation.progress.completedUnitCount = totalBytesWritten
+ operation.progress.addObservation(totalBytesWritten)
context.performBlock {
guard let downloadTask = Book.fetch(bookID, context: self.context)?.downloadTask where downloadTask.state == .Queued else {return}
diff --git a/Kiwix/Operations/BookOperation.swift b/Kiwix/Operations/BookOperation.swift
index ec1d0e19..1af00037 100644
--- a/Kiwix/Operations/BookOperation.swift
+++ b/Kiwix/Operations/BookOperation.swift
@@ -11,7 +11,6 @@ import CoreData
import Operations
class DownloadBookOperation: URLSessionDownloadTaskOperation {
-
let bookID: String?
let progress: DownloadProgress
@@ -20,6 +19,33 @@ class DownloadBookOperation: URLSessionDownloadTaskOperation {
bookID = downloadTask.taskDescription
super.init(downloadTask: downloadTask)
name = downloadTask.taskDescription
+
+ // Update Coredata
+ let context = NSManagedObjectContext.mainQueueContext
+ context.performBlockAndWait {
+ guard let bookID = self.bookID,
+ let book = Book.fetch(bookID, context: context),
+ let downloadTask = DownloadTask.addOrUpdate(book, context: context) else {return}
+ book.isLocal = nil
+ downloadTask.state = .Queued
+
+ // Overwrite progress
+ self.progress.completedUnitCount = book.downloadTask?.totalBytesWritten ?? 0
+ self.progress.totalUnitCount = book.fileSize
+ }
+ }
+
+ convenience init?(bookID: String, resumeData: NSData) {
+ if #available(iOS 10.0, *) {
+ guard let data = DownloadBookOperation.correctFuckingResumeData(resumeData) else {return nil}
+ let downloadTask = Network.shared.session.downloadTaskWithResumeData(data)
+ downloadTask.taskDescription = bookID
+ self.init(downloadTask: downloadTask)
+ } else {
+ let downloadTask = Network.shared.session.downloadTaskWithResumeData(resumeData)
+ downloadTask.taskDescription = bookID
+ self.init(downloadTask: downloadTask)
+ }
}
convenience init?(bookID: String) {
@@ -30,13 +56,6 @@ class DownloadBookOperation: URLSessionDownloadTaskOperation {
let task = Network.shared.session.downloadTaskWithURL(url)
task.taskDescription = bookID
self.init(downloadTask: task)
-
- let downloadTask = DownloadTask.addOrUpdate(book, context: context)
- downloadTask?.state = .Queued
- book.isLocal = nil
-
- progress.completedUnitCount = book.downloadTask?.totalBytesWritten ?? 0
- progress.totalUnitCount = book.fileSize
}
override func operationWillCancel(errors: [ErrorType]) {
@@ -45,76 +64,26 @@ class DownloadBookOperation: URLSessionDownloadTaskOperation {
override func operationDidCancel() {
print("Download Task did cancel")
- guard let bookID = bookID else {return}
+
+ // Update CoreData
let context = NSManagedObjectContext.mainQueueContext
context.performBlockAndWait {
- let book = Book.fetch(bookID, context: context)
- if !self.produceResumeData {book?.isLocal = false}
+ guard let bookID = self.bookID,
+ let book = Book.fetch(bookID, context: context) else {return}
+ if !self.produceResumeData {book.isLocal = false}
- guard let downloadTask = book?.downloadTask else {return}
+ guard let downloadTask = book.downloadTask else {return}
if self.produceResumeData {
downloadTask.state = .Paused
} else {
context.deleteObject(downloadTask)
}
-
}
}
-}
-
-class RemoveBookOperation: Operation {
- let bookID: String
+ // MARK: - Helper
- init(bookID: String) {
- self.bookID = bookID
- super.init()
- }
-
- override func execute() {
- let context = NSManagedObjectContext.mainQueueContext
- context.performBlockAndWait {
- guard let zimFileURL = ZimMultiReader.shared.readers[self.bookID]?.fileURL else {return}
- _ = try? NSFileManager.defaultManager().removeItemAtURL(zimFileURL)
-
- // Core data is updated by scan book operation
- // Article removal is handled by cascade relationship
-
- guard let idxFolderURL = ZimMultiReader.shared.readers[self.bookID]?.idxFolderURL else {return}
- _ = try? NSFileManager.defaultManager().removeItemAtURL(idxFolderURL)
- }
- finish()
- }
-}
-
-class PauseBookDwonloadOperation: Operation {
-
- let bookID: String
-
- init(bookID: String) {
- self.bookID = bookID
- super.init()
- }
-
- override func execute() {
- Network.shared.operations[bookID]?.cancel(produceResumeData: true)
- finish()
- }
-}
-
-class ResumeBookDwonloadOperation: Operation {
- let bookID: String
-
- init(bookID: String) {
- self.bookID = bookID
- super.init()
- }
-
- override func execute() {
-
- }
-
- private func correctFuckingResumeData(data: NSData?) -> NSData? {
+ private class func correctFuckingResumeData(data: NSData?) -> NSData? {
let kResumeCurrentRequest = "NSURLSessionResumeCurrentRequest"
let kResumeOriginalRequest = "NSURLSessionResumeOriginalRequest"
@@ -129,7 +98,7 @@ class ResumeBookDwonloadOperation: Operation {
return result
}
- private func correctFuckingRequestData(data: NSData?) -> NSData? {
+ private class func correctFuckingRequestData(data: NSData?) -> NSData? {
guard let data = data else {
return nil
}
@@ -174,3 +143,58 @@ class ResumeBookDwonloadOperation: Operation {
return result
}
}
+
+class RemoveBookOperation: Operation {
+ let bookID: String
+
+ init(bookID: String) {
+ self.bookID = bookID
+ super.init()
+ }
+
+ override func execute() {
+ let context = NSManagedObjectContext.mainQueueContext
+ context.performBlockAndWait {
+ guard let zimFileURL = ZimMultiReader.shared.readers[self.bookID]?.fileURL else {return}
+ _ = try? NSFileManager.defaultManager().removeItemAtURL(zimFileURL)
+
+ // Core data is updated by scan book operation
+ // Article removal is handled by cascade relationship
+
+ guard let idxFolderURL = ZimMultiReader.shared.readers[self.bookID]?.idxFolderURL else {return}
+ _ = try? NSFileManager.defaultManager().removeItemAtURL(idxFolderURL)
+ }
+ finish()
+ }
+}
+
+class PauseBookDwonloadOperation: Operation {
+ let bookID: String
+
+ init(bookID: String) {
+ self.bookID = bookID
+ super.init()
+ }
+
+ override func execute() {
+ Network.shared.operations[bookID]?.cancel(produceResumeData: true)
+ finish()
+ }
+}
+
+class ResumeBookDwonloadOperation: Operation {
+ let bookID: String
+
+ init(bookID: String) {
+ self.bookID = bookID
+ super.init()
+ name = "Resume Book Dwonload Operation, bookID = \(bookID)"
+ }
+
+ override func execute() {
+ guard let data: NSData = Preference.resumeData[bookID],
+ let operation = DownloadBookOperation(bookID: bookID, resumeData: data) else {return}
+ Network.shared.queue.addOperation(operation)
+ finish()
+ }
+}