@jwplayer/jwplayer-react-native 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/CODEOWNERS +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/ISSUE_TEMPLATE/question.md +11 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/LICENSE +21 -0
- package/README.md +425 -0
- package/RNJWPlayer.podspec +44 -0
- package/android/.gradle/8.1.1/checksums/checksums.lock +0 -0
- package/android/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.1.1/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.1.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.1.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.1.1/gc.properties +0 -0
- package/android/.gradle/8.2/checksums/checksums.lock +0 -0
- package/android/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.2/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.2/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/config.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/.idea/gradle.xml +12 -0
- package/android/.idea/migrations.xml +10 -0
- package/android/.idea/misc.xml +10 -0
- package/android/.idea/vcs.xml +6 -0
- package/android/.idea/workspace.xml +54 -0
- package/android/build.gradle +110 -0
- package/android/local.properties +8 -0
- package/android/src/main/AndroidManifest.xml +25 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/ArrayUtil.java +129 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/CastOptionsProvider.java +55 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/MapUtil.java +136 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayer.java +76 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerAds.java +239 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerModule.java +526 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerPackage.java +30 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +1499 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +171 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +219 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/WidevineCallback.java +62 -0
- package/badges/license.svg +1 -0
- package/badges/version.svg +1 -0
- package/docs/legacy_readme.md +634 -0
- package/docs/props.md +43 -0
- package/docs/types.md +254 -0
- package/index.d.ts +564 -0
- package/index.js +699 -0
- package/ios/RNJWPlayer/RCTConvert+RNJWPlayer.swift +119 -0
- package/ios/RNJWPlayer/RNJWPlayer-Bridging-Header.h +5 -0
- package/ios/RNJWPlayer/RNJWPlayerAds.swift +260 -0
- package/ios/RNJWPlayer/RNJWPlayerModels.swift +149 -0
- package/ios/RNJWPlayer/RNJWPlayerView.swift +1837 -0
- package/ios/RNJWPlayer/RNJWPlayerViewController.swift +616 -0
- package/ios/RNJWPlayer/RNJWPlayerViewManager.m +132 -0
- package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +500 -0
- package/ios/RNJWPlayer.xcodeproj/project.pbxproj +323 -0
- package/package.json +45 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNJWPlayerViewController.m
|
|
3
|
+
// RNJWPlayer
|
|
4
|
+
//
|
|
5
|
+
// Created by Chaim Paneth on 3/30/22.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import React
|
|
10
|
+
import JWPlayerKit
|
|
11
|
+
|
|
12
|
+
extension RCTConvert {
|
|
13
|
+
|
|
14
|
+
static func JWAdClient(_ value: String) -> JWAdClient {
|
|
15
|
+
switch value {
|
|
16
|
+
case "vast":
|
|
17
|
+
return .JWPlayer
|
|
18
|
+
case "ima":
|
|
19
|
+
return .GoogleIMA
|
|
20
|
+
case "ima_dai":
|
|
21
|
+
return .GoogleIMADAI
|
|
22
|
+
default:
|
|
23
|
+
return .unknown
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static func JWInterfaceBehavior(_ value: String) -> JWInterfaceBehavior {
|
|
28
|
+
switch value {
|
|
29
|
+
case "normal":
|
|
30
|
+
return .normal
|
|
31
|
+
case "hidden":
|
|
32
|
+
return .hidden
|
|
33
|
+
case "onscreen":
|
|
34
|
+
return .alwaysOnScreen
|
|
35
|
+
default:
|
|
36
|
+
return .normal
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static func JWCaptionEdgeStyle(_ value: String) -> JWCaptionEdgeStyle {
|
|
41
|
+
switch value {
|
|
42
|
+
case "none":
|
|
43
|
+
return .none
|
|
44
|
+
case "dropshadow":
|
|
45
|
+
return .dropshadow
|
|
46
|
+
case "raised":
|
|
47
|
+
return .raised
|
|
48
|
+
case "depressed":
|
|
49
|
+
return .depressed
|
|
50
|
+
case "uniform":
|
|
51
|
+
return .uniform
|
|
52
|
+
default:
|
|
53
|
+
return .undefined
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static func JWPreload(_ value: String) -> JWPreload {
|
|
58
|
+
switch value {
|
|
59
|
+
case "auto":
|
|
60
|
+
return .auto
|
|
61
|
+
case "none":
|
|
62
|
+
return .none
|
|
63
|
+
default:
|
|
64
|
+
return .none
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static func JWRelatedOnClick(_ value: String) -> JWRelatedOnClick {
|
|
69
|
+
switch value {
|
|
70
|
+
case "play":
|
|
71
|
+
return .play
|
|
72
|
+
case "link":
|
|
73
|
+
return .link
|
|
74
|
+
default:
|
|
75
|
+
return .play
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static func JWRelatedOnComplete(_ value: String) -> JWRelatedOnComplete {
|
|
80
|
+
switch value {
|
|
81
|
+
case "show":
|
|
82
|
+
return .show
|
|
83
|
+
case "hide":
|
|
84
|
+
return .hide
|
|
85
|
+
case "autoplay":
|
|
86
|
+
return .autoplay
|
|
87
|
+
default:
|
|
88
|
+
return .show
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static func JWControlType(_ value: String) -> JWControlType {
|
|
93
|
+
switch value {
|
|
94
|
+
case "forward":
|
|
95
|
+
return .fastForwardButton
|
|
96
|
+
case "rewind":
|
|
97
|
+
return .rewindButton
|
|
98
|
+
case "pip":
|
|
99
|
+
return .pictureInPictureButton
|
|
100
|
+
case "airplay":
|
|
101
|
+
return .airplayButton
|
|
102
|
+
case "chromecast":
|
|
103
|
+
return .chromecastButton
|
|
104
|
+
case "next":
|
|
105
|
+
return .nextButton
|
|
106
|
+
case "previous":
|
|
107
|
+
return .previousButton
|
|
108
|
+
case "settings":
|
|
109
|
+
return .settingsButton
|
|
110
|
+
case "languages":
|
|
111
|
+
return .languagesButton
|
|
112
|
+
case "fullscreen":
|
|
113
|
+
return .fullscreenButton
|
|
114
|
+
default:
|
|
115
|
+
return .fullscreenButton
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNJWPlayerAds.swift
|
|
3
|
+
// RNJWPlayer
|
|
4
|
+
//
|
|
5
|
+
// Created by Chaim Paneth on 24/12/2023.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import JWPlayerKit
|
|
10
|
+
|
|
11
|
+
class RNJWPlayerAds {
|
|
12
|
+
|
|
13
|
+
// Convert configureVASTWithAds function
|
|
14
|
+
static func configureVAST(with ads: [String: Any]) -> JWAdvertisingConfig? {
|
|
15
|
+
let adConfigBuilder = JWAdsAdvertisingConfigBuilder()
|
|
16
|
+
|
|
17
|
+
// Configure VAST specific settings here
|
|
18
|
+
// Example: setting ad schedule, tag, etc.
|
|
19
|
+
|
|
20
|
+
if let scheduleArray = getAdSchedule(from: ads), !scheduleArray.isEmpty {
|
|
21
|
+
adConfigBuilder.schedule(scheduleArray)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if let tag = ads["tag"] as? String, let encodedString = tag.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed), let tagUrl = URL(string: encodedString) {
|
|
25
|
+
adConfigBuilder.tag(tagUrl)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if let adVmap = ads["adVmap"] as? String, let encodedString = adVmap.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed), let adVmapUrl = URL(string: encodedString) {
|
|
29
|
+
adConfigBuilder.vmapURL(adVmapUrl)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if let openBrowserOnAdClick = ads["openBrowserOnAdClick"] as? Bool {
|
|
33
|
+
adConfigBuilder.openBrowserOnAdClick(openBrowserOnAdClick)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if let adRulesDict = ads["adRules"] as? [String: Any], let adRules = getAdRules(from: adRulesDict) {
|
|
37
|
+
adConfigBuilder.adRules(adRules)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if let adSettingsDict = ads["adSettings"] as? [String: Any] {
|
|
41
|
+
if let adSettings = getAdSettings(from: adSettingsDict) {
|
|
42
|
+
adConfigBuilder.adSettings(adSettings)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return try? adConfigBuilder.build()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Convert configureIMAWithAds function
|
|
50
|
+
static func configureIMA(with ads: [String: Any]) -> JWAdvertisingConfig? {
|
|
51
|
+
// Ensure Google IMA SDK is available
|
|
52
|
+
#if !USE_GOOGLE_IMA
|
|
53
|
+
assertionFailure("Error: GoogleAds-IMA-iOS-SDK is not installed. Add $RNJWPlayerUseGoogleIMA = true; to your podfile")
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
let adConfigBuilder = JWImaAdvertisingConfigBuilder()
|
|
57
|
+
|
|
58
|
+
// Configure Google IMA specific settings here
|
|
59
|
+
// Example: setting ad schedule, tag, IMA settings, etc.
|
|
60
|
+
|
|
61
|
+
if let scheduleArray = getAdSchedule(from: ads), !scheduleArray.isEmpty {
|
|
62
|
+
adConfigBuilder.schedule(scheduleArray)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if let tag = ads["tag"] as? String, let encodedString = tag.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed), let tagUrl = URL(string: encodedString) {
|
|
66
|
+
adConfigBuilder.tag(tagUrl)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if let adVmap = ads["adVmap"] as? String, let encodedString = adVmap.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed), let adVmapUrl = URL(string: encodedString) {
|
|
70
|
+
adConfigBuilder.vmapURL(adVmapUrl)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if let adRulesDict = ads["adRules"] as? [String: Any], let adRules = getAdRules(from: adRulesDict) {
|
|
74
|
+
adConfigBuilder.adRules(adRules)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if let imaSettingsDict = ads["imaSettings"] as? [String: Any] {
|
|
78
|
+
if let imaSettings = getIMASettings(from: imaSettingsDict) {
|
|
79
|
+
adConfigBuilder.imaSettings(imaSettings)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return try? adConfigBuilder.build()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Convert configureIMADAIWithAds function
|
|
87
|
+
static func configureIMADAI(with ads: [String: Any]) -> JWAdvertisingConfig? {
|
|
88
|
+
// Ensure Google IMA SDK is available
|
|
89
|
+
#if !USE_GOOGLE_IMA
|
|
90
|
+
assertionFailure("Error: GoogleAds-IMA-iOS-SDK is not installed. Add $RNJWPlayerUseGoogleIMA = true; to your podfile")
|
|
91
|
+
#endif
|
|
92
|
+
|
|
93
|
+
let adConfigBuilder = JWImaDaiAdvertisingConfigBuilder()
|
|
94
|
+
|
|
95
|
+
// Configure Google IMA DAI specific settings here
|
|
96
|
+
// Example: setting stream configuration, friendly obstructions, etc.
|
|
97
|
+
|
|
98
|
+
if let imaSettingsDict = ads["imaSettings"] as? [String: Any] {
|
|
99
|
+
if let imaSettings = getIMASettings(from: imaSettingsDict) {
|
|
100
|
+
adConfigBuilder.imaSettings(imaSettings)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if let googleDAIStreamDict = ads["googleDAIStream"] as? [String: Any], let googleDAIStream = getGoogleDAIStream(from: googleDAIStreamDict) {
|
|
105
|
+
adConfigBuilder.googleDAIStream(googleDAIStream)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return try? adConfigBuilder.build()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Convert getAdSchedule function
|
|
112
|
+
static func getAdSchedule(from ads: [String: Any]) -> [JWAdBreak]? {
|
|
113
|
+
guard let schedule = ads["adSchedule"] as? [[String: Any]], !schedule.isEmpty else { return nil }
|
|
114
|
+
|
|
115
|
+
var scheduleArray: [JWAdBreak] = []
|
|
116
|
+
|
|
117
|
+
for item in schedule {
|
|
118
|
+
if let offsetString = item["offset"] as? String, let tag = item["tag"] as? String, let encodedString = tag.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed), let tagUrl = URL(string: encodedString) {
|
|
119
|
+
|
|
120
|
+
let adBreakBuilder = JWAdBreakBuilder()
|
|
121
|
+
if let offset = JWAdOffset.from(string: offsetString) {
|
|
122
|
+
adBreakBuilder.offset(offset)
|
|
123
|
+
adBreakBuilder.tags([tagUrl])
|
|
124
|
+
|
|
125
|
+
if let adBreak = try? adBreakBuilder.build() {
|
|
126
|
+
scheduleArray.append(adBreak)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return scheduleArray.isEmpty ? nil : scheduleArray
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Convert getAdRules function
|
|
136
|
+
static func getAdRules(from adRulesDict: [String: Any]) -> JWAdRules? {
|
|
137
|
+
let builder = JWAdRulesBuilder()
|
|
138
|
+
|
|
139
|
+
if let startOn = adRulesDict["startOn"] as? UInt, let frequency = adRulesDict["frequency"] as? UInt, let timeBetweenAds = adRulesDict["timeBetweenAds"] as? UInt {
|
|
140
|
+
let startOnSeek = mapStringToJWAdShownOnSeek(adRulesDict["startOnSeek"] as? String)
|
|
141
|
+
builder.jwRules(startOn: startOn, frequency: frequency, timeBetweenAds: timeBetweenAds, startOnSeek: startOnSeek)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return try? builder.build()
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Convert mapStringToJWAdShownOnSeek function
|
|
148
|
+
static func mapStringToJWAdShownOnSeek(_ seekString: String?) -> JWAdShownOnSeek {
|
|
149
|
+
guard let seekString = seekString else { return .none }
|
|
150
|
+
switch seekString {
|
|
151
|
+
case "pre":
|
|
152
|
+
return .pre
|
|
153
|
+
default:
|
|
154
|
+
return .none
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Convert getAdSettings function
|
|
159
|
+
static func getAdSettings(from settingsDict: [String: Any]) -> JWAdSettings? {
|
|
160
|
+
let builder = JWAdSettingsBuilder()
|
|
161
|
+
|
|
162
|
+
if let allowsBackgroundPlayback = settingsDict["allowsBackgroundPlayback"] as? Bool {
|
|
163
|
+
builder.allowsBackgroundPlayback(allowsBackgroundPlayback)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Add other settings as needed
|
|
167
|
+
|
|
168
|
+
return builder.build()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Convert getIMASettings function
|
|
172
|
+
static func getIMASettings(from imaSettingsDict: [String: Any]) -> JWImaSettings? {
|
|
173
|
+
let builder = JWImaSettingsBuilder()
|
|
174
|
+
if let locale = imaSettingsDict["locale"] as? String {
|
|
175
|
+
builder.locale(locale)
|
|
176
|
+
}
|
|
177
|
+
if let ppid = imaSettingsDict["ppid"] as? String {
|
|
178
|
+
builder.ppid(ppid)
|
|
179
|
+
}
|
|
180
|
+
if let maxRedirects = imaSettingsDict["maxRedirects"] as? UInt {
|
|
181
|
+
builder.maxRedirects(maxRedirects)
|
|
182
|
+
}
|
|
183
|
+
if let sessionID = imaSettingsDict["sessionID"] as? String {
|
|
184
|
+
builder.sessionID(sessionID)
|
|
185
|
+
}
|
|
186
|
+
if let debugMode = imaSettingsDict["debugMode"] as? Bool {
|
|
187
|
+
builder.debugMode(debugMode)
|
|
188
|
+
}
|
|
189
|
+
return builder.build()
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Convert getGoogleDAIStream function
|
|
193
|
+
static func getGoogleDAIStream(from googleDAIStreamDict: [String: Any]) -> JWGoogleDAIStream? {
|
|
194
|
+
let builder = JWGoogleDAIStreamBuilder()
|
|
195
|
+
if let videoID = googleDAIStreamDict["videoID"] as? String, let cmsID = googleDAIStreamDict["cmsID"] as? String {
|
|
196
|
+
builder.vodStreamInfo(videoID: videoID, cmsID: cmsID)
|
|
197
|
+
} else if let assetKey = googleDAIStreamDict["assetKey"] as? String {
|
|
198
|
+
builder.liveStreamInfo(assetKey: assetKey)
|
|
199
|
+
}
|
|
200
|
+
if let apiKey = googleDAIStreamDict["apiKey"] as? String {
|
|
201
|
+
builder.apiKey(apiKey)
|
|
202
|
+
}
|
|
203
|
+
if let adTagParameters = googleDAIStreamDict["adTagParameters"] as? [String: Any] {
|
|
204
|
+
let stringParams = adTagParameters.compactMapValues { $0 as? String }
|
|
205
|
+
builder.adTagParameters(stringParams)
|
|
206
|
+
}
|
|
207
|
+
return try? builder.build()
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Placeholder for findViewWithId function - Needs implementation
|
|
211
|
+
// static func findView(withId viewId: String) -> UIView? {
|
|
212
|
+
// // Implementation needed to find and return the view with the given id
|
|
213
|
+
// return nil
|
|
214
|
+
// }
|
|
215
|
+
//
|
|
216
|
+
// static func createFriendlyObstructions(fromArray obstructionsArray: [[String: Any]]) -> [JWFriendlyObstruction] {
|
|
217
|
+
// var obstructions: [JWFriendlyObstruction] = []
|
|
218
|
+
//
|
|
219
|
+
// for obstructionDict in obstructionsArray {
|
|
220
|
+
// if let viewId = obstructionDict["viewId"] as? String,
|
|
221
|
+
// let view = findView(withId: viewId),
|
|
222
|
+
// let purposeString = obstructionDict["purpose"] as? String,
|
|
223
|
+
// let reason = obstructionDict["reason"] as? String {
|
|
224
|
+
// let purpose = mapStringToJWFriendlyObstructionPurpose(purposeString)
|
|
225
|
+
// let obstruction = JWFriendlyObstruction(view: view, purpose: purpose, reason: reason)
|
|
226
|
+
// obstructions.append(obstruction)
|
|
227
|
+
// }
|
|
228
|
+
// }
|
|
229
|
+
//
|
|
230
|
+
// return obstructions
|
|
231
|
+
// }
|
|
232
|
+
//
|
|
233
|
+
// static func mapStringToJWFriendlyObstructionPurpose(_ purposeString: String) -> JWFriendlyObstructionPurpose {
|
|
234
|
+
// switch purposeString {
|
|
235
|
+
// case "mediaControls":
|
|
236
|
+
// return .mediaControls
|
|
237
|
+
// case "closeAd":
|
|
238
|
+
// return .closeAd
|
|
239
|
+
// case "notVisible":
|
|
240
|
+
// return .notVisible
|
|
241
|
+
// default:
|
|
242
|
+
// return .other
|
|
243
|
+
// }
|
|
244
|
+
// }
|
|
245
|
+
//
|
|
246
|
+
// static func createCompanionAdSlot(fromDictionary companionAdSlotDict: [String: Any]) -> JWCompanionAdSlot? {
|
|
247
|
+
// guard let viewId = companionAdSlotDict["viewId"] as? String,
|
|
248
|
+
// let view = findView(withId: viewId),
|
|
249
|
+
// let sizeDict = companionAdSlotDict["size"] as? [String: Float],
|
|
250
|
+
// let width = sizeDict["width"],
|
|
251
|
+
// let height = sizeDict["height"] else {
|
|
252
|
+
// return nil
|
|
253
|
+
// }
|
|
254
|
+
//
|
|
255
|
+
// let size = CGSize(width: CGFloat(width), height: CGFloat(height))
|
|
256
|
+
// let slot = JWCompanionAdSlot(view: view, size: size)
|
|
257
|
+
// return slot
|
|
258
|
+
// }
|
|
259
|
+
}
|
|
260
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// This file was generated from JSON Schema using quicktype, do not modify it directly.
|
|
2
|
+
// To parse the JSON, add this file to your project and do:
|
|
3
|
+
//
|
|
4
|
+
// let jWConfig = try? JSONDecoder().decode(JWConfig.self, from: jsonData)
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
|
|
8
|
+
// MARK: - JWConfig
|
|
9
|
+
struct JWConfig: Codable {
|
|
10
|
+
let config: Config
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// MARK: - Config
|
|
14
|
+
struct Config: Codable {
|
|
15
|
+
let license: String
|
|
16
|
+
let advertising: Advertising
|
|
17
|
+
let autostart, controls, configRepeat: Bool
|
|
18
|
+
let nextUpStyle: NextUpStyle
|
|
19
|
+
let styling: Styling
|
|
20
|
+
let backgroundAudioEnabled: Bool
|
|
21
|
+
let category: String
|
|
22
|
+
let categoryOptions: [String]
|
|
23
|
+
let mode: String
|
|
24
|
+
let fullScreenOnLandscape, landscapeOnFullScreen, portraitOnExitFullScreen, exitFullScreenOnPortrait: Bool
|
|
25
|
+
let playlist: [Playlist]
|
|
26
|
+
let stretching: String
|
|
27
|
+
let related: Related
|
|
28
|
+
let preload, interfaceBehavior: String
|
|
29
|
+
let interfaceFadeDelay: Int
|
|
30
|
+
let hideUIGroups: [String]
|
|
31
|
+
let processSpcURL, fairplayCERTURL, contentUUID: String
|
|
32
|
+
let viewOnly, enableLockScreenControls, pipEnabled: Bool
|
|
33
|
+
|
|
34
|
+
enum CodingKeys: String, CodingKey {
|
|
35
|
+
case license, advertising, autostart, controls
|
|
36
|
+
case configRepeat = "repeat"
|
|
37
|
+
case nextUpStyle, styling, backgroundAudioEnabled, category, categoryOptions, mode, fullScreenOnLandscape, landscapeOnFullScreen, portraitOnExitFullScreen, exitFullScreenOnPortrait, playlist, stretching, related, preload, interfaceBehavior, interfaceFadeDelay, hideUIGroups
|
|
38
|
+
case processSpcURL = "processSpcUrl"
|
|
39
|
+
case fairplayCERTURL = "fairplayCertUrl"
|
|
40
|
+
case contentUUID, viewOnly, enableLockScreenControls, pipEnabled
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// MARK: - Advertising
|
|
45
|
+
struct Advertising: Codable {
|
|
46
|
+
let adSchedule: [AdSchedule]
|
|
47
|
+
let adVmap, tag: String
|
|
48
|
+
let openBrowserOnAdClick: Bool
|
|
49
|
+
let adClient: String
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// MARK: - AdSchedule
|
|
53
|
+
struct AdSchedule: Codable {
|
|
54
|
+
let tag, offset: String
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// MARK: - NextUpStyle
|
|
58
|
+
struct NextUpStyle: Codable {
|
|
59
|
+
let offsetSeconds, offsetPercentage: Int
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// MARK: - Playlist
|
|
63
|
+
struct Playlist: Codable {
|
|
64
|
+
let file: String
|
|
65
|
+
let sources: [Source]
|
|
66
|
+
let image, title, description, mediaID: String
|
|
67
|
+
let adSchedule: [AdSchedule]
|
|
68
|
+
let adVmap: String
|
|
69
|
+
let tracks: [Source]
|
|
70
|
+
let recommendations, startTime: String
|
|
71
|
+
let autostart: Bool
|
|
72
|
+
|
|
73
|
+
enum CodingKeys: String, CodingKey {
|
|
74
|
+
case file, sources, image, title, description
|
|
75
|
+
case mediaID = "mediaId"
|
|
76
|
+
case adSchedule, adVmap, tracks, recommendations, startTime, autostart
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// MARK: - Source
|
|
81
|
+
struct Source: Codable {
|
|
82
|
+
let file, label: String
|
|
83
|
+
let sourceDefault: Bool
|
|
84
|
+
|
|
85
|
+
enum CodingKeys: String, CodingKey {
|
|
86
|
+
case file, label
|
|
87
|
+
case sourceDefault = "default"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// MARK: - Related
|
|
92
|
+
struct Related: Codable {
|
|
93
|
+
let onClick, onComplete, heading, url: String
|
|
94
|
+
let autoplayMessage: String
|
|
95
|
+
let autoplayTimer: Int
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// MARK: - Styling
|
|
99
|
+
struct Styling: Codable {
|
|
100
|
+
let colors: Colors
|
|
101
|
+
let font: Font
|
|
102
|
+
let displayTitle, displayDescription: Bool
|
|
103
|
+
let captionsStyle: CaptionsStyle
|
|
104
|
+
let menuStyle: MenuStyle
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// MARK: - CaptionsStyle
|
|
108
|
+
struct CaptionsStyle: Codable {
|
|
109
|
+
let font: Font
|
|
110
|
+
let fontColor, backgroundColor, highlightColor, edgeStyle: String
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// MARK: - Font
|
|
114
|
+
struct Font: Codable {
|
|
115
|
+
let name: String
|
|
116
|
+
let size: Int
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// MARK: - Colors
|
|
120
|
+
struct Colors: Codable {
|
|
121
|
+
let buttons, backgroundColor, fontColor: String
|
|
122
|
+
let timeslider: Timeslider
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// MARK: - Timeslider
|
|
126
|
+
struct Timeslider: Codable {
|
|
127
|
+
let progress, rail, thumb: String
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// MARK: - MenuStyle
|
|
131
|
+
struct MenuStyle: Codable {
|
|
132
|
+
let font: Font
|
|
133
|
+
let fontColor, backgroundColor: String
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// MARK: - Extensions
|
|
137
|
+
extension Decodable {
|
|
138
|
+
init<Key: Hashable, Value>(_ dict: [Key: Value]) throws where Key: Codable, Value: Codable {
|
|
139
|
+
let data = try JSONEncoder().encode(dict)
|
|
140
|
+
self = try JSONDecoder().decode(Self.self, from: data)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
extension Decodable {
|
|
145
|
+
init<Key: Hashable>(_ dict: [Key: Any]) throws {
|
|
146
|
+
let data = try JSONSerialization.data(withJSONObject: dict, options: [])
|
|
147
|
+
self = try JSONDecoder().decode(Self.self, from: data)
|
|
148
|
+
}
|
|
149
|
+
}
|