Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #409 from clappr/feature/core_layer
Browse files Browse the repository at this point in the history
Create Core layer
  • Loading branch information
VitorFerraz authored Oct 7, 2020
2 parents 0bb4321 + 824f06d commit 686b53d
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 30 deletions.
24 changes: 21 additions & 3 deletions Clappr.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@
524B66AD242A9BEF0085789D /* AccessLogEventMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD29B8423FDDF5300C82098 /* AccessLogEventMock.swift */; };
524B66AE242A9C070085789D /* PlayerItemAccessLogMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD29B8223FDDF1900C82098 /* PlayerItemAccessLogMock.swift */; };
529D2F7224880ACD006283A4 /* UICorePluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF652211D467CCA00627C48 /* UICorePluginTests.swift */; };
568445B4251D31C3006568BF /* CoreLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568445B3251D31C3006568BF /* CoreLayer.swift */; };
568445B5251D31C3006568BF /* CoreLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568445B3251D31C3006568BF /* CoreLayer.swift */; };
568445B7251D39C7006568BF /* CoreLayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568445B6251D39C7006568BF /* CoreLayerTests.swift */; };
568445B8251D39C7006568BF /* CoreLayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568445B6251D39C7006568BF /* CoreLayerTests.swift */; };
568445BA251D3B38006568BF /* UICorePluginStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568445B9251D3B38006568BF /* UICorePluginStub.swift */; };
568445BB251D3B38006568BF /* UICorePluginStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568445B9251D3B38006568BF /* UICorePluginStub.swift */; };
571B7B252174DBDD005C0942 /* AVFoundationPlayback.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D362B31D41339400CCB866 /* AVFoundationPlayback.swift */; };
571B7B262174E324005C0942 /* AVFoundationPlayback+tvOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC7785B6200523E400EC879F /* AVFoundationPlayback+tvOS.swift */; };
571B7B292175013F005C0942 /* AVFoundationPlaybackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9684B6C81D186E2D00D012C2 /* AVFoundationPlaybackTests.swift */; };
Expand Down Expand Up @@ -544,6 +550,9 @@
5217467724EAE54D00BDBC43 /* AVFoundationPlaybackSubtitleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVFoundationPlaybackSubtitleTests.swift; sourceTree = "<group>"; };
522C8996246D938B008F5856 /* AVFoundationPlaybackStopActionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVFoundationPlaybackStopActionTests.swift; sourceTree = "<group>"; };
5232A454248A73780095D174 /* UIFocusEnvironment+ExtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFocusEnvironment+ExtTests.swift"; sourceTree = "<group>"; };
568445B3251D31C3006568BF /* CoreLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreLayer.swift; sourceTree = "<group>"; };
568445B6251D39C7006568BF /* CoreLayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreLayerTests.swift; sourceTree = "<group>"; };
568445B9251D3B38006568BF /* UICorePluginStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICorePluginStub.swift; sourceTree = "<group>"; };
571B7B30217503BB005C0942 /* NowPlayingServiceStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingServiceStub.swift; sourceTree = "<group>"; };
5733D1BB21BAA3C8002107D2 /* Dictionary+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Ext.swift"; sourceTree = "<group>"; };
5733D1BD21BAA6E4002107D2 /* Dictionary+ExtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+ExtTests.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1314,6 +1323,7 @@
A32A4A2A24F544C000953E47 /* LayerTests.swift */,
A308B35C24F6E8F700C84AB8 /* PlaybackLayerTests.swift */,
A308B35F24F6FD6C00C84AB8 /* ContainerLayerTests.swift */,
568445B6251D39C7006568BF /* CoreLayerTests.swift */,
3DDDF42325221E5100AAA9CD /* MediaControlLayerTests.swift */,
);
path = Layers;
Expand All @@ -1323,10 +1333,11 @@
isa = PBXGroup;
children = (
A3C8F3EC24CF489F002CA3F5 /* BackgroundLayer.swift */,
A3C8F3EB24CF489F002CA3F5 /* LayerComposer.swift */,
A32A4A2424F53F5000953E47 /* Layer.swift */,
A32A4A2624F53FAA00953E47 /* PlaybackLayer.swift */,
A3B8019124F6A31A009FA0D4 /* ContainerLayer.swift */,
568445B3251D31C3006568BF /* CoreLayer.swift */,
A32A4A2624F53FAA00953E47 /* PlaybackLayer.swift */,
A32A4A2424F53F5000953E47 /* Layer.swift */,
A3C8F3EB24CF489F002CA3F5 /* LayerComposer.swift */,
90988E2E25192EA4008CC9E9 /* MediaControlLayer.swift */,
);
path = Layers;
Expand Down Expand Up @@ -1551,6 +1562,7 @@
48A29C0D221DF3950004AD3B /* CorePluginStub.swift */,
C9EDF8512162D07D00789E2F /* CoreStub.swift */,
48A995172220842000042C0E /* UIPluginStub.swift */,
568445B9251D3B38006568BF /* UICorePluginStub.swift */,
);
path = Stubs;
sourceTree = "<group>";
Expand Down Expand Up @@ -2165,6 +2177,7 @@
CD57FCF322949BBB00AB24CF /* SimpleCorePlugin.swift in Sources */,
48A29C01221D82700004AD3B /* UIObject.swift in Sources */,
48EC492122A1908300DC7A2D /* AVPlayerItem+Ext.swift in Sources */,
568445B5251D31C3006568BF /* CoreLayer.swift in Sources */,
C9EDF8592163A9A900789E2F /* UIColor+ClapprAdditions.swift in Sources */,
48A29C00221D81B90004AD3B /* EventProtocol.swift in Sources */,
EFFC35CC24858D9E00A18E90 /* UIFocusEnvironment+Ext.swift in Sources */,
Expand Down Expand Up @@ -2225,6 +2238,7 @@
571B7B2B2175015F005C0942 /* AVURLAssetStub.swift in Sources */,
C934669B2305C13F0062E8DE /* String+Ext.swift in Sources */,
571B7B292175013F005C0942 /* AVFoundationPlaybackTests.swift in Sources */,
568445BB251D3B38006568BF /* UICorePluginStub.swift in Sources */,
5217467924EAE54D00BDBC43 /* AVFoundationPlaybackSubtitleTests.swift in Sources */,
C9096F1F24086B05001BB2A4 /* OHTTPStubsHelper.swift in Sources */,
C9C8BFAF2305C9B800A8FA55 /* SimpleCorePluginTests.swift in Sources */,
Expand Down Expand Up @@ -2269,6 +2283,7 @@
C93466952305BC440062E8DE /* EventHandlerTests.swift in Sources */,
C94D8CEE221B1E5400C7855D /* ContainerPluginTests.swift in Sources */,
FB0A223C2175492E00D2180F /* Loader+Plugins.swift in Sources */,
568445B8251D39C7006568BF /* CoreLayerTests.swift in Sources */,
EFEC758423C52D4500FA6A52 /* PlaybackRendererTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -2296,6 +2311,7 @@
7BCD8EE023073A8900FBE5A2 /* SimpleContainerPluginTests.swift in Sources */,
A32A4A2D24F546E800953E47 /* LayerTests.swift in Sources */,
96A9CE391C973A0600C21E80 /* LoaderTests.swift in Sources */,
568445B7251D39C7006568BF /* CoreLayerTests.swift in Sources */,
FC6418E12007DC2F00E81B7C /* ClapprDateFormatterTests.swift in Sources */,
FB3A8F1A209F8D7000CEFC3D /* FullscreenTests.swift in Sources */,
48A29C08221DEF690004AD3B /* CorePluginTests.swift in Sources */,
Expand Down Expand Up @@ -2352,6 +2368,7 @@
9EED97082088E5B800D1C84A /* AVPlayerItemStub.swift in Sources */,
7BD29B8123FDDEDC00C82098 /* PlayerItemMock.swift in Sources */,
C9C8BFAE2305C9B800A8FA55 /* SimpleCorePluginTests.swift in Sources */,
568445BA251D3B38006568BF /* UICorePluginStub.swift in Sources */,
32D18C8E20484CA10097653C /* SpinnerPluginTests.swift in Sources */,
9EED97042088E32800D1C84A /* AVFoundationPlaybackViewPortTests.swift in Sources */,
48A29C10221DF3BF0004AD3B /* CorePluginStub.swift in Sources */,
Expand Down Expand Up @@ -2456,6 +2473,7 @@
262B490D24D8898F0049DAF7 /* UIColor+ARGB.swift in Sources */,
4856322E220B54B90096CDAE /* QuickSeekPlugin.swift in Sources */,
CD10D93D22C28D4C0096B035 /* Environment.swift in Sources */,
568445B4251D31C3006568BF /* CoreLayer.swift in Sources */,
96D362C51D41339400CCB866 /* Container.swift in Sources */,
963B19981E4B827700A0A6BA /* Event.swift in Sources */,
48F1E97423229FDC00EAD6A1 /* DrawerPlugin.swift in Sources */,
Expand Down
14 changes: 9 additions & 5 deletions Sources/Clappr/Classes/Base/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,11 @@ open class Core: UIObject, UIGestureRecognizerDelegate {
.filter { $0.isNotMediaControlElement }
.filter { $0.isNotOverlayPlugin }
.filter { $0.isNotMediaControl }
.forEach(render)
.compactMap { $0 as? UICorePlugin }
.forEach { plugin in
layerComposer.attachUICorePlugin(plugin)
plugin.safeRender()
}
}

