diff --git a/client/ios/DivKit/Views/DivBlockProvider.swift b/client/ios/DivKit/Views/DivBlockProvider.swift index 3d3e7e6ee..c107fc215 100644 --- a/client/ios/DivKit/Views/DivBlockProvider.swift +++ b/client/ios/DivKit/Views/DivBlockProvider.swift @@ -71,6 +71,23 @@ final class DivBlockProvider { .dispose(in: disposePool) } + func setSource( + _ source: DivViewSource, + debugParams: DebugParams + ) { + id = source.id + self.debugParams = debugParams + + switch source.kind { + case let .data(data): + update(data: data) + case let .divData(divData): + update(divData: divData) + case let .json(json): + update(json: json) + } + } + func setSource( _ source: DivViewSource, debugParams: DebugParams @@ -88,6 +105,22 @@ final class DivBlockProvider { } } + private func update(data: Data) { + dataErrors = [] + do { + guard let jsonObj = try? JSONSerialization.jsonObject(with: data), + let jsonDict = jsonObj as? [String: Any] else { + throw DeserializationError.nestedObjectError( + field: cardId.rawValue, + error: .invalidJSONData(data: data) + ) + } + update(json: jsonDict) + } catch { + block = handleError(error: error) + } + } + private func update(data: Data) async { dataErrors = [] @@ -110,6 +143,17 @@ final class DivBlockProvider { } } + private func update(json: [String: Any]) { + dataErrors = [] + do { + let result = try parseDivDataWithTemplates(json, cardId: cardId) + dataErrors.append(contentsOf: result.errorsOrWarnings?.asArray() ?? []) + update(divData: result.value) + } catch { + block = handleError(error: error) + } + } + private func update(json: [String: Any]) async { dataErrors = [] do { @@ -209,6 +253,21 @@ final class DivBlockProvider { } } + private func parseDivDataWithTemplates( + _ jsonDict: [String: Any], + cardId: DivCardID + ) throws -> DeserializationResult { + let rawDivData = try RawDivData(dictionary: jsonDict) + let templates = try measurements.templateParsingTime.updateMeasure { + DivTemplates(dictionary: rawDivData.templates) + } + return try measurements.divDataParsingTime.updateMeasure { + templates + .parseValue(type: DivDataTemplate.self, from: rawDivData.card) + .asCardResult(cardId: cardId) + } + } + private func parseDivDataWithTemplates( _ jsonDict: [String: Any], cardId: DivCardID diff --git a/client/ios/DivKit/Views/DivView.swift b/client/ios/DivKit/Views/DivView.swift index 6c8e658f0..fa59d2f27 100644 --- a/client/ios/DivKit/Views/DivView.swift +++ b/client/ios/DivKit/Views/DivView.swift @@ -67,6 +67,29 @@ public final class DivView: VisibleBoundsTrackingView { await preloader.setSource(source, debugParams: debugParams) } + /// Sets the source of the ``DivView`` and updates the layout. + /// - Parameters: + /// - source: The source of the ``DivView``, specified using `JSON` data, a `Data` object, or + /// ``DivData``. + /// - debugParams: Optional debug configurations for the ``DivView``. + /// - shouldResetPreviousCardData: Specifies whether to clear the data of the previous card when + /// updating the ``DivView`` with new content. + @_spi(Legacy) + public func setSource( + _ source: DivViewSource, + debugParams: DebugParams = DebugParams(), + shouldResetPreviousCardData: Bool = false + ) { + if shouldResetPreviousCardData, let blockProvider { + divKitComponents.reset(cardId: blockProvider.cardId) + } + blockProvider = preloader.blockProvider(for: source.id.cardId) + blockSubscription = blockProvider?.$block.currentAndNewValues.addObserver { [weak self] in + self?.update(block: $0) + } + preloader.setSource(source, debugParams: debugParams) + } + /// Sets the source of the ``DivView`` and updates the layout. /// - Parameters: /// - cardId: ID of the card to show. (The card will not be shown if it has not been previously diff --git a/client/ios/DivKit/Views/DivViewPreloader.swift b/client/ios/DivKit/Views/DivViewPreloader.swift index 597ae62fa..7b8d760f2 100644 --- a/client/ios/DivKit/Views/DivViewPreloader.swift +++ b/client/ios/DivKit/Views/DivViewPreloader.swift @@ -59,6 +59,25 @@ public final class DivViewPreloader { blockProviders[source.id.cardId] = blockProvider } + /// Sets the source for ``DivViewPreloader`` and updates the layout. + /// - Parameters: + /// - source: The source of the ``DivView``. + /// - debugParams: Optional debug configurations for the ``DivView``. + @_spi(Legacy) + public func setSource( + _ source: DivViewSource, + debugParams: DebugParams = DebugParams() + ) { + let blockProvider: DivBlockProvider = blockProvider(for: source.id.cardId) + + blockProvider.setSource( + source, + debugParams: debugParams + ) + + blockProviders[source.id.cardId] = blockProvider + } + /// Sets the sources for ``DivViewPreloader`` and updates the layout. /// - Parameters: /// - sources: The sources of the ``DivView``.