mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-07 19:22:51 -04:00
Library loading defered
This commit is contained in:
parent
c9043bfa99
commit
99c99d7785
@ -216,12 +216,18 @@ struct RootView: View {
|
||||
}.task {
|
||||
switch AppType.current {
|
||||
case .kiwix:
|
||||
let perfLib = Performance()
|
||||
LibraryOperations.reopen {
|
||||
navigation.currentItem = .reading
|
||||
perfLib.measure("LibraryOperations.reopen")
|
||||
}
|
||||
let perf = Performance()
|
||||
LibraryOperations.scanDirectory(URL.documentDirectory)
|
||||
perf.measure("scanDirectory")
|
||||
LibraryOperations.applyFileBackupSetting()
|
||||
perf.measure("applyFileBackupSetting")
|
||||
DownloadService.shared.restartHeartbeatIfNeeded()
|
||||
perf.measure("restartHeartbeatIfNeeded")
|
||||
case let .custom(zimFileURL):
|
||||
LibraryOperations.open(url: zimFileURL) {
|
||||
ZimMigration.forCustomApps()
|
||||
|
36
Model/Utilities/Performance.swift
Normal file
36
Model/Utilities/Performance.swift
Normal file
@ -0,0 +1,36 @@
|
||||
// This file is part of Kiwix for iOS & macOS.
|
||||
//
|
||||
// Kiwix is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kiwix is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
import Foundation
|
||||
import QuartzCore
|
||||
|
||||
final class Performance {
|
||||
|
||||
private let id: UUID
|
||||
private var start: CFTimeInterval
|
||||
|
||||
init(id: UUID = UUID()) {
|
||||
self.id = id
|
||||
start = CACurrentMediaTime()
|
||||
}
|
||||
|
||||
func measure(_ msg: String) {
|
||||
print("\(msg) \(id): \((CACurrentMediaTime() - start) * 1000) ms")
|
||||
}
|
||||
|
||||
func reset() {
|
||||
start = CACurrentMediaTime()
|
||||
}
|
||||
}
|
54
Model/Utilities/PerformanceObjC.h
Normal file
54
Model/Utilities/PerformanceObjC.h
Normal file
@ -0,0 +1,54 @@
|
||||
// This file is part of Kiwix for iOS & macOS.
|
||||
//
|
||||
// Kiwix is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kiwix is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@interface PerformanceObjC : NSObject
|
||||
|
||||
@property (nonatomic, strong, readonly) NSUUID *id;
|
||||
@property (nonatomic, assign) CFTimeInterval start;
|
||||
|
||||
- (instancetype)initWithId:(NSUUID *)id;
|
||||
- (void)measure:(NSString *)msg;
|
||||
- (void)reset;
|
||||
|
||||
@end
|
||||
|
||||
@implementation PerformanceObjC
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithId:[NSUUID UUID]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithId:(NSUUID *)id {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_id = id;
|
||||
_start = CACurrentMediaTime();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)measure:(NSString *)msg {
|
||||
CFTimeInterval elapsedTime = (CACurrentMediaTime() - _start) * 1000;
|
||||
NSLog(@"%@ %@: %.2f ms", msg, _id.UUIDString, elapsedTime);
|
||||
}
|
||||
|
||||
- (void)reset {
|
||||
_start = CACurrentMediaTime();
|
||||
}
|
||||
|
||||
@end
|
@ -26,7 +26,8 @@
|
||||
|
||||
#pragma mark - Reader Management
|
||||
|
||||
- (void)open:(NSURL *_Nonnull)url NS_REFINED_FOR_SWIFT;
|
||||
//- (void)open:(NSURL *_Nonnull)url NS_REFINED_FOR_SWIFT;
|
||||
- (void)store:(NSURL *_Nonnull)url with: (NSUUID *_Nonnull)zimFileID NS_REFINED_FOR_SWIFT;
|
||||
- (void)close:(NSUUID *_Nonnull)zimFileID NS_REFINED_FOR_SWIFT;
|
||||
- (NSArray *_Nonnull)getReaderIdentifiers NS_REFINED_FOR_SWIFT;
|
||||
- (nonnull void *) getArchives;
|
||||
|
@ -14,7 +14,7 @@
|
||||
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdocumentation"
|
||||
#include "kiwix/book.h"
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#import "ZimFileService.h"
|
||||
#import "ZimFileMetaData.h"
|
||||
#import "PerformanceObjC.h"
|
||||
|
||||
@interface ZimFileService ()
|
||||
|
||||
@ -68,26 +69,13 @@
|
||||
|
||||
#pragma mark - Reader Management
|
||||
|
||||
- (void)open:(NSURL *)url {
|
||||
- (void)store:(NSURL *)url with:(NSUUID *)zimFileID {
|
||||
try {
|
||||
// if url does not ends with "zim", skip it
|
||||
NSString *pathExtension = [[url pathExtension] lowercaseString];
|
||||
if (![pathExtension isEqualToString:@"zim"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if we have previously added this url, skip it
|
||||
if ([[self.fileURLs allKeysForObject:url] count] > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add the archive
|
||||
[url startAccessingSecurityScopedResource];
|
||||
zim::Archive archive = zim::Archive([url fileSystemRepresentation]);
|
||||
self.archives->insert(std::make_pair(std::string(archive.getUuid()), archive));
|
||||
|
||||
// store file URL
|
||||
NSUUID *zimFileID = [[NSUUID alloc] initWithUUIDBytes:(unsigned char *)archive.getUuid().data];
|
||||
self.fileURLs[zimFileID] = url;
|
||||
} catch (std::exception) {
|
||||
NSLog(@"Error opening zim file.");
|
||||
@ -230,6 +218,18 @@
|
||||
}
|
||||
|
||||
- (zim::Archive *_Nullable) archiveBy: (NSUUID *_Nonnull) zimFileID {
|
||||
zim::Archive *found = [self findArchiveBy:zimFileID];
|
||||
if(found == nil) {
|
||||
NSURL *url = self.fileURLs[zimFileID];
|
||||
if (url == nil) {
|
||||
return nil;
|
||||
}
|
||||
[self insertIntoArchives:url with:zimFileID];
|
||||
}
|
||||
return [self findArchiveBy: zimFileID];
|
||||
}
|
||||
|
||||
- (zim::Archive *_Nullable) findArchiveBy: (NSUUID *_Nonnull) zimFileID {
|
||||
std::string zimFileID_C = [self zimfileID_C: zimFileID];
|
||||
auto found = self.archives->find(zimFileID_C);
|
||||
if (found == self.archives->end()) {
|
||||
@ -238,6 +238,16 @@
|
||||
return &(found->second);
|
||||
}
|
||||
|
||||
- (void) insertIntoArchives: (NSURL *_Nonnull) url with: (NSUUID *_Nonnull) zimFileID {
|
||||
try {
|
||||
[url startAccessingSecurityScopedResource];
|
||||
zim::Archive archive = zim::Archive([url fileSystemRepresentation]); // takes the longest time
|
||||
self.archives->insert(std::make_pair(std::string(archive.getUuid()), archive));
|
||||
} catch (std::exception) {
|
||||
NSLog(@"cannot insert archive with: %@, %@", url.absoluteString, zimFileID.UUIDString);
|
||||
}
|
||||
}
|
||||
|
||||
- (zim::Item) itemIn: (NSUUID *)zimFileID contentPath:(NSString *)contentPath {
|
||||
if ([contentPath hasPrefix:@"/"]) {
|
||||
contentPath = [contentPath substringFromIndex:1];
|
||||
|
@ -27,7 +27,7 @@ extension ZimFileService {
|
||||
/// - Parameter bookmark: url bookmark data of the zim file to open
|
||||
/// - Returns: new url bookmark data if the one used to open the zim file is stale
|
||||
@discardableResult
|
||||
func open(fileURLBookmark data: Data) throws -> Data? {
|
||||
func open(fileURLBookmark data: Data, for uuid: UUID) throws -> Data? {
|
||||
// resolve url
|
||||
var isStale: Bool = false
|
||||
#if os(macOS)
|
||||
@ -41,8 +41,7 @@ extension ZimFileService {
|
||||
throw ZimFileOpenError.missing
|
||||
}
|
||||
#endif
|
||||
|
||||
__open(url)
|
||||
__store(url, with: uuid)
|
||||
return isStale ? ZimFileService.getFileURLBookmarkData(for: url) : nil
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ struct LibraryOperations {
|
||||
|
||||
// open the file
|
||||
do {
|
||||
try ZimFileService.shared.open(fileURLBookmark: fileURLBookmark)
|
||||
try ZimFileService.shared.open(fileURLBookmark: fileURLBookmark, for: metadata.fileID)
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
@ -73,7 +73,7 @@ struct LibraryOperations {
|
||||
zimFiles.forEach { zimFile in
|
||||
guard let data = zimFile.fileURLBookmark else { return }
|
||||
do {
|
||||
if let data = try ZimFileService.shared.open(fileURLBookmark: data) {
|
||||
if let data = try ZimFileService.shared.open(fileURLBookmark: data, for: zimFile.fileID) {
|
||||
zimFile.fileURLBookmark = data
|
||||
}
|
||||
zimFile.isMissing = false
|
||||
|
@ -76,7 +76,6 @@ final class LibraryViewModel: ObservableObject {
|
||||
@MainActor
|
||||
func start(isUserInitiated: Bool) async {
|
||||
guard process.state != .inProgress else { return }
|
||||
let oldState = process.state
|
||||
do {
|
||||
// decide if refresh should proceed
|
||||
let lastRefresh: Date? = Defaults[.libraryLastRefresh]
|
||||
|
Loading…
x
Reference in New Issue
Block a user