mirror of
https://github.com/immich-app/immich.git
synced 2025-11-03 11:07:10 -05:00
fix: ios skip posting hash response after detached from engine (#22695)
* skip posting message after detached from engine * review changes * cancel plugin before destroying engine --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
46869f664d
commit
cf52b879b1
@ -131,10 +131,13 @@
|
|||||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
B231F52D2E93A44A00BC45D1 /* Core */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
path = Core;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B2CF7F8C2DDE4EBB00744BF6 /* Sync */ = {
|
B2CF7F8C2DDE4EBB00744BF6 /* Sync */ = {
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
exceptions = (
|
|
||||||
);
|
|
||||||
path = Sync;
|
path = Sync;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -247,6 +250,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B231F52D2E93A44A00BC45D1 /* Core */,
|
||||||
B25D37792E72CA15008B6CA7 /* Connectivity */,
|
B25D37792E72CA15008B6CA7 /* Connectivity */,
|
||||||
B21E34A62E5AF9760031FDB9 /* Background */,
|
B21E34A62E5AF9760031FDB9 /* Background */,
|
||||||
B2CF7F8C2DDE4EBB00744BF6 /* Sync */,
|
B2CF7F8C2DDE4EBB00744BF6 /* Sync */,
|
||||||
@ -331,6 +335,7 @@
|
|||||||
F0B57D482DF764BE00DC5BCC /* PBXTargetDependency */,
|
F0B57D482DF764BE00DC5BCC /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
fileSystemSynchronizedGroups = (
|
fileSystemSynchronizedGroups = (
|
||||||
|
B231F52D2E93A44A00BC45D1 /* Core */,
|
||||||
B2CF7F8C2DDE4EBB00744BF6 /* Sync */,
|
B2CF7F8C2DDE4EBB00744BF6 /* Sync */,
|
||||||
);
|
);
|
||||||
name = Runner;
|
name = Runner;
|
||||||
@ -521,10 +526,14 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
@ -553,10 +562,14 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import UIKit
|
|||||||
|
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
|
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
|
||||||
AppDelegate.registerPlugins(binaryMessenger: controller.binaryMessenger)
|
AppDelegate.registerPlugins(with: controller.engine)
|
||||||
BackgroundServicePlugin.register(with: self.registrar(forPlugin: "BackgroundServicePlugin")!)
|
BackgroundServicePlugin.register(with: self.registrar(forPlugin: "BackgroundServicePlugin")!)
|
||||||
|
|
||||||
BackgroundServicePlugin.registerBackgroundProcessing()
|
BackgroundServicePlugin.registerBackgroundProcessing()
|
||||||
@ -51,9 +51,13 @@ import UIKit
|
|||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func registerPlugins(binaryMessenger: FlutterBinaryMessenger) {
|
public static func registerPlugins(with engine: FlutterEngine) {
|
||||||
NativeSyncApiSetup.setUp(binaryMessenger: binaryMessenger, api: NativeSyncApiImpl())
|
NativeSyncApiImpl.register(with: engine.registrar(forPlugin: NativeSyncApiImpl.name)!)
|
||||||
ThumbnailApiSetup.setUp(binaryMessenger: binaryMessenger, api: ThumbnailApiImpl())
|
ThumbnailApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: ThumbnailApiImpl())
|
||||||
BackgroundWorkerFgHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: BackgroundWorkerApiImpl())
|
BackgroundWorkerFgHostApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: BackgroundWorkerApiImpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func cancelPlugins(with engine: FlutterEngine) {
|
||||||
|
(engine.valuePublished(byPlugin: NativeSyncApiImpl.name) as? NativeSyncApiImpl)?.detachFromEngine()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,7 +95,7 @@ class BackgroundWorker: BackgroundWorkerBgHostApi {
|
|||||||
// Register plugins in the new engine
|
// Register plugins in the new engine
|
||||||
GeneratedPluginRegistrant.register(with: engine)
|
GeneratedPluginRegistrant.register(with: engine)
|
||||||
// Register custom plugins
|
// Register custom plugins
|
||||||
AppDelegate.registerPlugins(binaryMessenger: engine.binaryMessenger)
|
AppDelegate.registerPlugins(with: engine)
|
||||||
flutterApi = BackgroundWorkerFlutterApi(binaryMessenger: engine.binaryMessenger)
|
flutterApi = BackgroundWorkerFlutterApi(binaryMessenger: engine.binaryMessenger)
|
||||||
BackgroundWorkerBgHostApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: self)
|
BackgroundWorkerBgHostApiSetup.setUp(binaryMessenger: engine.binaryMessenger, api: self)
|
||||||
|
|
||||||
@ -168,6 +168,7 @@ class BackgroundWorker: BackgroundWorkerBgHostApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isComplete = true
|
isComplete = true
|
||||||
|
AppDelegate.cancelPlugins(with: engine)
|
||||||
engine.destroyContext()
|
engine.destroyContext()
|
||||||
flutterApi = nil
|
flutterApi = nil
|
||||||
completionHandler(success)
|
completionHandler(success)
|
||||||
|
|||||||
17
mobile/ios/Runner/Core/ImmichPlugin.swift
Normal file
17
mobile/ios/Runner/Core/ImmichPlugin.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class ImmichPlugin: NSObject {
|
||||||
|
var detached: Bool
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
detached = false
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func detachFromEngine() {
|
||||||
|
self.detached = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func completeWhenActive<T>(for completion: @escaping (T) -> Void, with value: T) {
|
||||||
|
guard !self.detached else { return }
|
||||||
|
completion(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,13 +17,25 @@ struct AssetWrapper: Hashable, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NativeSyncApiImpl: NativeSyncApi {
|
class NativeSyncApiImpl: ImmichPlugin, NativeSyncApi, FlutterPlugin {
|
||||||
|
static let name = "NativeSyncApi"
|
||||||
|
|
||||||
|
static func register(with registrar: any FlutterPluginRegistrar) {
|
||||||
|
let instance = NativeSyncApiImpl()
|
||||||
|
NativeSyncApiSetup.setUp(binaryMessenger: registrar.messenger(), api: instance)
|
||||||
|
registrar.publish(instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
func detachFromEngine(for registrar: any FlutterPluginRegistrar) {
|
||||||
|
super.detachFromEngine()
|
||||||
|
}
|
||||||
|
|
||||||
private let defaults: UserDefaults
|
private let defaults: UserDefaults
|
||||||
private let changeTokenKey = "immich:changeToken"
|
private let changeTokenKey = "immich:changeToken"
|
||||||
private let albumTypes: [PHAssetCollectionType] = [.album, .smartAlbum]
|
private let albumTypes: [PHAssetCollectionType] = [.album, .smartAlbum]
|
||||||
private let recoveredAlbumSubType = 1000000219
|
private let recoveredAlbumSubType = 1000000219
|
||||||
|
|
||||||
private var hashTask: Task<Void, Error>?
|
private var hashTask: Task<Void?, Error>?
|
||||||
private static let hashCancelledCode = "HASH_CANCELLED"
|
private static let hashCancelledCode = "HASH_CANCELLED"
|
||||||
private static let hashCancelled = Result<[HashResult], Error>.failure(PigeonError(code: hashCancelledCode, message: "Hashing cancelled", details: nil))
|
private static let hashCancelled = Result<[HashResult], Error>.failure(PigeonError(code: hashCancelledCode, message: "Hashing cancelled", details: nil))
|
||||||
|
|
||||||
@ -272,7 +284,7 @@ class NativeSyncApiImpl: NativeSyncApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if Task.isCancelled {
|
if Task.isCancelled {
|
||||||
return completion(Self.hashCancelled)
|
return self?.completeWhenActive(for: completion, with: Self.hashCancelled)
|
||||||
}
|
}
|
||||||
|
|
||||||
await withTaskGroup(of: HashResult?.self) { taskGroup in
|
await withTaskGroup(of: HashResult?.self) { taskGroup in
|
||||||
@ -280,7 +292,7 @@ class NativeSyncApiImpl: NativeSyncApi {
|
|||||||
results.reserveCapacity(assets.count)
|
results.reserveCapacity(assets.count)
|
||||||
for asset in assets {
|
for asset in assets {
|
||||||
if Task.isCancelled {
|
if Task.isCancelled {
|
||||||
return completion(Self.hashCancelled)
|
return self?.completeWhenActive(for: completion, with: Self.hashCancelled)
|
||||||
}
|
}
|
||||||
taskGroup.addTask {
|
taskGroup.addTask {
|
||||||
guard let self = self else { return nil }
|
guard let self = self else { return nil }
|
||||||
@ -290,7 +302,7 @@ class NativeSyncApiImpl: NativeSyncApi {
|
|||||||
|
|
||||||
for await result in taskGroup {
|
for await result in taskGroup {
|
||||||
guard let result = result else {
|
guard let result = result else {
|
||||||
return completion(Self.hashCancelled)
|
return self?.completeWhenActive(for: completion, with: Self.hashCancelled)
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
}
|
}
|
||||||
@ -299,7 +311,7 @@ class NativeSyncApiImpl: NativeSyncApi {
|
|||||||
results.append(HashResult(assetId: missing, error: "Asset not found in library", hash: nil))
|
results.append(HashResult(assetId: missing, error: "Asset not found in library", hash: nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
completion(.success(results))
|
return self?.completeWhenActive(for: completion, with: .success(results))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -192,6 +192,7 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi {
|
|||||||
_cancellationToken.cancel();
|
_cancellationToken.cancel();
|
||||||
_logger.info("Cleaning up background worker");
|
_logger.info("Cleaning up background worker");
|
||||||
final cleanupFutures = [
|
final cleanupFutures = [
|
||||||
|
nativeSyncApi?.cancelHashing(),
|
||||||
workerManager.dispose().catchError((_) async {
|
workerManager.dispose().catchError((_) async {
|
||||||
// Discard any errors on the dispose call
|
// Discard any errors on the dispose call
|
||||||
return;
|
return;
|
||||||
@ -201,7 +202,6 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi {
|
|||||||
_drift.close(),
|
_drift.close(),
|
||||||
_driftLogger.close(),
|
_driftLogger.close(),
|
||||||
backgroundSyncManager?.cancel(),
|
backgroundSyncManager?.cancel(),
|
||||||
nativeSyncApi?.cancelHashing(),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (_isar.isOpen) {
|
if (_isar.isOpen) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user