diff --git a/Kiwix-iOS/Controller/SettingTBVC.swift b/Kiwix-iOS/Controller/SettingTBVC.swift index 4ba7bb2d..9d551a8a 100644 --- a/Kiwix-iOS/Controller/SettingTBVC.swift +++ b/Kiwix-iOS/Controller/SettingTBVC.swift @@ -9,9 +9,10 @@ import UIKit class SettingTBVC: UITableViewController { - private(set) var sectionHeader = [LocalizedStrings.library, LocalizedStrings.reading,LocalizedStrings.misc] + private(set) var sectionHeader = [LocalizedStrings.library, LocalizedStrings.reading, LocalizedStrings.search, LocalizedStrings.misc] private(set) var cellTextlabels = [[LocalizedStrings.libraryAutoRefresh, LocalizedStrings.libraryUseCellularData, LocalizedStrings.libraryBackup], [LocalizedStrings.fontSize, LocalizedStrings.adjustLayout], + [LocalizedStrings.history], [LocalizedStrings.rateKiwix, LocalizedStrings.about]] let dateComponentsFormatter: NSDateComponentsFormatter = { @@ -27,8 +28,7 @@ class SettingTBVC: UITableViewController { showRateKiwixIfNeeded() if UIApplication.buildStatus == .Alpha { - sectionHeader.append("Search") - cellTextlabels.append(["Boost Factor 🚀"]) + cellTextlabels[2].append("Boost Factor 🚀") } } diff --git a/Kiwix-iOS/Controller/TableOfContentsController.swift b/Kiwix-iOS/Controller/TableOfContentsController.swift index abbd3635..2a2a745d 100644 --- a/Kiwix-iOS/Controller/TableOfContentsController.swift +++ b/Kiwix-iOS/Controller/TableOfContentsController.swift @@ -9,7 +9,7 @@ import UIKit import DZNEmptyDataSet -class TableOfContentsController: UIViewController, UITableViewDelegate, UITableViewDataSource ,DZNEmptyDataSetSource, DZNEmptyDataSetDelegate { +class TableOfContentsController: UIViewController, UITableViewDelegate, UITableViewDataSource, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate { @IBOutlet weak var tableView: UITableView! weak var delegate: TableOfContentsDelegate? diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist index 18e1850f..5d37c1cc 100644 --- a/Kiwix-iOS/Info.plist +++ b/Kiwix-iOS/Info.plist @@ -36,7 +36,7 @@ CFBundleSignature ???? CFBundleVersion - 1.6.1529 + 1.6.1563 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/Kiwix-iOS/iOSExtensions.swift b/Kiwix-iOS/iOSExtensions.swift index 34db4a4d..58b46d7c 100644 --- a/Kiwix-iOS/iOSExtensions.swift +++ b/Kiwix-iOS/iOSExtensions.swift @@ -42,7 +42,7 @@ enum BuildStatus { extension UIApplication { class var buildStatus: BuildStatus { get { - return .Alpha + return .Beta } } } diff --git a/Kiwix/Operations/SearchOperation.swift b/Kiwix/Operations/SearchOperation.swift index 23e6be87..1894186a 100644 --- a/Kiwix/Operations/SearchOperation.swift +++ b/Kiwix/Operations/SearchOperation.swift @@ -12,6 +12,7 @@ import PSOperations 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 @@ -26,7 +27,7 @@ class SearchOperation: GroupOperation { guard let book = Book.fetch(id, context: managedObjectContext) else {continue} guard book.includeInSearch else {continue} let operation = SingleBookSearchOperation(zimReader: zimReader, - searchTerm: searchTerm.lowercaseString, + lowerCaseSearchTerm: searchTerm.lowercaseString, completionHandler: { [unowned sortOperation] (results) in sortOperation.results += results }) @@ -41,7 +42,7 @@ class SearchOperation: GroupOperation { } override func finished(errors: [NSError]) { -// print("Search Operation finished, status \(cancelled ? "Canceled" : "Not Canceled")") + //print("Search Operation finished, status \(cancelled ? "Canceled" : "Not Canceled"), \(NSDate().timeIntervalSinceDate(startTime))") NSOperationQueue.mainQueue().addOperationWithBlock { self.completionHandler(self.cancelled ? nil : self.results) } @@ -50,22 +51,22 @@ class SearchOperation: GroupOperation { private class SingleBookSearchOperation: Operation { let zimReader: ZimReader - let searchTerm: String + let lowerCaseSearchTerm: String let completionHandler: ([SearchResult]) -> Void - init(zimReader: ZimReader, searchTerm: String, completionHandler: ([SearchResult]) -> Void) { + init(zimReader: ZimReader, lowerCaseSearchTerm: String, completionHandler: ([SearchResult]) -> Void) { self.zimReader = zimReader - self.searchTerm = searchTerm + self.lowerCaseSearchTerm = lowerCaseSearchTerm self.completionHandler = completionHandler } override private func execute() { var results = [String: SearchResult]() - let indexedDics = zimReader.searchUsingIndex(searchTerm) as? [[String: AnyObject]] ?? [[String: AnyObject]]() - let titleDics = zimReader.searchSuggestionsSmart(searchTerm) as? [[String: AnyObject]] ?? [[String: AnyObject]]() + 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) else {continue} + guard let result = SearchResult (rawResult: dic, lowerCaseSearchTerm: lowerCaseSearchTerm) else {continue} results[result.path] = result } completionHandler(Array(results.values)) diff --git a/Kiwix/StringTools.swift b/Kiwix/StringTools.swift index 34ca10f8..c62958db 100644 --- a/Kiwix/StringTools.swift +++ b/Kiwix/StringTools.swift @@ -63,6 +63,7 @@ class LocalizedStrings { class var remove: String {return NSLocalizedString("Remove", comment: "Basic")} class var delete: String {return NSLocalizedString("Delete", comment: "Basic")} class var refreshing: String {return NSLocalizedString("Refreshing...", comment: "Basic")} + class var history: String {return NSLocalizedString("History", comment: "Basic")} // MARK: - OS X class var General: String {return NSLocalizedString("General", comment: "OS X, Preference")} diff --git a/Kiwix/ZimMultiReader/ExtensionAndTypealias.swift b/Kiwix/ZimMultiReader/ExtensionAndTypealias.swift index 8f7ff807..76980da5 100644 --- a/Kiwix/ZimMultiReader/ExtensionAndTypealias.swift +++ b/Kiwix/ZimMultiReader/ExtensionAndTypealias.swift @@ -8,6 +8,9 @@ import UIKit +typealias ZimID = String +typealias ArticlePath = String + extension ZimReader { var metaData: [String: AnyObject] { var metadata = [String: AnyObject]() @@ -28,5 +31,46 @@ extension ZimReader { } } -typealias ZimID = String -typealias ArticlePath = String +// https://gist.github.com/adamyanalunas/69f6601fad6040686d300a1cdc20f500 +private extension String { + subscript(index: Int) -> Character { + return self[startIndex.advancedBy(index)] + } + + subscript(range: Range) -> String { + let start = startIndex.advancedBy(range.startIndex) + let end = startIndex.advancedBy(range.endIndex) + return self[start.. Int { + let (length, cmpLength) = (characters.count, cmpString.characters.count) + var matrix = Array( + count: cmpLength + 1, + repeatedValue: Array( + count: length + 1, + repeatedValue: 0 + ) + ) + + for m in 1..getNextSuggestion(titleC)) { NSString *title = [NSString stringWithUTF8String:titleC.c_str()]; NSString *path = [self pageURLFromTitle:title]; - NSNumber *distance = [NSNumber numberWithInteger:[self levenshteinDistance:searchTerm andString:title.lowercaseString]]; [results addObject:@{@"title": title, @"path": path, - @"bookID": bookID, - @"distance": distance}]; + @"bookID": bookID}]; } } return results; @@ -99,13 +97,11 @@ NSString *path = [NSString stringWithUTF8String:doc.get_data().c_str()]; NSString *title = [NSString stringWithUTF8String:doc.get_value(0).c_str()]; NSString *snippet = [NSString stringWithUTF8String:doc.get_value(1).c_str()]; - NSNumber *distance = [NSNumber numberWithInteger:[self levenshteinDistance:searchTerm andString:title.lowercaseString]]; NSDictionary *result = @{@"title": title, @"path": path, @"bookID": bookID, @"probability": percent, - @"distance": distance, @"snippet": snippet}; [results addObject:result]; } @@ -343,4 +339,10 @@ int levenshtein_distance(const std::string &s1, const std::string &s2) } } ++ (NSInteger)levenshtein:(NSString *)strA anotherString:(NSString *)strB { + const string str1 = [strA cStringUsingEncoding:NSUTF8StringEncoding]; + const string str2 = [strB cStringUsingEncoding:NSUTF8StringEncoding]; + return levenshtein_distance(str1, str2); +} + @end