private func attachMediaControlLayer() {
Expand Down Expand Up @@ -296,17 +300,17 @@ fileprivate extension Plugin {
}

#if os(iOS)
var isNotMediaControl: Bool {
return !(self is MediaControl)
}

var isNotMediaControlElement: Bool {
return !(self is MediaControl.Element)
}

var isNotOverlayPlugin: Bool {
return !(self is OverlayPlugin)
}

var isNotMediaControl: Bool {
return !(self is MediaControl)
}
#endif

func safeDestroy() {
Expand Down
13 changes: 13 additions & 0 deletions Sources/Clappr/Classes/Base/Layers/CoreLayer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import UIKit

final class CoreLayer: Layer {
func attachPlugin(_ plugin: UICorePlugin) {
addSubview(plugin.view)
}

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = super.hitTest(point, with: event)
if result == self { return nil }
return result
}
}
6 changes: 6 additions & 0 deletions Sources/Clappr/Classes/Base/Layers/LayerComposer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class LayerComposer {
private weak var rootView: UIView?
private let backgroundLayer = BackgroundLayer()
private let playbackLayer = PlaybackLayer()
private let coreLayer = CoreLayer()
private let containerLayer = ContainerLayer()
private let mediaControlLayer = MediaControlLayer()

Expand All @@ -16,6 +17,7 @@ public class LayerComposer {
playbackLayer.attach(to: rootView, at: 1)
containerLayer.attach(to: rootView, at: 2)
mediaControlLayer.attach(to: rootView, at: 3)
coreLayer.attach(to: rootView, at: 4)
}

func attachContainer(_ view: UIView) {
Expand All @@ -25,6 +27,10 @@ public class LayerComposer {
func attachPlayback(_ view: UIView) {
playbackLayer.attachPlayback(view)
}

func attachUICorePlugin(_ plugin: UICorePlugin) {
coreLayer.attachPlugin(plugin)
}

func attachMediaControl(_ view: UIView) {
mediaControlLayer.attachMediaControl(view)
Expand Down
20 changes: 20 additions & 0 deletions Tests/Clappr_Tests/Classes/Base/Layers/CoreLayerTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Quick
import Nimble
@testable import Clappr

class CoreLayerTests: QuickSpec {
override func spec() {
describe(".CoreLayer") {
context("When a UICorePlugin is attached") {
it("is added as a CoreLayer subview") {
let uiCorePlugin = UICorePluginStub(context: CoreStub())
let coreLayer = CoreLayer()

coreLayer.attachPlugin(uiCorePlugin)

expect(uiCorePlugin.view.superview).to(equal(coreLayer))
}
}
}
}
}
14 changes: 14 additions & 0 deletions Tests/Clappr_Tests/Classes/Base/Layers/LayerComposerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ class LayerComposerTests: QuickSpec {
description: "MediaControlLayer should be the fourth subview of rootView, got \(String(describing: type(of: layer)))"
)
}
it("adds CoreLayer as the fifth layer"){
let index = 4
let rootView = UIView()
let layerComposer = LayerComposer()

layerComposer.compose(inside: rootView)

let layer = getLayer(from: rootView, at: index)
expect(layer).to(
beAKindOf(CoreLayer.self),
description: "CoreLayer should be the fifth subview of rootView, got \(String(describing: type(of: layer)))"
)
}

}
}

Expand Down
67 changes: 45 additions & 22 deletions Tests/Clappr_Tests/Classes/Plugin/Core/CoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@ class CoreTests: QuickSpec {

class LayerComposerSpy: LayerComposer {
var didCallCompose = false
var didCallAttachUICorePlugin = false
var didCallAttachMediaControl = false

override func compose(inside rootView: UIView) {
didCallCompose = true
}

override func attachUICorePlugin(_ plugin: UICorePlugin) {
didCallAttachUICorePlugin = true
}

override func attachMediaControl(_ view: UIView) {
didCallAttachMediaControl = true
}
Expand Down Expand Up @@ -807,15 +812,20 @@ class CoreTests: QuickSpec {
}

describe("#render") {
it("add plugin as subview after rendered") {
let core = Core()
let plugin = FakeCorePlugin(context: core)

core.addPlugin(plugin)
core.render()
#if os(tvOS)
context("core position") {
it("is positioned in front of Container view") {
Loader.shared.register(plugins: [FakeCorePlugin.self])
let core = CoreFactory.create(with: options, layerComposer: layerComposer)

core.render()

expect(plugin.view.superview).to(equal(core.view))
expect(core.view.subviews.count).to(equal(3))
expect(core.view.subviews.first?.accessibilityIdentifier).to(equal("Container"))
expect(core.view.subviews[1].accessibilityIdentifier).to(beNil())
}
}
#endif

#if os(iOS)
it("doesnt add plugin as subview if it is a MediaControlElement") {
Expand Down Expand Up @@ -863,6 +873,34 @@ class CoreTests: QuickSpec {

expect(mediaControlMock.didCallRenderElements).to(beTrue())
}

describe("#UICorePlugins") {
context("when rendering UICorePlugins") {
it("uses LayerComposer") {
Loader.shared.resetPlugins()
Loader.shared.register(plugins: [UICorePluginStub.self])
let layerComposer = LayerComposerSpy()
let core = CoreFactory.create(with: options, layerComposer: layerComposer)

core.render()

expect(layerComposer.didCallAttachUICorePlugin).to(beTrue())
}

it("calls render on Plugin") {
Loader.shared.resetPlugins()
Loader.shared.register(plugins: [UICorePluginStub.self])
let layerComposer = LayerComposer()
let core = CoreFactory.create(with: options, layerComposer: layerComposer)
let uiCorePlugin = core.plugins.first { $0.pluginName == "UICorePluginStub"} as? UICorePluginStub

core.render()

expect(uiCorePlugin?.didCallRender).to(beTrue())
}
}
}

#endif

it("protect the main thread when plugin crashes in render") {
Expand All @@ -879,21 +917,6 @@ class CoreTests: QuickSpec {
}
}

#if os(tvOS)
context("core position") {
it("is positioned in front of Container view") {
Loader.shared.register(plugins: [FakeCorePlugin.self])
let core = CoreFactory.create(with: options, layerComposer: layerComposer)

core.render()

expect(core.view.subviews.count).to(equal(3))
expect(core.view.subviews.first?.accessibilityIdentifier).to(equal("Container"))
expect(core.view.subviews[1].accessibilityIdentifier).to(beNil())
}
}
#endif

describe("rendering") {
context("when plugin is overlay") {
it("renders on the overlay view") {
Expand Down
12 changes: 12 additions & 0 deletions Tests/Clappr_Tests/Classes/Stubs/UICorePluginStub.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@testable import Clappr

class UICorePluginStub: UICorePlugin {
var didCallRender = false

override class var name: String { "UICorePluginStub" }
override func bindEvents() { }

override func render() {
didCallRender = true
}
}

0 comments on commit 686b53d

Please sign in to comment.