From cad639d32c220f1a9e275eb004ebf1256196037b Mon Sep 17 00:00:00 2001 From: Marten Rebane Date: Wed, 8 Jul 2026 14:36:12 +0300 Subject: [PATCH] Fix app closing on signing --- .../include/Conf/DigiDocConfWrapper.mm | 6 +- .../Container/DigiDocContainerWrapper.mm | 2 +- .../Signature/DigiDocSigningWrapper.mm | 2 + .../Domain/Conf/DigiDocConf.swift | 58 +++++++++++++------ .../Domain/Container/ContainerWrapper.swift | 5 ++ .../ViewModel/SigningViewModelTests.swift | 11 ++++ 6 files changed, 63 insertions(+), 21 deletions(-) diff --git a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm index 9369263a..43b5c3a3 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm +++ b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm @@ -250,8 +250,10 @@ static void initConf(DigiDocConfig *conf, NSString *userAgent, void (^completion } void updateConfiguration(DigiDocConfig *conf) { - DigiDocConfCurrent *newCurrentConf = new DigiDocConfCurrent(conf); - digidoc::Conf::init(newCurrentConf); + dispatch_async(dispatch_get_main_queue(), ^{ + DigiDocConfCurrent *newCurrentConf = new DigiDocConfCurrent(conf); + digidoc::Conf::init(newCurrentConf); + }); } static void setTSUrl(NSURL *tsaUrl) { diff --git a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Container/DigiDocContainerWrapper.mm b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Container/DigiDocContainerWrapper.mm index b101549c..428d2da3 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Container/DigiDocContainerWrapper.mm +++ b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Container/DigiDocContainerWrapper.mm @@ -47,7 +47,7 @@ virtual bool validateOnline() const override { @implementation DigiDocContainerWrapper {} + (void)dispatch:(void (^)(void))command completion:(void (^)(NSError *error))completion { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_async(dispatch_get_main_queue(), ^{ NSError *error = nil; try { diff --git a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Signature/DigiDocSigningWrapper.mm b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Signature/DigiDocSigningWrapper.mm index f5397ce1..d96c56f5 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Signature/DigiDocSigningWrapper.mm +++ b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Signature/DigiDocSigningWrapper.mm @@ -101,10 +101,12 @@ - (void)addSignature:(NSData *)data completion:(void (^)(BOOL success, NSError * NSLocalizedDescriptionKey: @"Did not find signature" }]; if (completion) completion(NO, error); + return; } if (auto timeStampTime = _signature->TimeStampTime(); !timeStampTime.empty()) { if (completion) completion(YES, error); + return; } try { diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift index d759f7af..e16f1021 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift @@ -172,6 +172,8 @@ public struct DigiDocConf: DigiDocConfProtocol, Loggable { public actor DigiDocInitializer: Loggable { private var isInitialized = false private var initializationError: ErrorDetail? + private var isInitializing = false + private var initializationWaiters: [CheckedContinuation] = [] private let configurationRepository: ConfigurationRepositoryProtocol private let fileManager: FileManagerProtocol @@ -195,30 +197,50 @@ public actor DigiDocInitializer: Loggable { userAgent: String ) async throws { - guard !isInitialized else { + if isInitialized { throw DigiDocError.alreadyInitialized } + if isInitializing { + try await withCheckedThrowingContinuation { continuation in + initializationWaiters.append(continuation) + } + throw DigiDocError.alreadyInitialized + } + + isInitializing = true + let logLevel = isLoggingEnabled ? DigiDocInitializer.libdigidocppLogLevel : 0 - if let customConf = configuration { - try await initDigiDoc( - conf: toDigiDocConfig( - logLevel: logLevel, - logFile: overrideLogFile(), - tslCache: overrideTSLCache(), - configurationProvider: customConf - ), - userAgent: userAgent - ) - } else { - digidocConf.logLevel = overrideLogLevel(logLevel: logLevel) - try await initDigiDoc( - conf: digidocConf, - userAgent: userAgent - ) + do { + if let customConf = configuration { + try await initDigiDoc( + conf: toDigiDocConfig( + logLevel: logLevel, + logFile: overrideLogFile(), + tslCache: overrideTSLCache(), + configurationProvider: customConf + ), + userAgent: userAgent + ) + } else { + digidocConf.logLevel = overrideLogLevel(logLevel: logLevel) + digidocConf.logFile = overrideLogFile() + digidocConf.tslcache = overrideTSLCache() + try await initDigiDoc(conf: digidocConf, userAgent: userAgent) + } + isInitialized = true + isInitializing = false + let waiters = initializationWaiters + initializationWaiters.removeAll() + waiters.forEach { $0.resume() } + } catch { + isInitializing = false + let waiters = initializationWaiters + initializationWaiters.removeAll() + waiters.forEach { $0.resume(throwing: error) } + throw error } - isInitialized = true } func toDigiDocConfig( diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift index ce3cc7c8..81a4bd76 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift @@ -31,6 +31,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { private let fileManager: FileManagerProtocol + @MainActor private let digiDocSigningWrapper: DigiDocSigningWrapper = DigiDocSigningWrapper() public init( @@ -188,6 +189,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { } } + @MainActor @discardableResult public func removeSignature(index: Int, containerFile: URL) async throws -> ContainerWrapperProtocol { do { @@ -207,6 +209,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { } } + @MainActor @discardableResult public func removeDataFile(index: Int, containerFile: URL) async throws -> ContainerWrapperProtocol { do { @@ -226,6 +229,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { } } + @MainActor public func prepareSignature( cert: Data, containerPath: URL, @@ -247,6 +251,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { ) } + @MainActor public func addSignature(signature: Data, containerFile: URL) async throws -> ContainerWrapperProtocol { do { diff --git a/RIADigiDocTests/ViewModel/SigningViewModelTests.swift b/RIADigiDocTests/ViewModel/SigningViewModelTests.swift index c6a2de2b..631e9335 100644 --- a/RIADigiDocTests/ViewModel/SigningViewModelTests.swift +++ b/RIADigiDocTests/ViewModel/SigningViewModelTests.swift @@ -63,6 +63,17 @@ struct SigningViewModelTests: Loggable { sivaRepository: mockSivaRepository, containerUtil: mockContainerUtil ) + + do { + try await DigiDocConf.initDigiDoc(userAgent: "TestUserAgent") + } catch let error as DigiDocError { + switch error { + case .alreadyInitialized: + break + default: + Issue.record("DigiDocConf initialization failed: \(error.localizedDescription)") + } + } } @Test