diff --git a/Kiwix-iOS/Controller/Search/SearchResultTBVC.swift b/Kiwix-iOS/Controller/Search/SearchResultTBVC.swift
index 43a521d6..9ee0bb09 100644
--- a/Kiwix-iOS/Controller/Search/SearchResultTBVC.swift
+++ b/Kiwix-iOS/Controller/Search/SearchResultTBVC.swift
@@ -121,17 +121,17 @@ class SearchResultTBVC: UIViewController, UITableViewDataSource, UITableViewDele
tableView.reloadData()
return
}
-// let operation = SearchOperation(searchTerm: searchText) { [unowned self] (results) in
-// guard let results = results else {return}
-// self.searchResults = results
-// self.tableView.reloadData()
-// if results.count > 0 {
-// self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
-// }
-// }
+
let operation = SearchOperation(searchTerm: searchText)
operation.addObserver(DidFinishObserver {(operation, errors) in
- print("search op did finish, result injection")
+ guard let operation = operation as? SearchOperation else {return}
+ NSOperationQueue.mainQueue().addOperationWithBlock({
+ self.searchResults = operation.results
+ self.tableView.reloadData()
+
+ guard operation.results.count > 0 else {return}
+ self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
+ })
})
GlobalQueue.shared.add(search: operation)
}
diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist
index 30ada7b1..4fac61d5 100644
--- a/Kiwix-iOS/Info.plist
+++ b/Kiwix-iOS/Info.plist
@@ -49,7 +49,7 @@
CFBundleVersion
- 1.8.279
+ 1.8.323
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/Kiwix-iOSWidgets/Bookmarks/Info.plist b/Kiwix-iOSWidgets/Bookmarks/Info.plist
index 269099c1..ab47930a 100644
--- a/Kiwix-iOSWidgets/Bookmarks/Info.plist
+++ b/Kiwix-iOSWidgets/Bookmarks/Info.plist
@@ -21,7 +21,7 @@
CFBundleSignature
????
CFBundleVersion
- 1.8.282
+ 1.8.326
NSExtension
NSExtensionMainStoryboard
diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj
index 49096e25..4d658453 100644
--- a/Kiwix.xcodeproj/project.pbxproj
+++ b/Kiwix.xcodeproj/project.pbxproj
@@ -355,7 +355,6 @@
97D6811C1D6F70AC00E5FA99 /* GlobalQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalQueue.swift; sourceTree = ""; };
97D6811D1D6F70AC00E5FA99 /* RefreshLibraryOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshLibraryOperation.swift; sourceTree = ""; };
97D6811E1D6F70AC00E5FA99 /* ScanLocalBookOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanLocalBookOperation.swift; sourceTree = ""; };
- 97D6811F1D6F70AC00E5FA99 /* SearchOperation-old.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SearchOperation-old.swift"; sourceTree = ""; };
97D681201D6F70AC00E5FA99 /* UIOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIOperations.swift; sourceTree = ""; };
97D681211D6F70AC00E5FA99 /* UpdateWidgetDataSourceOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateWidgetDataSourceOperation.swift; sourceTree = ""; };
97D681221D6F70AC00E5FA99 /* URLSessionDownloadTaskOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionDownloadTaskOperation.swift; sourceTree = ""; };
@@ -990,7 +989,6 @@
97D6811D1D6F70AC00E5FA99 /* RefreshLibraryOperation.swift */,
97D6811E1D6F70AC00E5FA99 /* ScanLocalBookOperation.swift */,
97D4D64E1D874E6E00C1B065 /* SearchOperation.swift */,
- 97D6811F1D6F70AC00E5FA99 /* SearchOperation-old.swift */,
97D681201D6F70AC00E5FA99 /* UIOperations.swift */,
97D681211D6F70AC00E5FA99 /* UpdateWidgetDataSourceOperation.swift */,
97D681221D6F70AC00E5FA99 /* URLSessionDownloadTaskOperation.swift */,
diff --git a/Kiwix/Operations/SearchOperation-old.swift b/Kiwix/Operations/SearchOperation-old.swift
deleted file mode 100644
index a02e625c..00000000
--- a/Kiwix/Operations/SearchOperation-old.swift
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// SearchOperation.swift
-// Kiwix
-//
-// Created by Chris Li on 4/9/16.
-// Copyright © 2016 Chris. All rights reserved.
-//
-
-import UIKit
-import Operations
-
-class SearchOperation: GroupOperation {
- let completionHandler: ([SearchResult]?) -> Void
- private(set) var results = [SearchResult]()
- //private let startTime = NSDate()
-
- init(searchTerm: String, completionHandler: ([SearchResult]?) -> Void) {
- self.completionHandler = completionHandler
- super.init(operations: [NSOperation]())
-
- let sortOperation = SortSearchResultsOperation { (results) in
- self.results = results
- }
-
- for (id, zimReader) in ZimMultiReader.shared.readers {
- let managedObjectContext = UIApplication.appDelegate.managedObjectContext
- guard let book = Book.fetch(id, context: managedObjectContext) else {continue}
- guard book.includeInSearch else {continue}
- let operation = SingleBookSearchOperation(zimReader: zimReader,
- lowerCaseSearchTerm: searchTerm.lowercaseString,
- completionHandler: { [unowned sortOperation] (results) in
- sortOperation.results += results
- })
-
- addOperation(operation)
- sortOperation.addDependency(operation)
- }
-
- addOperation(sortOperation)
-
- addCondition(MutuallyExclusive())
- }
-
- override func operationDidFinish(errors: [ErrorType]) {
- NSOperationQueue.mainQueue().addOperationWithBlock {
- self.completionHandler(self.cancelled ? nil : self.results)
- }
- }
-}
-
-private class SingleBookSearchOperation: Operation {
- let zimReader: ZimReader
- let lowerCaseSearchTerm: String
- let completionHandler: ([SearchResult]) -> Void
-
- init(zimReader: ZimReader, lowerCaseSearchTerm: String, completionHandler: ([SearchResult]) -> Void) {
- self.zimReader = zimReader
- self.lowerCaseSearchTerm = lowerCaseSearchTerm
- self.completionHandler = completionHandler
- super.init()
- }
-
- override private func execute() {
- var results = [String: SearchResult]()
- let indexedDics = zimReader.searchUsingIndex(lowerCaseSearchTerm) as? [[String: AnyObject]] ?? [[String: AnyObject]]()
- let titleDics = zimReader.searchSuggestionsSmart(lowerCaseSearchTerm) as? [[String: AnyObject]] ?? [[String: AnyObject]]()
- let mixedDics = titleDics + indexedDics // It is important we process the title search result first, so that we always keep the indexed search result
- for dic in mixedDics {
- guard let result = SearchResult (rawResult: dic, lowerCaseSearchTerm: lowerCaseSearchTerm) else {continue}
- results[result.path] = result
- }
- completionHandler(Array(results.values))
- finish()
- }
-}
-
-private class SortSearchResultsOperation: Operation {
- let completionHandler: ([SearchResult]) -> Void
- var results = [SearchResult]()
-
- init(completionHandler: ([SearchResult]) -> Void) {
- self.completionHandler = completionHandler
- super.init()
- }
-
- override private func execute() {
- sort()
- completionHandler(results)
- finish()
- }
-
- private func sort() {
- results.sortInPlace { (result0, result1) -> Bool in
- if result0.score != result1.score {
- return result0.score < result1.score
- } else {
- if result0.snippet != nil {return true}
- if result1.snippet != nil {return false}
- return titleCaseInsensitiveCompare(result0, result1: result1)
- }
- }
- }
-
- // MARK: - Utilities
-
- private func titleCaseInsensitiveCompare(result0: SearchResult, result1: SearchResult) -> Bool {
- return result0.title.caseInsensitiveCompare(result1.title) == NSComparisonResult.OrderedAscending
- }
-}
-
diff --git a/Kiwix/Operations/SearchOperation.swift b/Kiwix/Operations/SearchOperation.swift
index 9c91c0f0..6f7f5984 100644
--- a/Kiwix/Operations/SearchOperation.swift
+++ b/Kiwix/Operations/SearchOperation.swift
@@ -9,7 +9,72 @@
import Operations
class SearchOperation: GroupOperation {
+ private(set) var results = [SearchResult]()
+
init(searchTerm: String) {
- super.init(operations: [])
+ let searches: [BookSearch] = ZimMultiReader.shared.readers.keys.map({ BookSearch(zimID: $0, searchTerm: searchTerm) })
+ let sort = Sort()
+ searches.forEach { (search) in
+ sort.injectResultFromDependency(search, block: { (operation, dependency, errors) in
+ operation.requirement += dependency.results
+ })
+ }
+ super.init(operations: searches + [sort])
+
+ sort.addObserver(DidFinishObserver { [unowned self] (operation, errors) in
+ guard let operation = operation as? Sort else {return}
+ self.results = operation.requirement
+ })
+ }
+}
+
+private class BookSearch: Operation {
+ let zimID: String
+ let searchTerm: String
+ private var results = [SearchResult]()
+
+ init(zimID: String, searchTerm: String) {
+ self.zimID = zimID
+ self.searchTerm = searchTerm
+ super.init()
+ }
+
+ override private func execute() {
+ guard let reader = ZimMultiReader.shared.readers[zimID] else {return}
+
+ let indexedDics = reader.searchUsingIndex(searchTerm) as? [[String: AnyObject]] ?? [[String: AnyObject]]()
+ let titleDics = reader.searchSuggestionsSmart(searchTerm) as? [[String: AnyObject]] ?? [[String: AnyObject]]()
+ let mixedDics = titleDics + indexedDics // It is important we process the title search result first, so that we always keep the indexed search result
+
+ for dic in mixedDics {
+ guard let result = SearchResult (rawResult: dic, lowerCaseSearchTerm: searchTerm) else {continue}
+ self.results.append(result)
+ }
+ finish()
+ }
+}
+
+private class Sort: Operation, AutomaticInjectionOperationType {
+ var requirement = [SearchResult]()
+
+ private override func execute() {
+ sort()
+ finish()
+ }
+
+ private func sort() {
+ requirement.sortInPlace { (result0, result1) -> Bool in
+ if result0.score != result1.score {
+ return result0.score < result1.score
+ } else {
+ if result0.snippet != nil {return true}
+ if result1.snippet != nil {return false}
+ return titleCaseInsensitiveCompare(result0, result1: result1)
+ }
+ }
+ }
+
+ private func titleCaseInsensitiveCompare(result0: SearchResult, result1: SearchResult) -> Bool {
+ return result0.title.caseInsensitiveCompare(result1.title) == NSComparisonResult.OrderedAscending
}
}