Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Mindbox.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,8 @@
471D4C3B2FEED16200856EA5 /* TestPlans */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = TestPlans; sourceTree = "<group>"; };
57A1B3230000000000000203 /* EmbeddedBlocks */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = EmbeddedBlocks; sourceTree = "<group>"; };
57A1B3230000000000000300 /* EmbeddedBlocks */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = EmbeddedBlocks; sourceTree = "<group>"; };
57A1B3230000000000000400 /* Handlers */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Handlers; sourceTree = "<group>"; };
57A1B3230000000000000401 /* BridgeHandlers */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = BridgeHandlers; sourceTree = "<group>"; };
A8C878878353491FA01AC096 /* WebViewPrewarmTests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = WebViewPrewarmTests; sourceTree = "<group>"; };
F385631E2DB6729000D91208 /* InappConfigurationDataFacade */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = InappConfigurationDataFacade; sourceTree = "<group>"; };
F397DE1C2CFF568800B72DA9 /* JSONs */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = JSONs; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1600,6 +1602,7 @@
7C8192B8B7043EF74D05B36B /* MotionServiceResolvePositionTests.swift */,
7C8192B8B7043EF74D05B36C /* MotionServiceShakeToEditTests.swift */,
F0DB93A7997961CA7C2BE917 /* MotionServiceBehaviorTests.swift */,
57A1B3230000000000000401 /* BridgeHandlers */,
);
path = WebView;
sourceTree = "<group>";
Expand Down Expand Up @@ -3839,6 +3842,7 @@
F3BD9F812F273BCD00647BAF /* BridgeMessage.swift */,
F3BDA0372F27444500647BAF /* MindboxWebBridge.swift */,
F338028F2F29F3AF00F83D2F /* BridgeMessageDispatcher.swift */,
57A1B3230000000000000400 /* Handlers */,
);
path = Bridge;
sourceTree = "<group>";
Expand Down Expand Up @@ -3965,6 +3969,7 @@
);
fileSystemSynchronizedGroups = (
57A1B3230000000000000300 /* EmbeddedBlocks */,
57A1B3230000000000000400 /* Handlers */,
);
name = Mindbox;
productName = MindBox;
Expand All @@ -3986,6 +3991,7 @@
);
fileSystemSynchronizedGroups = (
57A1B3230000000000000203 /* EmbeddedBlocks */,
57A1B3230000000000000401 /* BridgeHandlers */,
A8C878878353491FA01AC096 /* WebViewPrewarmTests */,
F385631E2DB6729000D91208 /* InappConfigurationDataFacade */,
F397DE1C2CFF568800B72DA9 /* JSONs */,
Expand Down
13 changes: 4 additions & 9 deletions Mindbox/DI/Injections/InjectEmbeddedBlocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,15 @@ import Foundation
extension MBContainer {
func registerEmbeddedBlocks() -> Self {
// The resolver is shared: its per-id cache and its queue of waiting blocks are what make
// several blocks with the same id resolve through a single load of the data. The action
// router is shared because it is stateless. Providers, in contrast, are made per block by
// the factory, so blocks stay independent of each other.
// several blocks with the same id resolve through a single load of the data. Providers,
// in contrast, are made per block by the factory, so blocks stay independent of each
// other — and so does the bridge session each of their pages runs.
register(EmbeddedBlockResolving.self) {
EmbeddedBlockResolver()
}

register(EmbeddedBlockActionHandling.self) {
EmbeddedBlockActionRouter()
}

register(EmbeddedBlockContentProviderMaking.self) {
EmbeddedBlockContentProviderFactory(resolver: DI.injectOrFail(EmbeddedBlockResolving.self),
actionHandler: DI.injectOrFail(EmbeddedBlockActionHandling.self))
EmbeddedBlockContentProviderFactory(resolver: DI.injectOrFail(EmbeddedBlockResolving.self))
}

return self
Expand Down
35 changes: 0 additions & 35 deletions Mindbox/EmbeddedBlocks/Actions/EmbeddedBlockActionRouter.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@ protocol EmbeddedBlockContentProviderMaking {
final class EmbeddedBlockContentProviderFactory: EmbeddedBlockContentProviderMaking {

private let resolver: EmbeddedBlockResolving
private let actionHandler: EmbeddedBlockActionHandling

init(resolver: EmbeddedBlockResolving,
actionHandler: EmbeddedBlockActionHandling) {
init(resolver: EmbeddedBlockResolving) {
self.resolver = resolver
self.actionHandler = actionHandler
}

func makeProvider(id: String) -> EmbeddedBlockWebViewProvider {
EmbeddedBlockWebViewProvider(id: id,
resolver: resolver,
actionHandler: actionHandler,
makePage: { EmbeddedBlockWebViewPage(content: $0) })
makePage: { EmbeddedBlockWebViewPage(id: $0, content: $1) })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ final class EmbeddedBlockResolver: EmbeddedBlockResolving {

/// The stories feed page on static hosting. Hardcoded for now: once the admin panel config
/// arrives, the address will come from there together with the id → content mapping.
private static let storiesPageURL = "https://mobile-static.mindbox.ru/beta/inapps/webview/content/stories.html"
private static let storiesPageURL = "https://mobile-static-staging.mindbox.ru/inapps/webview/content/stories.html"

private let load: EmbeddedBlockContentLoading
private let overrides: EmbeddedBlockContentOverriding
Expand Down
28 changes: 18 additions & 10 deletions Mindbox/EmbeddedBlocks/WebView/EmbeddedBlockPageHosting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,37 @@ import UIKit

/// The embedded block page — everything the provider needs from the web view.
///
/// The single seam inside the block and the single place where WebKit lives: this is what lets the
/// translation of page messages into block states be tested without a real web view and without
/// the network.
/// The single seam inside the block and the single place where WebKit lives: this is what lets
/// the translation of page reports into block states be tested without a real web view and
/// without the network.
protocol EmbeddedBlockPageHosting: AnyObject {

/// The page view. The provider hands it to the container as the block content.
var view: UIView { get }

/// Messages from the page. Delivered on the main thread.
var onMessage: ((EmbeddedBlockPageMessage) -> Void)? { get set }
/// The page rendered `count` pieces of content. Fires once per load. A count of `0` means
/// the page is alive and correct and has nothing to show. Delivered on the main thread.
var onContentRendered: ((Int) -> Void)? { get set }

/// The page failed to load — connection, domain, a cancelled navigation. That is all navigation
/// reports: whether the page is ready is decided by the page itself with its `ready`.
/// The page failed to load — connection, domain, a bad address. That is all navigation
/// reports: whether there is anything to show is decided by the page itself.
/// Delivered on the main thread.
var onLoadFailure: (() -> Void)? { get set }

/// The document has loaded. That does not mean the block is ready — the page may be empty or
/// broken — so the regular path ignores this signal: the only listener is the debug readiness
/// override for pages without the web contract. Delivered on the main thread.
/// The document has loaded. That does not mean the block has content — the page may be empty
/// or broken — so the regular path ignores this signal: the only listener is the debug
/// readiness override for pages without the web contract. Delivered on the main thread.
var onLoadFinish: (() -> Void)? { get set }

/// Whether the block is on screen for the user. The provider keeps it current; the page's
/// bridge reads it before doing anything on the user's behalf, such as opening a link.
var isUserPresent: Bool { get set }

func load()

/// Starts the page over. Used when a block that already resolved is asked to load again.
func reload()

/// Stops the loading. The page and its bridge stay in place: the block may come back into the
/// window, and then the already rendered page is shown again without a reload.
func cancel()
Expand Down
94 changes: 0 additions & 94 deletions Mindbox/EmbeddedBlocks/WebView/EmbeddedBlockPageMessage.swift

This file was deleted.

Loading