mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-27 13:59:04 -04:00
parent
c755738a35
commit
a3e1617632
@ -47,6 +47,7 @@
|
||||
97533B461F4C723900F6651A /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97533B451F4C723900F6651A /* MainWindowController.swift */; };
|
||||
97598E09202B60E0005A9055 /* BackupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97598E08202B60E0005A9055 /* BackupManager.swift */; };
|
||||
97598E0A202B60E0005A9055 /* BackupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97598E08202B60E0005A9055 /* BackupManager.swift */; };
|
||||
975F97A820D00EAE0005D642 /* SettingSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975F97A720D00EAE0005D642 /* SettingSearchController.swift */; };
|
||||
975FDADA1F6082DA00A10E8C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975FDAD91F6082DA00A10E8C /* AppDelegate.swift */; };
|
||||
975FDAE41F6082DA00A10E8C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 975FDAE21F6082DA00A10E8C /* LaunchScreen.storyboard */; };
|
||||
975FDAF51F608A2200A10E8C /* URLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767717D1F437BB9007ED0C2 /* URLProtocol.swift */; };
|
||||
@ -67,6 +68,7 @@
|
||||
977D7BB91F9E6A43009A8703 /* ZimMultiReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977D7BB31F9E6A43009A8703 /* ZimMultiReader.swift */; };
|
||||
977D7BBE1F9FC618009A8703 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977D7BBD1F9FC618009A8703 /* Queue.swift */; };
|
||||
977D7BBF1F9FC618009A8703 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977D7BBD1F9FC618009A8703 /* Queue.swift */; };
|
||||
977ED8C820BD9BCB009A2FB2 /* MapController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977ED8C720BD9BCB009A2FB2 /* MapController.swift */; };
|
||||
977F983E1F9E43EC002ABFCE /* ScanProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977F983D1F9E43EC002ABFCE /* ScanProcedure.swift */; };
|
||||
977F983F1F9E43EC002ABFCE /* ScanProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977F983D1F9E43EC002ABFCE /* ScanProcedure.swift */; };
|
||||
979D6E0C20B34FD700B08DE7 /* BookmarkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979D6E0B20B34FD700B08DE7 /* BookmarkController.swift */; };
|
||||
@ -168,6 +170,7 @@
|
||||
97F4D10620AB80740038FC87 /* LibraryZimFileDetailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F4D10520AB80740038FC87 /* LibraryZimFileDetailController.swift */; };
|
||||
97F4D10A20ADD0F00038FC87 /* DownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F4D10920ADD0F00038FC87 /* DownloadManager.swift */; };
|
||||
97F4D10C20ADFE370038FC87 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97F4D10B20ADFE370038FC87 /* Assets.xcassets */; };
|
||||
97F6CC5120BD960F005CDBD2 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97F6CC5020BD960F005CDBD2 /* MapKit.framework */; };
|
||||
DFD371610877B5817E9C9FEB /* Pods_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81DF90AB14037E242E284CA8 /* Pods_macOS.framework */; };
|
||||
FA1E975E797443400EBF3EE8 /* Pods_WikiMed.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14995D226EC82CFFBBB5B159 /* Pods_WikiMed.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
@ -266,6 +269,7 @@
|
||||
975415D31F54C1870007EA6C /* SearchProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchProcedure.swift; sourceTree = "<group>"; };
|
||||
97598E08202B60E0005A9055 /* BackupManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupManager.swift; sourceTree = "<group>"; };
|
||||
9759D4211F4F278800705779 /* Kiwix.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Kiwix.entitlements; sourceTree = "<group>"; };
|
||||
975F97A720D00EAE0005D642 /* SettingSearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingSearchController.swift; sourceTree = "<group>"; };
|
||||
975FDAD91F6082DA00A10E8C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
975FDAE31F6082DA00A10E8C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
975FDAE51F6082DA00A10E8C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -285,6 +289,7 @@
|
||||
977D7BB21F9E6A43009A8703 /* ZimMultiReader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ZimMultiReader.mm; sourceTree = "<group>"; };
|
||||
977D7BB31F9E6A43009A8703 /* ZimMultiReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZimMultiReader.swift; sourceTree = "<group>"; };
|
||||
977D7BBD1F9FC618009A8703 /* Queue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = "<group>"; };
|
||||
977ED8C720BD9BCB009A2FB2 /* MapController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapController.swift; sourceTree = "<group>"; };
|
||||
977F983D1F9E43EC002ABFCE /* ScanProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanProcedure.swift; sourceTree = "<group>"; };
|
||||
9780DE051E43BFF5009B6945 /* NetworkActivityIndicatorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkActivityIndicatorController.swift; sourceTree = "<group>"; };
|
||||
979315811E5127930093D3BA /* Kiwix.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kiwix.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -624,6 +629,7 @@
|
||||
97F4D10520AB80740038FC87 /* LibraryZimFileDetailController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryZimFileDetailController.swift; sourceTree = "<group>"; };
|
||||
97F4D10920ADD0F00038FC87 /* DownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadManager.swift; sourceTree = "<group>"; };
|
||||
97F4D10B20ADFE370038FC87 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97F6CC5020BD960F005CDBD2 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
|
||||
C6EB8B17B86590EA06112D8C /* Pods-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-macOS/Pods-macOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
C93DC28B91BE9E73AFC06E16 /* Pods-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-iOS/Pods-iOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||
DB2AE49B95B84C6AAA4C6A80 /* Pods-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-macOS/Pods-macOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@ -685,6 +691,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
97F6CC5120BD960F005CDBD2 /* MapKit.framework in Frameworks */,
|
||||
97C575F4202CB0E800E37502 /* NotificationCenter.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -695,6 +702,7 @@
|
||||
3B93EAF9B5C5AA23046BDEAC /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97F6CC5020BD960F005CDBD2 /* MapKit.framework */,
|
||||
97A6882F207D40F500DBBE0D /* Pods_iOS.framework */,
|
||||
975FDB061F608F4100A10E8C /* WebKit.framework */,
|
||||
2E854211810A39173DD6A5BD /* Pods_iOS.framework */,
|
||||
@ -736,6 +744,7 @@
|
||||
9763EDC8201FCA6900F3A6D5 /* SettingWebController.swift */,
|
||||
97A2180B2024EC3800D1E67B /* SettingFontSizeViewController.swift */,
|
||||
97BAA541202B4C5E00500644 /* SettingBackupController.swift */,
|
||||
975F97A720D00EAE0005D642 /* SettingSearchController.swift */,
|
||||
97DBCF9C203CA254004EE274 /* SettingExternalLinkControllerTableViewController.swift */,
|
||||
);
|
||||
path = Setting;
|
||||
@ -823,7 +832,8 @@
|
||||
97028C4E20192F65001259CB /* TableOfContentController.swift */,
|
||||
97252102200D3C4B00B60A80 /* HUDController.swift */,
|
||||
972B6661200808D6003F5365 /* WelcomeController.swift */,
|
||||
97C99B45205AF58D00439C77 /* Main */,
|
||||
977ED8C720BD9BCB009A2FB2 /* MapController.swift */,
|
||||
97C99B47205AF58D00439C77 /* MainController.swift */,
|
||||
97050CFF1F6730010021DE78 /* Tab */,
|
||||
972E6F651FA2872A00F5C927 /* Search */,
|
||||
97B1046D1F8FC61400488444 /* Library */,
|
||||
@ -1012,14 +1022,6 @@
|
||||
path = Migration;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C99B45205AF58D00439C77 /* Main */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C99B47205AF58D00439C77 /* MainController.swift */,
|
||||
);
|
||||
path = Main;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97CA45D3209BB247008CEA6D /* ZimFileProcessing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1844,6 +1846,7 @@
|
||||
97CA45D2209BB23F008CEA6D /* ZimFileProcessingProcedure.swift in Sources */,
|
||||
97A6882E207D3DE300DBBE0D /* ZimFile.swift in Sources */,
|
||||
971B8E58202246ED00C5C939 /* RecentSearchCells.swift in Sources */,
|
||||
975F97A820D00EAE0005D642 /* SettingSearchController.swift in Sources */,
|
||||
97242E162093A9AC00AA4436 /* Bookmark.swift in Sources */,
|
||||
97D00A7F1FBB92D400165629 /* TableOfContentItem.swift in Sources */,
|
||||
97A5C1412089115D009CA5F9 /* SearchResultContainerController.swift in Sources */,
|
||||
@ -1861,6 +1864,7 @@
|
||||
97A36C321F8C21210079B452 /* AppDelegate.swift in Sources */,
|
||||
979FD159201679C5007B5290 /* SearchResultsListController.swift in Sources */,
|
||||
972B66602007F9F7003F5365 /* WebKitWebController.swift in Sources */,
|
||||
977ED8C820BD9BCB009A2FB2 /* MapController.swift in Sources */,
|
||||
97C57638202CB86800E37502 /* Article.swift in Sources */,
|
||||
9763EDC9201FCA6900F3A6D5 /* SettingWebController.swift in Sources */,
|
||||
97AC121320878F8B004779D1 /* SearchResultController.swift in Sources */,
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "0940"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
|
@ -129,7 +129,7 @@ class DownloadManager: NSObject, URLSessionDelegate, URLSessionTaskDelegate, URL
|
||||
session.getTasksWithCompletionHandler { (_, _, downloadTasks) in
|
||||
guard let task = downloadTasks.filter({$0.taskDescription == taskDescription}).first else {return}
|
||||
if producingResumingData {
|
||||
task.cancel(byProducingResumeData: {data in Preference.resumeData[taskDescription] = data })
|
||||
task.cancel(byProducingResumeData: {data in })
|
||||
} else {
|
||||
task.cancel()
|
||||
}
|
||||
|
@ -38,12 +38,6 @@ class Preference {
|
||||
set{Defaults[.langFilterNameDisplayInOriginalLocale] = newValue}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Resume Data
|
||||
|
||||
class var resumeData: [String: Data] {
|
||||
get{return Defaults[DefaultsKeys.resumeData] as? [String: Data] ?? [String: Data]()}
|
||||
set{Defaults[DefaultsKeys.resumeData] = newValue}}
|
||||
}
|
||||
|
||||
extension DefaultsKeys {
|
||||
@ -68,7 +62,7 @@ extension DefaultsKeys {
|
||||
static let langFilterSortByAlphabeticalAsc = DefaultsKey<Bool>("langFilterSortByAlphabeticalAsc")
|
||||
static let langFilterNameDisplayInOriginalLocale = DefaultsKey<Bool>("langFilterNameDisplayInOriginalLocale")
|
||||
|
||||
static let resumeData = DefaultsKey<[String: Any]>("resumeData")
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Rate
|
||||
|
@ -11,13 +11,15 @@ import ProcedureKit
|
||||
class SearchProcedure: Procedure {
|
||||
let searchText: String
|
||||
let ids: Set<ZimFileID>
|
||||
let extractSnippet: Bool
|
||||
|
||||
private var results = Set<SearchResult>()
|
||||
private(set) var sortedResults: [SearchResult] = []
|
||||
|
||||
init(term: String, ids: Set<ZimFileID> = Set()) {
|
||||
init(term: String, ids: Set<ZimFileID> = Set(), extractSnippet: Bool) {
|
||||
self.searchText = term
|
||||
self.ids = ids.count == 0 ? Set(ZimMultiReader.shared.ids) : ids
|
||||
self.extractSnippet = extractSnippet
|
||||
super.init()
|
||||
name = "Search Procedure"
|
||||
}
|
||||
@ -33,7 +35,7 @@ class SearchProcedure: Procedure {
|
||||
private func addIndexedSearchResults() {
|
||||
guard !isCancelled else { ZimMultiReader.shared.stopIndexSearch(); return }
|
||||
ZimMultiReader.shared.startIndexSearch(searchText: searchText, zimFileIDs: ids)
|
||||
while let result = ZimMultiReader.shared.getNextIndexSearchResult() {
|
||||
while let result = ZimMultiReader.shared.getNextIndexSearchResult(extractSnippet: extractSnippet) {
|
||||
guard !isCancelled else { ZimMultiReader.shared.stopIndexSearch(); return }
|
||||
results.insert(result)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import ProcedureKit
|
||||
import SwiftyUserDefaults
|
||||
|
||||
class SearchQueue: ProcedureQueue, ProcedureQueueDelegate {
|
||||
weak var eventDelegate: SearchQueueEvents?
|
||||
@ -18,7 +19,7 @@ class SearchQueue: ProcedureQueue, ProcedureQueueDelegate {
|
||||
}
|
||||
|
||||
func enqueue(searchText: String, zimFileIDs: Set<ZimFileID>) {
|
||||
let procedure = SearchProcedure(term: searchText, ids: zimFileIDs)
|
||||
let procedure = SearchProcedure(term: searchText, ids: zimFileIDs, extractSnippet: !Defaults[.searchResultExcludeSnippet])
|
||||
add(operation: procedure)
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
- (NSString *_Nullable)getMainPagePath:(NSString *_Nonnull)bookID NS_REFINED_FOR_SWIFT;
|
||||
|
||||
- (void)startIndexSearch:(NSString *_Nonnull)searchText zimFileIDs:(NSSet *_Nonnull)zimFileIDs NS_REFINED_FOR_SWIFT;
|
||||
- (NSDictionary *_Nullable)getNextIndexSearchResult NS_REFINED_FOR_SWIFT;
|
||||
- (NSDictionary *_Nullable)getNextIndexSearchResultWithSnippet:(BOOL)extractSnippet NS_REFINED_FOR_SWIFT;
|
||||
- (void)stopIndexSearch;
|
||||
- (NSArray *_Nonnull)getTitleSearchResults:(NSString *_Nonnull)searchText zimFileID:(NSString *_Nullable)zimFileID count:(unsigned int)count NS_REFINED_FOR_SWIFT;
|
||||
|
||||
|
@ -217,7 +217,7 @@ NSMutableDictionary *fileURLs = [[NSMutableDictionary alloc] init]; // [ID: File
|
||||
}
|
||||
}
|
||||
|
||||
# pragma mark - Search
|
||||
# pragma mark - Text Search
|
||||
|
||||
- (void)startIndexSearch:(NSString *)searchText zimFileIDs:(NSSet *)zimFileIDs {
|
||||
std::string searchTextC = [searchText cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
@ -250,26 +250,31 @@ NSMutableDictionary *fileURLs = [[NSMutableDictionary alloc] init]; // [ID: File
|
||||
searcher->search(searchTextC, 0, 20);
|
||||
}
|
||||
|
||||
- (NSDictionary *)convertSearchResultWithIndentifier:(NSString *)identifier result:(kiwix::Result *)result {
|
||||
- (NSDictionary *)convertSearchResultWithIndentifier:(NSString *)identifier result:(kiwix::Result *)result extractSnippet:(BOOL)extractSnippet {
|
||||
NSString *title = [NSString stringWithCString:result->get_title().c_str() encoding:NSUTF8StringEncoding];
|
||||
NSString *path = [NSString stringWithCString:result->get_url().c_str() encoding:NSUTF8StringEncoding];
|
||||
NSNumber *probability = [[NSNumber alloc] initWithDouble:(double)result->get_score() / double(100)];
|
||||
NSString *snippet = [NSString stringWithCString:result->get_snippet().c_str() encoding:NSUTF8StringEncoding];
|
||||
NSString *snippet = @"";
|
||||
|
||||
if (extractSnippet) {
|
||||
snippet = [NSString stringWithCString:result->get_snippet().c_str() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
delete result;
|
||||
return @{@"id": identifier, @"title": title, @"path": path, @"probability": probability, @"snippet": snippet};
|
||||
}
|
||||
|
||||
- (NSDictionary *)getNextIndexSearchResult {
|
||||
- (NSDictionary *)getNextIndexSearchResultWithSnippet:(BOOL)extractSnippet {
|
||||
kiwix::Result *result = searcher->getNextResult();
|
||||
if (result != NULL) {
|
||||
NSString *identifier = searcherZimIDs[result->get_readerIndex()];
|
||||
return [self convertSearchResultWithIndentifier:identifier result:result];
|
||||
return [self convertSearchResultWithIndentifier:identifier result:result extractSnippet:extractSnippet];
|
||||
} else {
|
||||
for(auto iter: externalSearchers) {
|
||||
NSString *identifier = [NSString stringWithCString:iter.first.c_str() encoding:NSUTF8StringEncoding];
|
||||
result = iter.second->getNextResult();
|
||||
if (result != NULL) {
|
||||
return [self convertSearchResultWithIndentifier:identifier result:result];
|
||||
return [self convertSearchResultWithIndentifier:identifier result:result extractSnippet:extractSnippet];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
@ -308,4 +313,7 @@ NSMutableDictionary *fileURLs = [[NSMutableDictionary alloc] init]; // [ID: File
|
||||
}
|
||||
}
|
||||
|
||||
# pragma mark - Geo Search
|
||||
|
||||
|
||||
@end
|
||||
|
@ -45,8 +45,8 @@ extension ZimMultiReader {
|
||||
__startIndexSearch(searchText, zimFileIDs: zimFileIDs)
|
||||
}
|
||||
|
||||
func getNextIndexSearchResult() -> SearchResult? {
|
||||
guard let result = __getNextIndexSearchResult() as? Dictionary<String, Any>,
|
||||
func getNextIndexSearchResult(extractSnippet: Bool) -> SearchResult? {
|
||||
guard let result = __getNextIndexSearchResult(withSnippet: extractSnippet) as? Dictionary<String, Any>,
|
||||
let id = result["id"] as? String,
|
||||
let path = result["path"] as? String,
|
||||
let title = result["title"] as? String else {return nil}
|
||||
|
@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.9.1</string>
|
||||
<string>1.9.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>18</string>
|
||||
<string>21</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
|
@ -33,7 +33,7 @@ class TodayViewController: UIViewController, NCWidgetProviding, UICollectionView
|
||||
|
||||
func getBookmarks() -> [(title: String, url: String, thumbImageData: Data)] {
|
||||
return UserDefaults(suiteName: "group.kiwix")?.array(forKey: "bookmarks")?
|
||||
.flatMap({ $0 as? [String: Any] }).flatMap({ (bookmark) -> (title: String, url: String, thumbImageData: Data)? in
|
||||
.compactMap({ $0 as? [String: Any] }).compactMap({ (bookmark) -> (title: String, url: String, thumbImageData: Data)? in
|
||||
guard let title = bookmark["title"] as? String,
|
||||
let url = bookmark["url"] as? String,
|
||||
let thumbImageData = bookmark["thumbImageData"] as? Data else {return nil}
|
||||
|
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
import NotificationCenter
|
||||
import RealmSwift
|
||||
import SwiftyUserDefaults
|
||||
@ -143,6 +144,17 @@ extension MainController: WebViewControllerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func webViewDidTapOnGeoLocation(controller: WebViewController, url: URL) {
|
||||
// guard let components = URLComponents(string: url.absoluteString) else {return}
|
||||
// let parts = components.path.split(separator: ",")
|
||||
// guard parts.count == 2, let latitude = CLLocationDegrees(parts[0]), let longitude = CLLocationDegrees(parts[1]) else {return}
|
||||
// let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
|
||||
//
|
||||
// let mapController = MapController(coordinate: coordinate, title: controller.currentTitle)
|
||||
// let navigationController = UINavigationController(rootViewController: mapController)
|
||||
// self.navigationController?.present(navigationController, animated: true)
|
||||
}
|
||||
|
||||
func webViewDidFinishLoading(controller: WebViewController) {
|
||||
navigationBackButtonItem.button.isEnabled = controller.canGoBack
|
||||
navigationForwardButtonItem.button.isEnabled = controller.canGoForward
|
45
iOS/Controller/MapController.swift
Normal file
45
iOS/Controller/MapController.swift
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// MapController.swift
|
||||
// iOS
|
||||
//
|
||||
// Created by Chris Li on 5/29/18.
|
||||
// Copyright © 2018 Chris Li. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
class MapController: UIViewController {
|
||||
let coordinate: CLLocationCoordinate2D
|
||||
private let mapView = MKMapView()
|
||||
|
||||
init(coordinate: CLLocationCoordinate2D, title: String?) {
|
||||
self.coordinate = coordinate
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
self.title = title
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
view = mapView
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissController))
|
||||
|
||||
let region = MKCoordinateRegion(center: self.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
|
||||
mapView.setRegion(region, animated: false)
|
||||
let annotation = MKPointAnnotation()
|
||||
annotation.coordinate = self.coordinate
|
||||
annotation.title = title
|
||||
mapView.addAnnotation(annotation)
|
||||
}
|
||||
|
||||
@objc func dismissController() {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
}
|
@ -22,19 +22,9 @@ class SettingNavigationController: UINavigationController {
|
||||
|
||||
class SettingController: UIViewController, UITableViewDataSource, UITableViewDelegate {
|
||||
let tableView = UITableView(frame: .zero, style: .grouped)
|
||||
let titles: [SettingMenuItem: String] = {
|
||||
var titles = [SettingMenuItem: String]()
|
||||
titles[.fontSize] = NSLocalizedString("Font Size", comment: "Setting Item Title")
|
||||
titles[.backup] = NSLocalizedString("Backup", comment: "Setting Item Title")
|
||||
titles[.externalLink] = NSLocalizedString("External Link", comment: "Setting Item Title")
|
||||
titles[.feedback] = NSLocalizedString("Email us your suggestions", comment: "Setting Item Title")
|
||||
titles[.rateApp] = NSLocalizedString("Give Kiwix a rate", comment: "Setting Item Title")
|
||||
titles[.about] = NSLocalizedString("About", comment: "Setting Item Title")
|
||||
return titles
|
||||
}()
|
||||
private let items: [[SettingMenuItem]] = {
|
||||
var items: [[SettingMenuItem]] = [
|
||||
[.fontSize, .backup, .externalLink],
|
||||
private let items: [[MenuItem]] = {
|
||||
var items: [[MenuItem]] = [
|
||||
[.fontSize, .backup, .search, .externalLink],
|
||||
[.rateApp],
|
||||
[.about]
|
||||
]
|
||||
@ -79,7 +69,7 @@ class SettingController: UIViewController, UITableViewDataSource, UITableViewDel
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
|
||||
let item = items[indexPath.section][indexPath.row]
|
||||
cell.textLabel?.text = titles[item]
|
||||
cell.textLabel?.text = item.description
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
return cell
|
||||
}
|
||||
@ -105,21 +95,23 @@ class SettingController: UIViewController, UITableViewDataSource, UITableViewDel
|
||||
switch item {
|
||||
case .fontSize:
|
||||
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SettingFontSizeViewController")
|
||||
controller.title = titles[item]
|
||||
controller.title = item.description
|
||||
navigationController?.pushViewController(controller, animated: true)
|
||||
case.backup:
|
||||
navigationController?.pushViewController(SettingBackupController(title: titles[item]), animated: true)
|
||||
navigationController?.pushViewController(SettingBackupController(title: item.description), animated: true)
|
||||
case .externalLink:
|
||||
navigationController?.pushViewController(SettingExternalLinkController(title: titles[item]), animated: true)
|
||||
navigationController?.pushViewController(SettingExternalLinkController(title: item.description), animated: true)
|
||||
case .search:
|
||||
navigationController?.pushViewController(SettingSearchController(title: item.description), animated: true)
|
||||
case .feedback:
|
||||
presentFeedbackEmailComposer()
|
||||
case .rateApp:
|
||||
presentRateAppAlert(title: titles[item]!)
|
||||
presentRateAppAlert(title: item.description)
|
||||
case .about:
|
||||
guard let path = Bundle.main.path(forResource: "About", ofType: "html") else {return}
|
||||
let url = URL(fileURLWithPath: path)
|
||||
let controller = SettingWebController(fileURL: url)
|
||||
controller.title = titles[item]
|
||||
controller.title = item.description
|
||||
navigationController?.pushViewController(controller, animated: true)
|
||||
}
|
||||
}
|
||||
@ -139,6 +131,33 @@ class SettingController: UIViewController, UITableViewDataSource, UITableViewDel
|
||||
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Type Definition
|
||||
|
||||
enum MenuItem: CustomStringConvertible {
|
||||
case fontSize, backup, externalLink, search
|
||||
case feedback, rateApp
|
||||
case about
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .fontSize:
|
||||
return NSLocalizedString("Font Size", comment: "Setting Item Title")
|
||||
case .backup:
|
||||
return NSLocalizedString("Backup", comment: "Setting Item Title")
|
||||
case .externalLink:
|
||||
return NSLocalizedString("External Link", comment: "Setting Item Title")
|
||||
case .search:
|
||||
return NSLocalizedString("Search", comment: "Setting Item Title")
|
||||
case .feedback:
|
||||
return NSLocalizedString("Email us your suggestions", comment: "Setting Item Title")
|
||||
case .rateApp:
|
||||
return NSLocalizedString("Give Kiwix a rate", comment: "Setting Item Title")
|
||||
case .about:
|
||||
return NSLocalizedString("About", comment: "Setting Item Title")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SettingController: MFMailComposeViewControllerDelegate {
|
||||
@ -172,9 +191,3 @@ extension SettingController: MFMailComposeViewControllerDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SettingMenuItem {
|
||||
case fontSize, backup, externalLink
|
||||
case feedback, rateApp
|
||||
case about
|
||||
}
|
||||
|
68
iOS/Controller/Setting/SettingSearchController.swift
Normal file
68
iOS/Controller/Setting/SettingSearchController.swift
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// SettingSearchController.swift
|
||||
// iOS
|
||||
//
|
||||
// Created by Chris Li on 6/12/18.
|
||||
// Copyright © 2018 Chris Li. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftyUserDefaults
|
||||
|
||||
class SettingSearchController: UIViewController, UITableViewDataSource, UITableViewDelegate {
|
||||
let tableView = UITableView(frame: .zero, style: .grouped)
|
||||
|
||||
init(title: String) {
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
self.title = title
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
view = tableView
|
||||
tableView.dataSource = self
|
||||
tableView.delegate = self
|
||||
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
|
||||
}
|
||||
|
||||
@objc func switchValueChanged(switchControl: UISwitch) {
|
||||
Defaults[.searchResultExcludeSnippet] = !switchControl.isOn
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDataSource & Delegate
|
||||
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
|
||||
cell.textLabel?.text = NSLocalizedString("Snippet", comment: "Setting: Search")
|
||||
cell.selectionStyle = .none
|
||||
let switchControl = UISwitch()
|
||||
switchControl.addTarget(self, action: #selector(switchValueChanged(switchControl:)), for: .valueChanged)
|
||||
switchControl.isOn = !Defaults[.searchResultExcludeSnippet]
|
||||
cell.accessoryView = switchControl
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
return NSLocalizedString("Search Result", comment: "Setting: Search")
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
||||
return NSLocalizedString("If search performance issue is encountered, disable snippets to improve the situation.", comment: "Setting: Search")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension DefaultsKeys {
|
||||
static let searchResultExcludeSnippet = DefaultsKey<Bool>("searchResultExcludeSnippet")
|
||||
}
|
@ -125,6 +125,7 @@ class LegacyWebController: UIViewController, UIWebViewDelegate, WebViewControlle
|
||||
}
|
||||
return false
|
||||
} else if url.scheme == "geo" {
|
||||
delegate?.webViewDidTapOnGeoLocation(controller: self, url: url)
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
|
@ -131,7 +131,7 @@ class WebKitWebController: UIViewController, WKUIDelegate, WKNavigationDelegate,
|
||||
}
|
||||
decisionHandler(.cancel)
|
||||
} else if url.scheme == "geo" {
|
||||
// show map
|
||||
delegate?.webViewDidTapOnGeoLocation(controller: self, url: url)
|
||||
decisionHandler(.cancel)
|
||||
} else {
|
||||
decisionHandler(.cancel)
|
||||
|
@ -27,6 +27,7 @@ protocol WebViewController {
|
||||
}
|
||||
|
||||
protocol WebViewControllerDelegate: class {
|
||||
func webViewDidTapOnGeoLocation(controller: WebViewController, url: URL)
|
||||
func webViewDidFinishLoading(controller: WebViewController)
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.9.1</string>
|
||||
<string>1.9.2</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
@ -30,7 +30,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>18</string>
|
||||
<string>21</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
Loading…
x
Reference in New Issue
Block a user