From 3d3232eedcb92879203f9b5d0a2d12835c3bcae1 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 13 Mar 2026 09:00:55 +0100 Subject: [PATCH] Temp --- .bazelrc | 35 +++- .vscode/settings.json | 4 +- BUILD.bazel | 7 +- Telegram/BUILD | 24 ++- Tests/TelegramCoreBuildTest/BUILD | 21 ++- build-system/Make/Make.py | 1 - build-system/bazel-rules/rules_apple | 2 +- build-system/bazel-utils/plist_fragment.bzl | 3 + scripts/lldb_build_common.sh | 3 - .../TelegramUI/Sources/AppDelegate.swift | 152 ++++++++++-------- .../Sources/ChatHistoryEntriesForView.swift | 6 + .../Sources/ChatHistoryViewForLocation.swift | 8 +- .../Sources/SharedWakeupManager.swift | 52 ++++-- 13 files changed, 205 insertions(+), 113 deletions(-) diff --git a/.bazelrc b/.bazelrc index 1ce9174344..9127415f6a 100644 --- a/.bazelrc +++ b/.bazelrc @@ -22,14 +22,36 @@ build --strategy=SwiftCompile=worker #common --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main/ -# SourceKit BSP: Swift indexing features -common --features=swift.index_while_building -common --features=swift.use_global_index_store -common --features=swift.use_global_module_cache -common --features=oso_prefix_is_pwd +# rules_swift flags migration +# --swiftcopt and --host_swiftcopt are deprecated +common --flag_alias=swiftcopt=@build_bazel_rules_swift//swift:copt +common --flag_alias=host_swiftcopt=@build_bazel_rules_swift//swift:exec_copt +#common --swiftcopt=-whole-module-optimization +#common --host_swiftcopt=-whole-module-optimization -# SourceKit BSP: Index build config (used for background indexing) +common --check_visibility=false + +# All of the following are Debug/Index setup configs inspired by the default rules_xcodeproj template + +common --verbose_failures +common --cache_computed_file_digests=500000 +common --action_cache_store_output_metadata +common --experimental_use_cpp_compile_action_args_params_file +common --define=apple.experimental.tree_artifact_outputs=1 +common --features=apple.swizzle_absolute_xcttestsourcelocation +common --features=oso_prefix_is_pwd +common --features=relative_ast_path +common --features=swift.cacheable_swiftmodules +common --features=swift.index_while_building +common --features=swift.use_global_module_cache +common --features=swift.emit_swiftsourceinfo +common --nolegacy_important_outputs +build --noworker_sandboxing +build --spawn_strategy=remote,worker,local + +# Only for BSP builds common:index_build --experimental_convenience_symlinks=ignore +common:index_build --bes_backend= --bes_results_url= common:index_build --show_result=0 common:index_build --noshow_loading_progress common:index_build --noshow_progress @@ -37,3 +59,4 @@ common:index_build --noannounce_rc common:index_build --noshow_timestamps common:index_build --curses=no common:index_build --color=no + diff --git a/.vscode/settings.json b/.vscode/settings.json index d1e808574b..ba34a33e56 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,5 +23,7 @@ ] } }, - "swift.sourcekit-lsp.serverPath": "${workspaceFolder}/build-input/sourcekit-lsp" + "swift.sourcekit-lsp.serverPath": "${workspaceFolder}/build-input/sourcekit-lsp", + "sourcekit-bazel-bsp.rulesAppleName": "build_bazel_rules_apple", + "cmake.sourceDirectory": "/Users/ali/build/telegram/telegram-ios/submodules/rlottie/rlottie/test" } diff --git a/BUILD.bazel b/BUILD.bazel index 05e5d1c325..4292181ff1 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,5 +1,7 @@ load("@sourcekit_bazel_bsp//rules:setup_sourcekit_bsp.bzl", "setup_sourcekit_bsp") +exports_files(["versions.json"]) + setup_sourcekit_bsp( name = "setup_sourcekit_bsp", bazel_wrapper = "./build-input/bazel-8.4.2-darwin-arm64", @@ -18,17 +20,12 @@ setup_sourcekit_bsp( "submodules/**/*.cpp", ], aquery_flags = [ - "define=telegramVersion=12.5", - "define=buildNumber=100000", ], index_flags = [ "config=index_build", - "define=telegramVersion=12.5", - "define=buildNumber=100000", ], index_build_batch_size = 10, targets = [ "//Telegram:Telegram", ], - merge_lsp_config = False, ) diff --git a/Telegram/BUILD b/Telegram/BUILD index 15f6fe2c5f..a1cf7d9524 100644 --- a/Telegram/BUILD +++ b/Telegram/BUILD @@ -385,7 +385,8 @@ plist_fragment( """ CFBundleVersion {buildNumber} - """ + """, + defaults = {"buildNumber": "1"}, ) plist_fragment( @@ -574,14 +575,23 @@ plist_fragment( ]) ) -plist_fragment( +genrule( name = "VersionInfoPlist", - extension = "plist", - template = - """ + srcs = ["//:versions.json"], + outs = ["VersionInfoPlist.plist"], + cmd = """ + version=$$(python3 -c "import json; print(json.load(open('$(location //:versions.json)'))['app'])") + cat > $@ < + + + CFBundleShortVersionString - {telegramVersion} - """ + $$version + + +PLIST + """, ) plist_fragment( diff --git a/Tests/TelegramCoreBuildTest/BUILD b/Tests/TelegramCoreBuildTest/BUILD index 8b4227a100..e5038bea6f 100644 --- a/Tests/TelegramCoreBuildTest/BUILD +++ b/Tests/TelegramCoreBuildTest/BUILD @@ -43,14 +43,23 @@ plist_fragment( """ ) -plist_fragment( +genrule( name = "VersionInfoPlist", - extension = "plist", - template = - """ + srcs = ["//:versions.json"], + outs = ["VersionInfoPlist.plist"], + cmd = """ + version=$$(python3 -c "import json; print(json.load(open('$(location //:versions.json)'))['app'])") + cat > $@ < + + + CFBundleShortVersionString - {telegramVersion} - """ + $$version + + +PLIST + """, ) plist_fragment( diff --git a/build-system/Make/Make.py b/build-system/Make/Make.py index ebff8097e5..457e5d9517 100644 --- a/build-system/Make/Make.py +++ b/build-system/Make/Make.py @@ -212,7 +212,6 @@ class BazelCommandLine: def get_define_arguments(self): return [ '--define=buildNumber={}'.format(self.build_number), - '--define=telegramVersion={}'.format(self.build_environment.app_version) ] def get_project_generation_arguments(self): diff --git a/build-system/bazel-rules/rules_apple b/build-system/bazel-rules/rules_apple index 39cc252924..f6aef7db5b 160000 --- a/build-system/bazel-rules/rules_apple +++ b/build-system/bazel-rules/rules_apple @@ -1 +1 @@ -Subproject commit 39cc2529241335d20afcb6700c587d064e7a2870 +Subproject commit f6aef7db5b649ffc3b7497ecc83a08ad3ab19559 diff --git a/build-system/bazel-utils/plist_fragment.bzl b/build-system/bazel-utils/plist_fragment.bzl index ac40575332..64ef8d4076 100644 --- a/build-system/bazel-utils/plist_fragment.bzl +++ b/build-system/bazel-utils/plist_fragment.bzl @@ -18,6 +18,8 @@ def _plist_fragment(ctx): resolved_values = dict() for key in found_keys: value = ctx.var.get(key, None) + if value == None: + value = ctx.attr.defaults.get(key, None) if value == None: fail("Expected value for --define={} was not found".format(key)) resolved_values[key] = value @@ -38,6 +40,7 @@ plist_fragment = rule( attrs = { "extension": attr.string(mandatory = True), "template": attr.string(mandatory = True), + "defaults": attr.string_dict(), }, outputs = { "out": "%{name}.%{extension}" diff --git a/scripts/lldb_build_common.sh b/scripts/lldb_build_common.sh index 8633902f40..223417bc5b 100755 --- a/scripts/lldb_build_common.sh +++ b/scripts/lldb_build_common.sh @@ -10,12 +10,9 @@ WORKSPACE_ROOT=$(pwd) BAZEL_CMD="./build-input/bazel-8.4.2-darwin-arm64" export ADDITIONAL_FLAGS=() -TELEGRAM_VERSION=$(python3 -c "import json; print(json.load(open('${WORKSPACE_ROOT}/versions.json'))['app'])") ADDITIONAL_FLAGS+=("--keep_going") ADDITIONAL_FLAGS+=("--color=yes") -ADDITIONAL_FLAGS+=("--define=telegramVersion=${TELEGRAM_VERSION}") -ADDITIONAL_FLAGS+=("--define=buildNumber=100000") if [ -n "${BAZEL_EXTRA_BUILD_FLAGS:-}" ]; then ADDITIONAL_FLAGS+=("${BAZEL_EXTRA_BUILD_FLAGS[@]}") diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index f28a25671b..042bcda543 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -551,80 +551,94 @@ private func extractAccountManagerState(records: AccountRecordsView CallSessionManagerImplementationVersion in - CallSessionManagerImplementationVersion(version: version, supportsVideo: supportsVideo) - }, appData: self.regularDeviceToken.get() - |> map { token in - let tokenEnvironment: String - #if DEBUG - tokenEnvironment = "sandbox" - #else - tokenEnvironment = "production" - #endif - - let data = buildConfig.bundleData(withAppToken: token, tokenType: "apns", tokenEnvironment: tokenEnvironment, signatureDict: signatureDict) - if let data = data, let _ = String(data: data, encoding: .utf8) { - } else { - Logger.shared.log("data", "can't deserialize") - } - return data - }, externalRequestVerificationStream: self.firebaseRequestVerificationSecretStream.get(), externalRecaptchaRequestVerification: { method, siteKey in - return Signal { subscriber in - let recaptchaClient: Promise - if let current = self.recaptchaClientsBySiteKey[siteKey] { - recaptchaClient = current - } else { - recaptchaClient = Promise() - self.recaptchaClientsBySiteKey[siteKey] = recaptchaClient - - Recaptcha.fetchClient(withSiteKey: siteKey) { client, error in - Queue.mainQueue().async { - guard let client else { - Logger.shared.log("App \(self.episodeId)", "RecaptchaClient creation error: \(String(describing: error)).") - return - } - recaptchaClient.set(.single(client)) - } - } - } + let networkArguments = NetworkInitializationArguments( + apiId: apiId, + apiHash: apiHash, + languagesCategory: languagesCategory, + appVersion: appVersion, + voipMaxLayer: PresentationCallManagerImpl.voipMaxLayer, + voipVersions: PresentationCallManagerImpl.voipVersions(includeExperimental: true, includeReference: false).map { version, supportsVideo -> CallSessionManagerImplementationVersion in + CallSessionManagerImplementationVersion(version: version, supportsVideo: supportsVideo) + }, + appData: self.regularDeviceToken.get() |> map { token in + let tokenEnvironment: String + #if DEBUG + tokenEnvironment = "sandbox" + #else + tokenEnvironment = "production" + #endif - return (recaptchaClient.get() - |> take(1) - |> mapToSignal { recaptchaClient -> Signal in - return Signal { subscriber in - var recaptchaAction: RecaptchaAction? - switch method { - case "signup": - recaptchaAction = RecaptchaAction.signup - default: - break - } + let data = buildConfig.bundleData(withAppToken: token, tokenType: "apns", tokenEnvironment: tokenEnvironment, signatureDict: signatureDict) + if let data = data, let _ = String(data: data, encoding: .utf8) { + } else { + Logger.shared.log("data", "can't deserialize") + } + return data + }, + externalRequestVerificationStream: self.firebaseRequestVerificationSecretStream.get(), + externalRecaptchaRequestVerification: { method, siteKey in + return Signal { subscriber in + let recaptchaClient: Promise + if let current = self.recaptchaClientsBySiteKey[siteKey] { + recaptchaClient = current + } else { + recaptchaClient = Promise() + self.recaptchaClientsBySiteKey[siteKey] = recaptchaClient - guard let recaptchaAction else { - subscriber.putNext(nil) - subscriber.putCompletion() - - return EmptyDisposable - } - recaptchaClient.execute(withAction: recaptchaAction) { token, error in - if let token { - subscriber.putNext(token) - Logger.shared.log("App \(self.episodeId)", "RecaptchaClient executed successfully") - } else { - subscriber.putNext(nil) - Logger.shared.log("App \(self.episodeId)", "RecaptchaClient execute error: \(String(describing: error))") + Recaptcha.fetchClient(withSiteKey: siteKey) { client, error in + Queue.mainQueue().async { + guard let client else { + Logger.shared.log("App \(self.episodeId)", "RecaptchaClient creation error: \(String(describing: error)).") + return + } + recaptchaClient.set(.single(client)) } - subscriber.putCompletion() - } - - return ActionDisposable { } } - |> runOn(Queue.mainQueue()) - }).startStandalone(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) - } - |> runOn(Queue.mainQueue()) - }, autolockDeadine: autolockDeadine, encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil, useBetaFeatures: !buildConfig.isAppStoreBuild, isICloudEnabled: buildConfig.isICloudEnabled) + + return (recaptchaClient.get() + |> take(1) + |> mapToSignal { recaptchaClient -> Signal in + return Signal { subscriber in + var recaptchaAction: RecaptchaAction? + switch method { + case "signup": + recaptchaAction = RecaptchaAction.signup + default: + break + } + + guard let recaptchaAction else { + subscriber.putNext(nil) + subscriber.putCompletion() + + return EmptyDisposable + } + recaptchaClient.execute(withAction: recaptchaAction) { token, error in + if let token { + subscriber.putNext(token) + Logger.shared.log("App \(self.episodeId)", "RecaptchaClient executed successfully") + } else { + subscriber.putNext(nil) + Logger.shared.log("App \(self.episodeId)", "RecaptchaClient execute error: \(String(describing: error))") + } + subscriber.putCompletion() + } + + return ActionDisposable { + } + } + |> runOn(Queue.mainQueue()) + }).startStandalone(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) + } + |> runOn(Queue.mainQueue()) + }, + autolockDeadine: autolockDeadine, + encryptionProvider: OpenSSLEncryptionProvider(), + deviceModelName: nil, + useBetaFeatures: !buildConfig.isAppStoreBuild, + isICloudEnabled: buildConfig.isICloudEnabled + ) guard let appGroupUrl = maybeAppGroupUrl else { self.mainWindow?.presentNative(UIAlertController(title: nil, message: "Error 2", preferredStyle: .alert)) diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 0bf833a029..15bbad296b 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -433,6 +433,12 @@ func chatHistoryEntriesForView( var i = 0 let unreadEntry: ChatHistoryEntry = .UnreadEntry(maxReadIndex, presentationData) for entry in entries { + if case let .MessageGroupEntry(_, messages, _) = entry { + if !messages.isEmpty && maxReadIndex >= messages[0].0.index { + i += 1 + continue + } + } if entry > unreadEntry { if i != 0 { entries.insert(unreadEntry, at: i) diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index 00ba078433..b990c02468 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -65,7 +65,7 @@ func chatHistoryViewForLocation( let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData) - if view.isLoading { + if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) { return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType)) } @@ -147,7 +147,7 @@ func chatHistoryViewForLocation( if preloaded { return .HistoryView(view: view, type: .Generic(type: updateType), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: combinedInitialData, id: location.id) } else { - if view.isLoading { + if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) { return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType)) } var scrollPosition: ChatHistoryViewScrollPosition? @@ -311,7 +311,7 @@ func chatHistoryViewForLocation( let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData) - if view.isLoading { + if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) { return ChatHistoryViewUpdate.Loading(initialData: combinedInitialData, type: .Generic(type: updateType)) } @@ -461,7 +461,7 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea case .Loading: return nil case let .HistoryView(view, _, _, _, _, _, _): - if view.isLoading { + if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) { return nil } return view.entries.isEmpty diff --git a/submodules/TelegramUI/Sources/SharedWakeupManager.swift b/submodules/TelegramUI/Sources/SharedWakeupManager.swift index e259fd8693..4e6bb1fcc7 100644 --- a/submodules/TelegramUI/Sources/SharedWakeupManager.swift +++ b/submodules/TelegramUI/Sources/SharedWakeupManager.swift @@ -50,6 +50,8 @@ private struct AccountTasks { } } +private let backgroundTaskSubmissionDelay: Double = 10.0 + private struct PendingMediaUploadKey: Hashable { let accountId: AccountRecordId let messageId: MessageId @@ -99,7 +101,8 @@ public final class SharedWakeupManager { private var backgroundProcessingTaskId: String? private var backgroundProcessingTaskLaunched: Bool = false private var backgroundProcessingTaskCancellationRequestedByApp: Bool = false - + private var pendingBackgroundProcessingTaskTimer: SwiftSignalKit.Timer? + private var pendingStoryUploadsByKey: [PendingStoryUploadKey: Float] = [:] private var pendingStoryUploadStatusesByKey: [PendingStoryUploadKey: PendingStoryUploadStatus] = [:] private var backgroundStoryProcessingTaskProgressByKey: [PendingStoryUploadKey: Float] = [:] @@ -107,7 +110,8 @@ public final class SharedWakeupManager { private var backgroundStoryProcessingTaskId: String? private var backgroundStoryProcessingTaskLaunched: Bool = false private var backgroundStoryProcessingTaskCancellationRequestedByApp: Bool = false - + private var pendingBackgroundStoryProcessingTaskTimer: SwiftSignalKit.Timer? + public init(beginBackgroundTask: @escaping (String, @escaping () -> Void) -> UIBackgroundTaskIdentifier?, endBackgroundTask: @escaping (UIBackgroundTaskIdentifier) -> Void, backgroundTimeRemaining: @escaping () -> Double, acquireIdleExtension: @escaping () -> Disposable?, activeAccounts: Signal<(primary: Account?, accounts: [(AccountRecordId, Account)]), NoError>, liveLocationPolling: Signal, watchTasks: Signal, inForeground: Signal, hasActiveAudioSession: Signal, notificationManager: SharedNotificationManager?, mediaManager: MediaManager, callManager: PresentationCallManager?, accountUserInterfaceInUse: @escaping (AccountRecordId) -> Signal, presentationData: @escaping () -> PresentationData?) { assert(Queue.mainQueue().isCurrent()) @@ -155,6 +159,10 @@ public final class SharedWakeupManager { } strongSelf.allowBackgroundTimeExtensionDeadlineTimer?.invalidate() strongSelf.allowBackgroundTimeExtensionDeadlineTimer = nil + strongSelf.pendingBackgroundProcessingTaskTimer?.invalidate() + strongSelf.pendingBackgroundProcessingTaskTimer = nil + strongSelf.pendingBackgroundStoryProcessingTaskTimer?.invalidate() + strongSelf.pendingBackgroundStoryProcessingTaskTimer = nil } strongSelf.updateBackgroundProcessingTaskStateFromPendingMediaUploads() strongSelf.updateBackgroundProcessingTaskStateFromPendingStoryUploads() @@ -356,6 +364,8 @@ public final class SharedWakeupManager { self.pendingStoryUploadsDisposable?.dispose() self.managedPausedInBackgroundPlayer?.dispose() self.keepIdleDisposable?.dispose() + self.pendingBackgroundProcessingTaskTimer?.invalidate() + self.pendingBackgroundStoryProcessingTaskTimer?.invalidate() if let (taskId, _, timer) = self.currentTask { timer.invalidate() self.endBackgroundTask(taskId) @@ -369,19 +379,30 @@ public final class SharedWakeupManager { let shouldHaveTask = !self.pendingMediaUploadsByKey.isEmpty && !self.inForeground let hadTask = self.backgroundProcessingTaskId != nil - + if shouldHaveTask { - if !hadTask { - self.startBackgroundProcessingTaskIfNeeded() + if !hadTask && self.pendingBackgroundProcessingTaskTimer == nil { + let timer = SwiftSignalKit.Timer(timeout: backgroundTaskSubmissionDelay, repeat: false, completion: { [weak self] in + guard let self else { + return + } + self.pendingBackgroundProcessingTaskTimer = nil + self.startBackgroundProcessingTaskIfNeeded() + }, queue: .mainQueue()) + self.pendingBackgroundProcessingTaskTimer = timer + timer.start() } } else { + self.pendingBackgroundProcessingTaskTimer?.invalidate() + self.pendingBackgroundProcessingTaskTimer = nil + if let backgroundProcessingTaskId = self.backgroundProcessingTaskId { if !self.backgroundProcessingTaskCancellationRequestedByApp { self.backgroundProcessingTaskCancellationRequestedByApp = true BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: backgroundProcessingTaskId) Logger.shared.log("Wakeup", "Requested BG task cancellation by app: \(backgroundProcessingTaskId)") } - + if !self.backgroundProcessingTaskLaunched { self.backgroundProcessingTaskId = nil self.backgroundProcessingTaskProgressByKey = [:] @@ -399,19 +420,30 @@ public final class SharedWakeupManager { let shouldHaveTask = !self.pendingStoryUploadStatusesByKey.isEmpty && !self.inForeground let hadTask = self.backgroundStoryProcessingTaskId != nil - + if shouldHaveTask { - if !hadTask { - self.startBackgroundStoryProcessingTaskIfNeeded() + if !hadTask && self.pendingBackgroundStoryProcessingTaskTimer == nil { + let timer = SwiftSignalKit.Timer(timeout: backgroundTaskSubmissionDelay, repeat: false, completion: { [weak self] in + guard let self else { + return + } + self.pendingBackgroundStoryProcessingTaskTimer = nil + self.startBackgroundStoryProcessingTaskIfNeeded() + }, queue: .mainQueue()) + self.pendingBackgroundStoryProcessingTaskTimer = timer + timer.start() } } else { + self.pendingBackgroundStoryProcessingTaskTimer?.invalidate() + self.pendingBackgroundStoryProcessingTaskTimer = nil + if let backgroundStoryProcessingTaskId = self.backgroundStoryProcessingTaskId { if !self.backgroundStoryProcessingTaskCancellationRequestedByApp { self.backgroundStoryProcessingTaskCancellationRequestedByApp = true BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: backgroundStoryProcessingTaskId) Logger.shared.log("Wakeup", "Requested story BG task cancellation by app: \(backgroundStoryProcessingTaskId)") } - + if !self.backgroundStoryProcessingTaskLaunched { self.backgroundStoryProcessingTaskId = nil self.backgroundStoryProcessingTaskProgressByKey = [:]