mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-26 13:29:31 -04:00
commit
This commit is contained in:
parent
3bbb2b1f23
commit
f3690739e9
74
.gitignore
vendored
74
.gitignore
vendored
@ -1,9 +1,67 @@
|
||||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData/
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata/
|
||||
|
||||
## Other
|
||||
*.moved-aside
|
||||
*.xcuserstate
|
||||
Pods
|
||||
Kiwix/libkiwix/C&C++
|
||||
Kiwix/libkiwix/include
|
||||
Kiwix/libkiwix/shared
|
||||
Kiwix/libkiwix/static
|
||||
*.a
|
||||
Kiwix/libkiwix/iOS
|
||||
Kiwix/libkiwix/macOS
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.dSYM.zip
|
||||
*.dSYM
|
||||
|
||||
## Playgrounds
|
||||
timeline.xctimeline
|
||||
playground.xcworkspace
|
||||
|
||||
# Swift Package Manager
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||
# Packages/
|
||||
.build/
|
||||
|
||||
# CocoaPods
|
||||
#
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||
#
|
||||
Pods/
|
||||
|
||||
# Carthage
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||
# Carthage/Checkouts
|
||||
|
||||
Carthage/Build
|
||||
|
||||
# fastlane
|
||||
#
|
||||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||
# screenshots whenever they are needed.
|
||||
# For more information about the recommended setup visit:
|
||||
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
|
||||
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
|
||||
Kiwix/libkiwix/
|
@ -274,8 +274,10 @@ class CloudBooksController: CoreDataTableBaseController, UITableViewDelegate, UI
|
||||
switch book.spaceState {
|
||||
case .enough:
|
||||
let action = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: LocalizedStrings.download, handler: { _ in
|
||||
// guard let download = DownloadBookOperation(bookID: book.id) else {return}
|
||||
// Network.shared.queue.addOperation(download)
|
||||
guard let url = book.url else {return}
|
||||
let download = BookDownloadProcedure(session: DownloadManager.shared.session, bookID: book.id, url: url)
|
||||
DownloadManager.shared.queue.add(operation: download)
|
||||
self.tableView.setEditing(false, animated: true)
|
||||
})
|
||||
action.backgroundColor = UIColor.defaultTint
|
||||
return [action]
|
||||
|
@ -49,7 +49,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.8.3683</string>
|
||||
<string>1.8.3835</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.8.3701</string>
|
||||
<string>1.8.3853</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
|
@ -63,6 +63,8 @@
|
||||
975227CD1D0227E8001D1DDE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975227CA1D0227E8001D1DDE /* Main.storyboard */; };
|
||||
975227CE1D0227E8001D1DDE /* Setting.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975227CB1D0227E8001D1DDE /* Setting.storyboard */; };
|
||||
975227D01D022814001D1DDE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975227CF1D022814001D1DDE /* LaunchScreen.storyboard */; };
|
||||
9757C74A1E10660B008A9469 /* DownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9757C7491E10660B008A9469 /* DownloadManager.swift */; };
|
||||
9757C74C1E106958008A9469 /* BackgroundDownload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9757C74B1E106958008A9469 /* BackgroundDownload.swift */; };
|
||||
975B90FE1CEB909100D13906 /* iOSExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975B90FD1CEB909100D13906 /* iOSExtensions.swift */; };
|
||||
9764CBD11D806AD800072D6A /* RefreshLibControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764CBD01D806AD800072D6A /* RefreshLibControl.swift */; };
|
||||
9764F5931D830EF200E0B1C4 /* liblzma.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9764F5921D830EF200E0B1C4 /* liblzma.tbd */; };
|
||||
@ -217,6 +219,8 @@
|
||||
975227CA1D0227E8001D1DDE /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = "Kiwix-iOS/Storyboard/Main.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
975227CB1D0227E8001D1DDE /* Setting.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Setting.storyboard; path = "Kiwix-iOS/Storyboard/Setting.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
975227CF1D022814001D1DDE /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = "Kiwix-iOS/Storyboard/LaunchScreen.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
9757C7491E10660B008A9469 /* DownloadManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadManager.swift; sourceTree = "<group>"; };
|
||||
9757C74B1E106958008A9469 /* BackgroundDownload.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundDownload.swift; sourceTree = "<group>"; };
|
||||
975B90FD1CEB909100D13906 /* iOSExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = iOSExtensions.swift; path = "Kiwix-iOS/iOSExtensions.swift"; sourceTree = SOURCE_ROOT; };
|
||||
9763275D1D64FE0F0034F120 /* BookDetailController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookDetailController.swift; sourceTree = "<group>"; };
|
||||
9764CBD01D806AD800072D6A /* RefreshLibControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshLibControl.swift; sourceTree = "<group>"; };
|
||||
@ -751,6 +755,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97DF259F1D6F996B001648A3 /* Network.swift */,
|
||||
9757C7491E10660B008A9469 /* DownloadManager.swift */,
|
||||
9726591A1D8DB91200D1DFFB /* DownloadProgress.swift */,
|
||||
);
|
||||
path = Network;
|
||||
@ -773,6 +778,7 @@
|
||||
children = (
|
||||
97D6811C1D6F70AC00E5FA99 /* GlobalQueue.swift */,
|
||||
9764CBD21D8083AA00072D6A /* ArticleOperation.swift */,
|
||||
9757C74B1E106958008A9469 /* BackgroundDownload.swift */,
|
||||
970A2A211DD562CB0078BB7C /* BookOperations.swift */,
|
||||
973A5C981DEBC54800C7804C /* CloudKit.swift */,
|
||||
973208281DD223DB00EDD3DC /* RefreshLibrary.swift */,
|
||||
@ -1111,6 +1117,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9757C74C1E106958008A9469 /* BackgroundDownload.swift in Sources */,
|
||||
970E7F771D9DBEA900741290 /* SettingController.swift in Sources */,
|
||||
973A5C951DEA6DD000C7804C /* URLResponseCache.swift in Sources */,
|
||||
973207A51DD1984700EDD3DC /* SearchBooksController.swift in Sources */,
|
||||
@ -1137,6 +1144,7 @@
|
||||
97A1FD3A1D6F724E00A80EE2 /* reader.cpp in Sources */,
|
||||
973207A31DD1983D00EDD3DC /* LanguageFilterController.swift in Sources */,
|
||||
97D681371D6F711A00E5FA99 /* Article.swift in Sources */,
|
||||
9757C74A1E10660B008A9469 /* DownloadManager.swift in Sources */,
|
||||
972F81571DDBFC79008D7289 /* Search.swift in Sources */,
|
||||
970E7F831DA0305000741290 /* WelcomeController.swift in Sources */,
|
||||
97A1FD3B1D6F724E00A80EE2 /* stringTools.cpp in Sources */,
|
||||
|
@ -7,7 +7,7 @@
|
||||
<key>Bookmarks.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>2</integer>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>Kiwix-iOS.xcscheme</key>
|
||||
<dict>
|
||||
@ -20,57 +20,57 @@
|
||||
<key>9722121A1D3ECCFE00C0DCF2</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>973BCCE81CEB3FA400F10B44</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>973BCCFB1CEB3FA400F10B44</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>973BCD061CEB3FA500F10B44</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>9779C2FD1D4574280064CC8E</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>9779C3121D4575AD0064CC8E</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>97A2AB871C1B80FF00052E74</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>97A2AB9E1C1B80FF00052E74</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>97A2ABA91C1B810000052E74</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>97CF3EEA1D428F9600AE82FE</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>97E609EE1D103DED00EBCB9D</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
|
@ -12,7 +12,7 @@ import CoreData
|
||||
|
||||
class DownloadTask: NSManagedObject {
|
||||
|
||||
class func fetch(_ book: Book, context: NSManagedObjectContext) -> DownloadTask? {
|
||||
class func fetch(book: Book, context: NSManagedObjectContext) -> DownloadTask? {
|
||||
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "DownloadTask")
|
||||
fetchRequest.predicate = NSPredicate(format: "book = %@", book)
|
||||
let downloadTask = DownloadTask.fetch(fetchRequest, type: DownloadTask.self, context: context)?.first ?? insert(DownloadTask.self, context: context)
|
||||
|
62
Kiwix/Network/DownloadManager.swift
Normal file
62
Kiwix/Network/DownloadManager.swift
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// DownloadManager.swift
|
||||
// Kiwix
|
||||
//
|
||||
// Created by Chris Li on 12/25/16.
|
||||
// Copyright © 2016 Chris Li. All rights reserved.
|
||||
//
|
||||
|
||||
import ProcedureKit
|
||||
|
||||
class DownloadManager: NSObject, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDownloadDelegate {
|
||||
static let shared = DownloadManager()
|
||||
let queue = ProcedureQueue()
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
private(set) lazy var session: Foundation.URLSession = {
|
||||
let configuration = URLSessionConfiguration.background(withIdentifier: "org.kiwix.www")
|
||||
configuration.allowsCellularAccess = false
|
||||
configuration.isDiscretionary = false
|
||||
return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
|
||||
}()
|
||||
|
||||
|
||||
|
||||
// MARK: - URLSessionDelegate
|
||||
|
||||
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - URLSessionTaskDelegate
|
||||
|
||||
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
|
||||
guard let operation = queue.operations.flatMap({$0 as? BookDownloadProcedure})
|
||||
.filter({$0.task.taskDescription == task.taskDescription})
|
||||
.first else {
|
||||
if let bookID = task.taskDescription,
|
||||
let resumeData = (error as? NSError)?.userInfo[NSURLSessionDownloadTaskResumeData] as? Data {
|
||||
let operation = BookDownloadProcedure(session: session, bookID: bookID, resumeData: resumeData)
|
||||
DownloadManager.shared.queue.add(operation: operation)
|
||||
}
|
||||
return
|
||||
}
|
||||
if let error = error {
|
||||
operation.finish(withError: error)
|
||||
} else {
|
||||
operation.finish()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - URLSessionDownloadDelegate
|
||||
|
||||
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
|
||||
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
|
||||
|
||||
}
|
||||
}
|
80
Kiwix/Operations/BackgroundDownload.swift
Normal file
80
Kiwix/Operations/BackgroundDownload.swift
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// BookDownload.swift
|
||||
// Kiwix
|
||||
//
|
||||
// Created by Chris Li on 12/25/16.
|
||||
// Copyright © 2016 Chris Li. All rights reserved.
|
||||
//
|
||||
|
||||
import ProcedureKit
|
||||
|
||||
class BackgroundDownloadProcedure: Procedure {
|
||||
let task: URLSessionDownloadTask
|
||||
let resumeDataProcessing: (Data?) -> Void
|
||||
private let stateLock = NSLock()
|
||||
private var produceResumeData = false
|
||||
|
||||
init(task: URLSessionDownloadTask, resumeData: @escaping (Data?) -> Void) {
|
||||
self.task = task
|
||||
self.resumeDataProcessing = resumeData
|
||||
super.init()
|
||||
|
||||
add(observer: NetworkObserver())
|
||||
addDidCancelBlockObserver { procedure, errors in
|
||||
procedure.stateLock.withCriticalScope {
|
||||
if procedure.produceResumeData {
|
||||
procedure.task.cancel(byProducingResumeData: self.resumeDataProcessing)
|
||||
} else {
|
||||
procedure.task.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func execute() {
|
||||
stateLock.withCriticalScope {
|
||||
guard !isCancelled, task.state == .suspended else { return }
|
||||
task.resume()
|
||||
}
|
||||
}
|
||||
|
||||
func pause() {
|
||||
produceResumeData = true
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
class BookDownloadProcedure: BackgroundDownloadProcedure {
|
||||
|
||||
init(task: URLSessionDownloadTask) {
|
||||
super.init(task: task) { data in
|
||||
print("cancelled, resume data length = \(data?.count)")
|
||||
}
|
||||
addDidFinishBlockObserver { (procedure, errors) in
|
||||
print("Download has finished")
|
||||
}
|
||||
}
|
||||
|
||||
convenience init(session: URLSession, bookID: String, url: URL) {
|
||||
let task = session.downloadTask(with: url)
|
||||
task.taskDescription = bookID
|
||||
self.init(task: task)
|
||||
}
|
||||
|
||||
convenience init(session: URLSession, bookID: String, resumeData: Data) {
|
||||
let task = session.downloadTask(withResumeData: resumeData)
|
||||
task.taskDescription = bookID
|
||||
self.init(task: task)
|
||||
}
|
||||
|
||||
override func execute() {
|
||||
let context = AppDelegate.persistentContainer.viewContext
|
||||
context.performAndWait {
|
||||
guard let bookID = self.task.taskDescription,
|
||||
let book = Book.fetch(bookID, context: context),
|
||||
let downloadTask = DownloadTask.fetch(book: book, context: context) else {return}
|
||||
downloadTask.state = .queued
|
||||
}
|
||||
super.execute()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user